33

I have two lists and I need to compare them and only return a List of Items not in both.

var listOfIds = new List<int> {1,2,4};

var persons = new ObservableCollection<Person>
{
    new Person {Id = 1, Name = "Person 1"},
    new Person {Id = 2, Name = "Person 2"},
    new Person {Id = 3, Name = "Person 3"},
    new Person {Id = 4, Name = "Person 4"}
};

In this example new Person {Id = 3, Name = "Person 3"} would be the result. A Linq solution would be preferred.

Dave R.
  • 7,166
  • 3
  • 29
  • 52
gulbaek
  • 2,391
  • 13
  • 42
  • 63

5 Answers5

42

not in will work for you

var listOfIds = new List<int> {1,2,4};

var query = from item in persons 
            where !listOfIds .Contains( item.id )
            select item;

You can check for more detail : SQL to LINQ ( Case 7 - Filter data by using IN and NOT IN clause)

Community
  • 1
  • 1
Pranay Rana
  • 170,430
  • 35
  • 234
  • 261
37

You can also use lambda:

var query = persons.Where(item => !listOfIds.Contains(item.Id));
Mohamed Abed
  • 4,857
  • 20
  • 30
20
var list1 = new List<int> {1,2,3,4,5};
var list2 = new List<int> {2,3,4,5,6};

list1.Except(list2); //1 - items removed
list2.Except(list1); //6 - items added
Kris Kilton
  • 819
  • 8
  • 11
1

With Linq in C# you can do the following variants which give the same results:

int[] numbers1 = { 1,2,3,4 };
int[] numbers2 = { 3,4,5,6 };

// Ac V Bc, thus complement of A plus the complement of B
IEnumerable<int> differencesVariant1 = 
numbers1.Except(numbers2).Union(numbers2.Except(numbers1));

// (A V b)c, thus complement of (set A plus set B)
IEnumerable<int> differencesVariant2 = 
numbers1.Union(numbers2).Except(numbers1.Intersect(numbers2));

Console.WriteLine("variant 1:");
foreach (int number in differencesVariant1)
    Console.WriteLine(number);   // prints: 1,2,5,6

Console.WriteLine("variant 2:");
foreach (int number in differencesVariant2)
    Console.WriteLine(number);   // prints: 1,2,5,6
Robin
  • 151
  • 5
-3

10 years later. You can write your own extension method. With that you don´t need to worry about which set has the longest length.

public static IEnumerable<T> Difference<T>(this IEnumerable<T> set1, IEnumerable<T> set2)
    {
        IEnumerable<T> biggerSet = set2;
        IEnumerable<T> smallerSet = set1;
        if(set1.Count() > set2.Count())
        {
            biggerSet = set1;
            smallerSet = set2;
        }
        return biggerSet.Except(smallerSet);
    }
rubendmatos1985
  • 420
  • 3
  • 11