Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a built-in method to compare collections?

I would like to compare the contents of a couple of collections in my Equals method. I have a Dictionary and an IList. Is there a built-in method to do this?

Edited: I want to compare two Dictionaries and two ILists, so I think what equality means is clear - if the two dictionaries contain the same keys mapped to the same values, then they're equal.

like image 589
TimK Avatar asked Oct 05 '22 18:10

TimK


4 Answers

Enumerable.SequenceEqual

Determines whether two sequences are equal by comparing their elements by using a specified IEqualityComparer(T).

You can't directly compare the list & the dictionary, but you could compare the list of values from the Dictionary with the list

like image 203
Glenn Slaven Avatar answered Oct 20 '22 10:10

Glenn Slaven


As others have suggested and have noted, SequenceEqual is order-sensitive. To solve that, you can sort the dictionary by key (which is unique, and thus the sort is always stable) and then use SequenceEqual. The following expression checks if two dictionaries are equal regardless of their internal order:

dictionary1.OrderBy(kvp => kvp.Key).SequenceEqual(dictionary2.OrderBy(kvp => kvp.Key))

EDIT: As pointed out by Jeppe Stig Nielsen, some object have an IComparer<T> that is incompatible with their IEqualityComparer<T>, yielding incorrect results. When using keys with such an object, you must specify a correct IComparer<T> for those keys. For example, with string keys (which exhibit this issue), you must do the following in order to get correct results:

dictionary1.OrderBy(kvp => kvp.Key, StringComparer.Ordinal).SequenceEqual(dictionary2.OrderBy(kvp => kvp.Key, StringComparer.Ordinal))
like image 48
Allon Guralnek Avatar answered Oct 20 '22 09:10

Allon Guralnek


In addition to the mentioned SequenceEqual, which

is true if two lists are of equal length and their corresponding elements compare equal according to a comparer

(which may be the default comparer, i.e. an overriden Equals())

it is worth mentioning that in .Net4 there is SetEquals on ISet objects, which

ignores the order of elements and any duplicate elements.

So if you want to have a list of objects, but they don't need to be in a specific order, consider that an ISet (like a HashSet) may be the right choice.

like image 17
Desty Avatar answered Oct 20 '22 09:10

Desty


Take a look at the Enumerable.SequenceEqual method

var dictionary = new Dictionary<int, string>() {{1, "a"}, {2, "b"}};
var intList = new List<int> {1, 2};
var stringList = new List<string> {"a", "b"};
var test1 = dictionary.Keys.SequenceEqual(intList);
var test2 = dictionary.Values.SequenceEqual(stringList);
like image 6
aku Avatar answered Oct 20 '22 09:10

aku