Coder Perfect

Is there a built-in comparison technique for collections?

Problem

In my Equals technique, I’d like to compare the contents of a couple of collections. I have an IList and a Dictionary. Is there a built-in way to accomplish this?

Edited: Since I’m comparing two Dictionaries and two ILists, I believe the definition of equality is self-evident: if the two dictionaries have the same keys mapped to the same values, they’re equal.

Asked by TimK

Solution #1

Enumerable.SequenceEqual

You can’t compare the list and the dictionary directly, but you can compare the Dictionary’s list of values with the list.

Answered by Glenn Slaven

Solution #2

SequenceEqual is order-sensitive, as others have hypothesized and reported. To address this, sort the dictionary by key (which is always stable because it is unique) and then use SequenceEqual. The following expression compares two dictionaries regardless of their internal order to see if they are equal:

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

EDIT: As Jeppe Stig Nielsen pointed out, some objects have an IComparerT> that is incompatible with their IEqualityComparerT>, resulting in inaccurate results. When using keys with this type of object, you must use the right IComparerT>. For example, in order to get correct results using string keys (which exhibit this issue), you must do the following:

dictionary1.OrderBy(kvp => kvp.Key, StringComparer.Ordinal).SequenceEqual(dictionary2.OrderBy(kvp => kvp.Key, StringComparer.Ordinal))

Answered by Allon Guralnek

Solution #3

In addition to the previously mentioned SequenceEqual,

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

It’s worth noting that SetEquals on ISet objects is available in.Net4.

So, if you require a list of objects but don’t need them to be in any particular order, an ISet (like a HashSet) might be the best option.

Answered by Desty

Solution #4

Look through the Enumerable. The technique SequenceEqual is used to compare two sequences.

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);

Answered by aku

Solution #5

Although this does not directly answer your questions, both Microsoft’s TestTools and NUnit have similar functionality.

 CollectionAssert.AreEquivalent

This accomplishes the majority of your objectives.

Answered by tymtam

Post is based on https://stackoverflow.com/questions/43500/is-there-a-built-in-method-to-compare-collections