Using Linq Except for Two Int Array Lists

Is it possible to use int except two lists of int arrays, for example:

List<int[]> a = new List<int[]>(){ new int[]{3,4,5}, new int[]{7,8,9}, new int[]{10,11,12} }; List<int[]> b = new List<int[]>(){ new int[]{6,7,9}, new int[]{3,4,5}, new int[]{10,41,12} }; var c = a.Except(b); 

and exepecting {3,4,5} to be absent enumerated c? Of course I tried, and this one does not work. Is the solution as effective as Except? Or better yet, faster?

+5
source share
2 answers

In .NET, arrays are only equal to another if they are the same array object. Thus, two different arrays that have the same contents are not considered equal:

 int[] x = new int[] { 1, 2 }; int[] y = new int[] { 1, 2 }; Console.WriteLine(x == y); // false 

To check equality based on content, you can use Enumerable.SequenceEqual :

 Console.WriteLine(x.SequenceEqual(y)); // true 

Of course, this will not help you when trying to use Enumerable.Except , since the default equality Enumerable.Except will be used, which checks only for equality (and since each array is uneven for any other array except itself ...).

Thus, the solution will use a different overload and provide a custom IEqualityComparer that compares arrays based on their contents.

 public class IntArrayEqualityComparer : IEqualityComparer<int[]> { public bool Equals(int[] a, int[] b) { return a.SequenceEqual(b); } public int GetHashCode(int[] a) { return a.Sum(); } } 

Unfortunately, simply delegating SequenceEqual not enough. We also need to provide an implementation of GetHashCode for this. As a simple solution, we can use the sum of the numbers in the array here. Usually we would like to provide a strong hash function that talks a lot about the content, but since we use this hash function to call Except , we can use something simple here. (In general, we would also like to avoid creating a hash value from a mutable object)

And when using this equality comparator, we correctly filter duplicate arrays:

 var c = a.Except(b, new IntArrayEqualityComparer()); 
+6
source

This is because, by default, EqualityComparer for an int array returns false for arrays with the same values:

 int[] a1 = { 1, 2, 3 }; int[] a2 = { 1, 2, 3 }; var ec = EqualityComparer<int[]>.Default; Console.WriteLine(ec.Equals(a1, a2));//result is false 

You can fix this by running your own EqualityComparer and passing your instance to the Except method ( see the documentation ).

You can also read about comparing arrays in C # here .

+5
source

Source: https://habr.com/ru/post/1245864/


All Articles