Friday, August 22, 2008

Union to find if two lists match

So let's say you have two lists you want to compare to see if they hold the same items, but the items are not equal reference. Now, if you are comparing two lists that have unique values to compare, Union is perfect.

List 1 { 1, 2, 3, 4, 5 }
List 2 { 2, 1, 4, 3, 5 }

As you can see, there are no repeated values in these two lists. Easy way to figure out if all the values are the same in the two lists:
  var query = (from first in firstList
            select first).Union(from second in secondlist
                                select second);

  Assert.IsTrue(query.Count() == first.Count());
Why does this work? Union combine the two lists, removing any duplicates. So if everything goes correctly, the count of the new list has to match the count of either of the olds lists. After all 5 pairs of duplicate items gets reduced to a list of 5. Now, if there is anything different between the lists the count will get screwed. Why? Because even one difference will cause an extra item to show up in the list.

List 1 { 1, 2, 3, 4, 5 }
List 2 { 1, 2, 3, 4, 6 }
Union { 1, 2, 3, 4 , 5, 6 }

And it will only get worse for every mismatch.

Real worldish example:
    var query = (from user in userListFirst
              select user.UserID).Union(from secondUser in userListSecond
                                       select second.UserID);

    Assert.IsTrue(query.Count() == userListFirst.Count());
Bonus points if you can figure out why this would fail at times. Actually, I already told you...

UsInGS
  using System;
  using System.Linq;

No comments: