2

In my C# program, I have an int array containing a set of integers and occasionally duplicates of those integers. I want to create an array that only contains the numbers that exist as duplicates in the initial array, but in itself contains no duplicates. Based on my newbie understanding of C# I thought that the following code would do the trick:

int a = 9;
int b = 6;
int c = 3;
int index = 0;

int[] mltpls = new int[a + b + c];

while (a > 0)
{
    mltpls[index] = 2 * a;
    a -= 1;
    index += 1;
}

while(b > 0)
{
    mltpls[index] = 3 * b;
    b -= 1;
    index += 1;
}

while(c > 0)
{
    mltpls[index] = 5 * c;
    c -= 1;
    index += 1;
}

int[] mltpls_unique = mltpls.Distinct().ToArray();
int[] mltpls_dplcts = mltpls.Except(mltpls_unique).ToArray();

Console.WriteLine(mltpls_dplcts);

//EDIT

//By running the following code I can write out all numbers in "mltpls"
for (int i = 0; i < mltpls.Length; i++)
{
 Console.Write(mltpls[i] + ", ");
}

/*If I try to run equivalent code for the "mltpls_dplcts" array nothing
only a blank line is displayed.*/

When I run this goal my the final result of my console application is a blank row. My interpretation of this is that the array mltpls_dplcts is empty or that I'm incorrectly going about printing the array.

How do get only the duplicate values from an array?

5
  • 2
    Can you add the input array contents? It's rather difficult from the code to estimate what really is in that array. Commented Dec 13, 2017 at 7:34
  • 2
    This is better done use a List<int> than an array. Commented Dec 13, 2017 at 7:38
  • Possible duplicate of Remove items from list that intersect on property using Linq Commented Dec 13, 2017 at 7:44
  • @PMF The array input of the array called "mltpls" is: 18, 16, 14, 12, 10, 8, 6, 4, 2, 18, 15, 12, 9, 6, 3, 15, 10, 5 Commented Dec 13, 2017 at 7:46
  • "How do I delete all elements in an int array that exist in another int array in C#?" this question is misleading. If you remove all elements in mltpls that exist in mltpls_unique you remove them ALL! this is actually what you have done. But it seems that you want the duplicates singled out into a new array Commented Dec 13, 2017 at 8:05

5 Answers 5

3

My interpretation of this is that the array mltpls_dplcts is empty or that I'm incorrectly going about printing the array.

Both interpretations are correct

Distinct will return every item that is at least once present in mltps. If you now apply Except you get nothing because all items that are in mltpls_unique are also present in mltps. The items in the array are compared by value, so for Except it does not matter whether a number occurs multiple times in the other array. If it is there once it will not return the number. So you get an empty array.

Furthermore you cannot simply shove an entire array into Console.WriteLine. Either use a loop or String.Join to print the content:

Console.WriteLine(String.Join(" ",mltpls_dplcts));

Solution: You can solve it using a good old loop approach ;)

int[] mltpls_unique = mltpls.Distinct().ToArray();
// The amount of duplicates is the difference between the original and the unique array
int[] mltpls_dplcts = new int[mltpls.Length-mltpls_unique.Length];


int dupCount = 0;
for (int i = 0; i < mltpls.Length; i++)
{
    for (int j = i+1; j < mltpls.Length; j++)
    {
        if (mltpls[i] == mltpls[j])
        {
            mltpls_dplcts[dupCount] = mltpls[i];
            dupCount++;
        }
    }
}

Output: 18 12 10 6 15

Sign up to request clarification or add additional context in comments.

5 Comments

@Mong_Zhu I understand that the above code solves the problem in question. However, I don't fully understand how it functions or what thoughts would need to go through my mind to come up with it. Specifically, I don't understand how the use of a for loop within a for loop helps us generate the sought after equality.
@K.Claesson Think about how you would identify duplicates if they were written down on a piece of paper. You would remember the first number and scan the list to find it again. You would start to look at the position right to the remembered item (since you don't want to compare the item with itself) IF you find the number you write it down on a separate sheet of paper, otherwise you know that it is unique. Now you take the second element in the list, remember it and start again scanning. You problem is examplary for the use of loops. If you have more question don't hesitate to ask :)
@K.Claesson Imagine you put the left index finger on the first number that you try to remember and you use your right index finger to look for the duplicate. Now you fingers work as pointers or indexers which is basically also the use of the index variables (they are even called this way) in the 2 loops i and j. Each time you move the right finger you look back at the position where you left finger points to and compare the numbers, then you shift the right finger one position forward :) Is this somehow understandable?
@Mong_Zhu Yes, your analogy was superb for helping me interpret the code and understand the thought process behind it. Two questions: i) Is the reason we can say that the first, and equivalently second, for loop should execute while i < mltpls.Length because mltpls.Length = x whereas the last index mltpls is x - 1 due to indexes starting at 0? ii) Based on my interpretation of the code, if one number occurred n times in mltpls, mltpls_dplcts would include that numner n - 1 times. Is this correct?
@K.Claesson i) " whereas the last index mltpls is x - 1 due to indexes starting at 0?" Yes. you could also run the first loop only until mltpls.Length-1 because there is no need to compare the last element, since no other follow it. ii) that is correct since it counts only the positive comparisons. This is why the unique elements are not present and their count is 0
1

You cannot print the array directly. You need to loop and print one by one:

foreach (var element in mltpls_dplcts)
{
    Console.WriteLine(element);
}

Comments

1

You can get array of distinct duplicates like this:

var duplicates = mltpls.GroupBy(o => o)
    .Where(g => g.Count() > 1)
    .Select(g => g.First()).ToArray();

To get new array that contains only the elements from the original one that are not in the second array you can use:

var newArr = mltpls.Except(duplicates).ToArray();

Comments

0

It is not proper way to find duplicates. You can determine the duplicates by using GroupBy and print them to console like this;

        var mltpls_dplcts = mltpls.GroupBy(x => x).Where(x => x.Count() > 1).Select(x => x.Key).ToArray();
        foreach (var duplicate in mltpls_dplcts)
        {
            Console.WriteLine(duplicate);
        }

Also, If it isn't must to use Array for you, I suggest you to use List<int>.

Comments

0

Updated question from OP:

How do get only the duplicate values from an array?

var arr1 = new[] {1, 2, 4, 4, 5, 5, 5, 5, 6, 7, 1};
var duplicates = arr1.ToLookup(_ => _, _ => _).Where(_ => _.Count()>1).Select(_ => _.Key).ToArray();
// duplicates is now { 1, 4, 5 }

Original question from OP:

How do I delete all elements in an int array that exist in another int array in C#?

var arr1 = new[] {1, 2, 4, 5, 6, 7};
var arr2 = new[] {4, 5};

var hash = new HashSet<int>(arr1);
hash.ExceptWith(arr2);
var filteredArray = hash.ToArray();

// filteredArray is now { 1, 2, 6, 7 }

3 Comments

unfortunately your examplke does not match that from the post. Your input need to look like this: var arr1 = new[] { 1, 2, 4, 2, 5, 1, 4 }; and var arr2 = new[] { 1, 2, 4, 5 }; with your approach you will get the same result as OP.
I see that OP has edited the question. :-( I answered "How do I delete all elements in an int array that exist in another int array in C#?", but now that question has been rephrased.
I guess the question was misleading, since he described a different case than the question let assume. I edited and rephrased the question. He describes aim in his post as " I want to create an array that only contains the numbers that exist as duplicates in the initial array"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.