devklick
devklick

Reputation: 2629

Inner join two lists based on a child list

I have two lists of different types of custom objects, and I'm trying to perform an inner join where the join criteria is contained within a child list of the objects.

Here's an example of my objects:

public class Container
{
    public List<Reference> Refs;

    public Container(List<Reference> refs )
    {
        Refs = refs;
    }
}

public class Reference
{
    public int Id;

    public Reference(int id )
    {
        Id = id;
    }
}

And here's an example the data I'm working with:

List<Container> containers = new List<Container>()
{
    new Container(new List<Reference>()
    {
        new Reference(1),
        new Reference(2),
        new Reference(3)
    }),

    new Container(new List<Reference>()
    {
        new Reference(4),
        new Reference(5),
        new Reference(6)
    })
};

List<Reference> references = new List<Reference>()
{
    new Reference(4),
    new Reference(5),
    new Reference(6)
};

I'm trying to select all the Containers in List<Container> which have a matching Reference in the List<Reference> based on Reference.Id. With this data, I expect only the second item in the List<Container> to be selected.

If it were valid syntax, I'd be looking to do something along the lines of:

var query = from c in containers
            join r in references on c.Refs.Contains( r.Id )
            select c;

How can this be done? Thanks


Sorry for the poor title. I'm struggling to put this scenario into a short group of words - please suggest an edit if you can think of something more suitable. Thanks

Upvotes: 1

Views: 401

Answers (3)

Ousmane D.
Ousmane D.

Reputation: 56423

an inner join is not necessary here, you're better off without it:

containers.Where(c => c.Refs.Any(x => references.Any(e => x.Id == e.Id)));

or if you want the entire set of Id's to be equal then use SequenceEqual:

var sequence = references.Select(e => e.Id);
var result = containers.Where(c => c.Refs.Select(s => s.Id).SequenceEqual(sequence));

Upvotes: 1

Code Pope
Code Pope

Reputation: 5449

I would use:

var query = from c in containers where c.Refs.SequenceEqual(references)
                select c;

No join is necessary.

Upvotes: 0

Varty
Varty

Reputation: 363

containers.Where(c => c.Refs.Select(r => r.Id).Intersect(references.Select(r => r.Id)).Any());

Upvotes: 1

Related Questions