1

I'm rather proud to have produced this Linq assertion on my own:

bool assert1 = (from e in A
               select B.Contains<T>(e, new TComparer()))
               .All(x => x == true);

bool assert2 = (from e in B
               select A.Contains<T>(e, new TComparer()))
               .All(x => x == true);

Assert(assert1 && assert2);

This will check that A and B are equal by containing the same elements i.e. A ⊆ B and B ⊆ A.

Is there a prettier way of doing this?

jason
  • 236,483
  • 35
  • 423
  • 525
Martin
  • 2,956
  • 7
  • 30
  • 59
  • 3
    http://stackoverflow.com/questions/1673347/linq-determine-if-two-sequences-contains-exactly-the-same-elements – xofz Jan 24 '10 at 23:59

3 Answers3

3

I would do this:

IComparer<T> comparer = new TComparer();
bool equal = !A.Except(B, comparer).Any() && !B.Except(A, comparer).Any();
jason
  • 236,483
  • 35
  • 423
  • 525
2

What library are you using for assertions? If by any chance it's NUnit, there's a CollectionAssert class with AreEquivalent() method just for this kind of thing.

Linq can be very elegant for collection transformations, but this is exact kind of task, where it takes a huge performance hit if collections are big enough. You would need a temporary Hashtable-based collection (HashSet or Dictionary) with specialized methods to do it fast.

Chriso
  • 289
  • 2
  • 8
  • Good point. However, in my special case, the sets are members of objects tested for equality in an MbUnit (==NUnit in syntax, I believe), so the above is checked a few calls up from the actuall assert. The sets are in most cases <10, so I'll take a pretty solution in this case. – Martin Jan 25 '10 at 09:32
0

how about:

Assert.IsTrue(A.SequenceEqual(B, new SomeEqualityComparer()));

following a clarification in a comment I'm adding a sorting of the sequences. Both sequences should contain a same number of elements anyway.

OrderSequence(A).SequenceEqual(OrderSequence(B), new SomeEqualityComparer());

private static IEnumerable<StudentClass> OrderSequence(IEnumerable<StudentClass> left)
{
    IComparer<StudentClass> comparer = new TComparer();
    return left.OrderBy(a => a, comparer);
}
Boris Lipschitz
  • 9,236
  • 5
  • 53
  • 63
  • `Enumerable.SequenceEqual(other)` is only true if they are equal as a sequence; i.e., they have an equal number of elements and `A.First()` equals `B.First()` (according to `SomeEqualityComparer`), `A.Skip(1).First()` equals `B.Skip(1).First()` (according to `SomeEqualityComparer`), etc. – jason Jan 24 '10 at 23:40