Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Linq not equals

Tags:

c#

linq

I've 2 list collections in my C# app..A and B.

Both the collections have customer object which has Id and Name attributes.Typically, A has more items than B.

Using Linq,I want to return only those customers whose Id is in A but not in B.

How do I do this?

like image 450
Jimmy Avatar asked Sep 08 '10 15:09

Jimmy


3 Answers

There are multiple approaches to take. The cleanest approach is to use the Except extension method if you have overriden Equals and GetHashCode. If you have not, there are other options.

// have you overriden Equals/GetHashCode?
IEnumerable<Customer> resultsA = listA.Except(listB);

// no override of Equals/GetHashCode? Can you provide an IEqualityComparer<Customer>?
IEnumerable<Customer> resultsB = listA.Except(listB, new CustomerComparer()); // Comparer shown below

// no override of Equals/GetHashCode + no IEqualityComparer<Customer> implementation?
IEnumerable<Customer> resultsC = listA.Where(a => !listB.Any(b => b.Id == a.Id));

// are the lists particularly large? perhaps try a hashset approach 
HashSet<int> customerIds = new HashSet<int>(listB.Select(b => b.Id).Distinct());
IEnumerable<Customer> resultsD = listA.Where(a => !customerIds.Contains(a.Id));

...

class CustomerComparer : IEqualityComparer<Customer>
{
    public bool Equals(Customer x, Customer y)
    {
        return x.Id.Equals(y.Id);
    }

    public int GetHashCode(Customer obj)
    {
        return obj.Id.GetHashCode();
    }
}
like image 84
Anthony Pegram Avatar answered Oct 31 '22 15:10

Anthony Pegram


If you override Equals for your customer object, then just use

A.Except(B);
like image 29
Larsenal Avatar answered Oct 31 '22 15:10

Larsenal


Expanding on Except, providing your own equality so you don't need to change your Equals behavior. I got this from here:

http://www.codeproject.com/KB/dotnet/LINQ.aspx#distinct

List<Customer> customersA = new List<Customer> { new Customer { Id = 1, Name = "A" }, new Customer { Id = 2, Name = "B" } };
List<Customer> customersB = new List<Customer> { new Customer { Id = 1, Name = "A" }, new Customer { Id = 3, Name = "C" } };

var c = (from custA in customersA
        select custA.Id).Distinct()
             .Except((from custB in customersB
            select custB.Id).Distinct());
like image 4
Jim L Avatar answered Oct 31 '22 13:10

Jim L