Remove Subscriber from List

I have 2 lists: list1 and list2 (both types are int)

Now I want to remove the contents of list2 from list1 . How can I do this in C #?

PS: Do not use a loop.

+4
source share
4 answers

IMPORTANT CHANGE

As noted in the comments, .Except() uses the set internally, so any duplicate elements of list1 will be missing in the final result.

Makes the difference set of two sequences

http://msdn.microsoft.com/en-us/library/system.linq.enumerable.except(v=vs.110).aspx

However, there is a solution that is both O (N) and keeps duplicates in the original list: change the RemoveAll(i => list2.Contains(i)) approach RemoveAll(i => list2.Contains(i)) to use the HashSet<int> to store the exception set.

 List<int> list1 = Enumerable.Range(1, 10000000).ToList(); HashSet<int> exclusionSet = Enumerable.Range(500000, 10).ToHashSet(); list1.Remove(i => exclusionSet.Contains(i)); 

The ToHashSet() extension method is available in MoreLinq .

ORIGINAL RESPONSE

You can use linq

 list1 = list1.Except(list2).ToList(); 

UPDATE

Out of curiosity, I did a simple test of my decision against @ HighCore's.

For list2 , which has only one item, its code runs faster. As list2 gets bigger and bigger, its code becomes very slow. It looks like its O (N-square) (or, more specifically, O (list1.length * list2.length), since each item in list1 compared with every item in list2 ). I don’t have enough data to validate Big-O of my solution, but it is much faster when list2 has more than a few items.

Code used for verification:

  List<int> list1 = Enumerable.Range(1, 10000000).ToList(); List<int> list2 = Enumerable.Range(500000, 10).ToList(); // Gets MUCH slower as 10 increases to 100 or 1000 Stopwatch sw = Stopwatch.StartNew(); //list1 = list1.Except(list2).ToList(); list1.RemoveAll(i => list2.Contains(i)); sw.Stop(); var ms1 = sw.ElapsedMilliseconds; 

UPDATE 2

This solution assigns the new list to list1 . As @ Tolya points out, other links (if any) to the original list1 will not be updated. This solution is significantly superior to RemoveAll for all but the smallest list2 sizes. If no other links should see the update, this is preferable for this reason.

+18
source
 list1.RemoveAll(x => list2.Contains(x)); 
+6
source

Mhhhh ... use this:

 List<T> result = list1.Except(list2).ToList(); 
+3
source

This will remove each element in secondList from firstList :

 firstList.RemoveAll( item => { secondList.Contains(item); } ); 
0
source

All Articles