tags:

views:

54

answers:

3

Hi all, Just a bit rusty on the old linq. If I have 2 collections EG NewCustomerList and OldCustomerList and see if a surname exists already how would I do it in linq .I am sure there are many ways. SelectMany rings a bell but forgot how to do it!

In a forEach I would do something like that. What is the equivalent in linq?

     foreach (var  oldCustomer in OldCustomerList)
     {
        foreach (var newCustomer in NewCustomerList.Where(x => x.Surname == oldCustomer.Surname))
        {
           break;
        }
     } 

Any Suggestions? Thanks a lot

+3  A: 

So you're trying to see whether any of the old customer surnames are in the new customer list?

One simple option: do a join and see if it's empty:

if (OldCustomerList.Join(NewCustomerList, x => x.Surname, x => x.Surname,
                         (x, y) => null).Any())
{
    ...
}

(I've used a null projection because we really don't care about the join result.)

Another option:

var oldSurnames = new HashSet<string>(OldCustomrList.Select(x => x.Surname));
if (NewSurnameList.Any(x => oldSurnames.Contains(x.Surname))
{
    ...
}

I suspect you may find that you actually want the result in terms of which surnames are in common though... if you can give us more context, we may be able to help you more.

Jon Skeet
Thanks for your reply.your examples really helped me to understand.The above is just a noddy example I put together to understand how you deal with 2 collections when you want to find whether an item with a particular property EG Surname exists in the other collection. Was I off the mark with SelectMany? Thanks for your help
@user451259: SelectMany would have been a very direct translation of your nested-foreach code - but it's inefficient. It's an O(n * m) approach instead of the O(n + m) approach of my code, if you see what I mean.
Jon Skeet
+2  A: 

You can do this by:

NewCustomerList.Where(n => OldCustomerList.Any(o => o.Surname == n.Surname))
Yogesh
+1  A: 

Here's another approach, which also has O(n + m) complexity + quick-pass semantics:

OldCustomerList.Select(cust => cust.Surname)
               .Intersect(NewCustomerList.Select(cust => cust.Surname))
               .Any();

IMO, it is more readable than an explicit Enumerable.Join: "test if the projection of surnames from the old customer-list has any elements in common with the projection of surnames from the new customer-list", which is pretty close to the problem-statement.

Ani
That's certainly a good alternative. I wish there were an "IntersectBy" standard LINQ operator, so we could just do `OldCustomerList.IntersectBy(NewCustomerList, x => x.Surname)`...
Jon Skeet