John Humphreys
John Humphreys

Reputation: 39354

Using LINQ to filter a list of items based on those items' presence in another list

I'm trying to learn LINQ by practice. This seems like a situation where I should be able to use it, but I can't quite figure out if it's possible or if I'm barking up the wrong tree.

Can I achieve what's in the brackets [] with a one-liner LINQ query given the use case below?

List<Command> list1, list2;

PopulateCommandLists(list1, list2);

foreach(Command cmd in list1)
{
    if ([cmd.Name is present as the Name in any of list2's Command objects])
    {
        //some code.
    }
}

Upvotes: 3

Views: 988

Answers (5)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727087

Try this:

if (list2.Any(item => item.Name == cmd.Name)) {
}

Here is the "anatomy" of the statement:

  • Any applies its condition to each item of list2, and returns true if true has been returned for any item from the list
  • The predicate inside Any tests for item's name to be equal to that of cmd.

You can fold the if into LINQ as well:

foreach (var cmd in list1.Where(c => list2.Any(item => item.Name == c.Name))) {
    ...
}

Upvotes: 6

Austin Salonen
Austin Salonen

Reputation: 50245

I think this is what you want.

if (list2.Any(l2c => l2c.Name == cmd.Name))
{ ... }

but you can add it to the foreach and avoid the if in your code:

foreach(Command cmd in list1.Where(l1c => list2.Any(l2c => l2c.Name == l1c.Name)))
{
    ... some code ...
}

If you control the Command class and can define equality in it (overriding Equals, etc), you can simply use Intersect:

foreach(var cmd in list1.Intersect(list2))
{ ... }

If you don't control Command or don't want to define equality in the class, you can still use Intersect with an IEqualityComparer

foreach(var cmd in list1.Intersect(list2, new CommandComparer()))
{ ... }

class CommandComparer : IEqualityComparer<Command>
{ ... }

Upvotes: 5

NominSim
NominSim

Reputation: 8511

You can get the enumerable itself as:

var query = list1.Where(cmd => (list2.Any(item => item.Name == cmd.Name)));

Then just loop over query, which will contain every Command you want:

foreach( Command cmd in query)
{
    // Do something
}

Upvotes: 3

Marty
Marty

Reputation: 7522

I think you are looking for something like this

if(list2.Any(list2cmd=> list2cmd.Name == cmd.name))
{
    // do stuff
}

Upvotes: 3

sisve
sisve

Reputation: 19791

if (list2.Any(x => x.Name == cmd.Name)) { }

Upvotes: 5

Related Questions