sakura-bloom
sakura-bloom

Reputation: 4594

Select objects that contain specific child elements

I have the following classes.

public class Bin
{
    public int BinId { get; set; }
    public IEnumerable<Component> Components { get; set; }
}

public class Component 
{
    public int ComponentId { get; set; }
    public string ComponentName { get; set; }
}

Using LINQ how do I find all Bin objects that contain specific set of components, say components with IDs 1, 2, 3?

Edit

Just to clarify all IDs must be present in a Bin. Also I have a collection that contains IDs to match.

Upvotes: 0

Views: 79

Answers (4)

CodingYoshi
CodingYoshi

Reputation: 26989

var bins = new List<Bin>();
var ids = new List<int> { 1, 2, 3 };

// go through each bin and make sure it has all the items in ids
bins.Where(x => ids.All(id => x.Components.Select(c => 
    c.ComponentId).Contains(id)));

Upvotes: 1

Anton&#237;n Lejsek
Anton&#237;n Lejsek

Reputation: 6103

IEnumerable<int> test = ...;
bins.Where(x => !test.Except(x.Components.Select(c => c.ComponentId)).Any());

Upvotes: 1

Alex Lyalka
Alex Lyalka

Reputation: 1641

Like this:

bins.Where(b => b.Components.Any( c => new[]{1,2,3}.Contains(c.ComponentId) )

If you need all:

bins.Where(b => b.Components.All( c => new[]{1,2,3}.Any( i => i == c.ComponentId) ))

Or if you need that some items in the list has this items:

bins.Where(b => new[]{1,2,3}.All(i => b.Components.Any(c => i == c.ComponentId) ))

You can combine all/any/contains in sub query as you want

Upvotes: 1

Rey
Rey

Reputation: 4002

bins.Where(x => x.Components.Any(y  => y.ComponentId ==1 || y.ComponentId == 2 || y.ComponentId == 3))

Try this one.

If you have list of integers then you can modify last conditions like below.

y => list.Any(z => y.ComponentId == z)

Or something like this.

y => list.Contains(y.ComponentId)

These conditions are to contain at least one component id. If you want to contain all component ids you can use All method instead of Any

Upvotes: 0

Related Questions