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?
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();
}
}
If you override Equals for your customer object, then just use
A.Except(B);
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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With