Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete duplicates in a List of int arrays

Tags:

having a List of int arrays like:

List<int[]> intArrList = new List<int[]>(); intArrList.Add(new int[3] { 0, 0, 0 }); intArrList.Add(new int[5] { 20, 30, 10, 4, 6 });  //this intArrList.Add(new int[3] { 1, 2, 5 }); intArrList.Add(new int[5] { 20, 30, 10, 4, 6 });  //this intArrList.Add(new int[3] { 12, 22, 54 }); intArrList.Add(new int[5] { 1, 2, 6, 7, 8 }); intArrList.Add(new int[4] { 0, 0, 0, 0 }); 

How would you remove duplicates (by duplicate I mean element of list has same length and same numbers).

On the example I would remove element { 20, 30, 10, 4, 6 } because it is found twice

I was thinking on sorting the list by element size, then loop each element against rest but I am not sure how to do that.

Other question would be, if using other structure like a Hash would be better... If so how to use it?

like image 328
edgarmtze Avatar asked Jun 16 '16 04:06

edgarmtze


People also ask

How do you remove duplicates from an array in place C#?

In C#, we cannot remove values in the array. Instead, we will have to create a new array with the values we want. So, we have to get the distinct values from the specified array and create a new array of distinct values instead of removing duplicate values.


2 Answers

Use GroupBy:

var result = intArrList.GroupBy(c => String.Join(",", c))                        .Select(c => c.First().ToList()).ToList(); 

The result:

{0, 0, 0}

{20, 30, 10, 4, 6}

{1, 2, 5}

{12, 22, 54}

{1, 2, 6, 7, 8}

{0, 0, 0, 0}

EDIT: If you want to consider {1,2,3,4} be equal to {2,3,4,1} you need to use OrderBy like this:

var result = intArrList.GroupBy(p => string.Join(", ", p.OrderBy(c => c)))                        .Select(c => c.First().ToList()).ToList();  

EDIT2: To help understanding how the LINQ GroupBy solution works consider the following method:

public List<int[]> FindDistinctWithoutLinq(List<int[]> lst) {     var dic = new Dictionary<string, int[]>();     foreach (var item in lst)     {         string key = string.Join(",", item.OrderBy(c=>c));          if (!dic.ContainsKey(key))         {             dic.Add(key, item);         }     }      return dic.Values.ToList(); } 
like image 181
Salah Akbari Avatar answered Oct 12 '22 20:10

Salah Akbari


You can define your own implementation of IEqualityComparer and use it together with IEnumerable.Distinct:

class MyComparer : IEqualityComparer<int[]>  {     public int GetHashCode(int[] instance) { return 0; } // TODO: better HashCode for arrays     public bool Equals(int[] instance, int[] other)     {         if (other == null || instance == null || instance.Length != other.Length) return false;          return instance.SequenceEqual(other);     } } 

Now write this to get only distinct values for your list:

var result = intArrList.Distinct(new MyComparer()); 

However if you want different permutations also you should implement your comparer this way:

public bool Equals(int[] instance, int[] other) {     if (ReferenceEquals(instance, other)) return true; // this will return true when both arrays are NULL     if (other == null || instance == null) return false;     return instance.All(x => other.Contains(x)) && other.All(x => instance.Contains(x)); } 

EDIT: For a better GetashCode-implementation you may have a look at this post as also suggested in @Mick´s answer.

like image 31
MakePeaceGreatAgain Avatar answered Oct 12 '22 20:10

MakePeaceGreatAgain