Navid Rahmani
Navid Rahmani

Reputation: 7958

Linq getting a list from another list

I have two collections: one is Items And Another is ActiveItems

The only intersection between these two collection is Name

I want a list with Linq from Items where the Items names are in the ActiveItems with that name

I wrote this code is there a better idea:

Items.Where(i => ActiveItems.Count(v=> v.Name==i.Name) > 0)

Upvotes: 9

Views: 23148

Answers (4)

Matthew Manela
Matthew Manela

Reputation: 16752

Using a join:

from item in Items
join active in ActiveItems on item.Name equals active.Name
select item

Upvotes: 0

Bala R
Bala R

Reputation: 108947

var results = from i1 in collection1.Items
              join i2 in collection2.ActiveItems on i1.Name equals i2.Name
              select i2.Name;

Upvotes: 0

Magnus
Magnus

Reputation: 46929

Items.where(i => ActiveItems.Any(a => i.Name == a.Name))

Upvotes: 7

Jon Skeet
Jon Skeet

Reputation: 1500375

I would probably create a set of the names from ActiveItems and then use that:

var activeNames = new HashSet<string>(activeItems.Select(x => x.Name));
var itemsWithActiveNames = items.Where(x => activeNames.Contains(x.Name))
                                .ToList();

Another option is to use a join, e.g. with a query expression:

var query = from activeItem in activeItems
            join item in items on activeItem.Name equals item.Name
            select item;

Note that this will give duplicate item values if there are multiple ActiveItem values with the same name. Another alternative join, which doesn't have this problem but is a bit clumsier:

var query = from item in items
            join activeItem in activeItems 
                on item.Name equals activeItem.Name
                into g
            where g.Any()
            select item;

Note that all of these will avoid the O(N * M) check for names - they'll all use hash tables behind the scenes, to give an O(N + M) complexity.

Upvotes: 17

Related Questions