views:

212

answers:

4

I want to get the difference between two sets of ints in c#. Given s1 and s2 I want to return those ints which are in s1 and not in s2. I can do something such as:

    List<int> s1 = new List<int>();
    List<int> s2 = new List<int>();

    foreach (int i in s1)
    {
        if (s1.Contains(i))
        {
            //
        }
        else
        {
            //
        }
    }

But I was wondering if anyone can point out anything cleaner. I would like to do something such as

List<int> omitted = s1.Difference(s2);

Not sure if there is an existing method or a LINQ construct that anyone might be able to point out? Thank you.

+5  A: 

I think you want HashSet.Except. That is, rather than use Lists, use HashSets, and then the operation is available. This is a better type if what you are representing is really a 'set' anyway. (If you already have a list, you can just create a 'new HashSet' out of it.)

Brian
awesome thankyou. Except() is the method I was looking for and I take your advice on HashSets.
SiC
Except is an extension function, no?
leppie
There is an extension method Enumerable.Except for all IEnumerables. But HashSet has a method Except specifically for HashSets.
Brian
Except is indeed an extension method that operates on any IEnumerable (see http://msdn.microsoft.com/en-us/library/system.linq.enumerable_members.aspx). That means it works fine on List<T>. Of course, if order doesn't matter HashSet /is/ a more appropriate type.
Matthew Flaschen
Brian, I don't think so. The method you linked above is the extension method. HashSet has a ExceptWith method that destructively removes the elements in the parameter from the instance HashSet, but no Except.
Matthew Flaschen
Matthew: Touche! Thanks for the correction.
Brian
+1  A: 
from x in s1
where ! s2.contains(x)
select x
IMil
+2  A: 
List<int> s1 = new List<int>();
List<int> s2 = new List<int>();

return sl.FindAll( i => !s2.Contains(i) )
Chad Grant
+6  A: 
IEnumerable<T> a, b;

var added = a.Except(b);
var removed = b.Except(a);
leppie
Note that this uses Enumerable.Except, so you need to use System.Linq.http://msdn.microsoft.com/en-us/library/bb300779.aspx
Brian
Is that a problem? :)
leppie
Problem? No, I just wanted to help someone out who might cut-and-paste this code and find that it doesn't compile.
Brian
@Brian, The same caveat also applies to your own answer. HashSet doesn't implement it's own Except method, so your answer requires System.Linq too.
LukeH
my answer requires no LINQ so there!! lol
Chad Grant
@Deviant: But yours run at O(n^2) and mine in O(n) :)
leppie