w3dev
w3dev

Reputation: 555

Select object from nested collection using Linq

I have a class structure something like this:

class MyClass
{
    public IEnumerable<AttributeGroup> AttributeGroups { get; set; }
}

class AttributeGroup
{
    public IEnumerable<Attribute> Attributes { get; set; }
}

class Attribute
{
    public string SomeProp { get; set; }
}

I need to get all 'Attributes' which has a specific 'SomeProp' value no matter which Attribute Group they belong to.

For example, SomeProperty== 'A' can be found in both MyClassObj.AttributeGroup[0] and MyClassObj.AttributeGroup[5] and I need to write a Linq (or something like that) to fetch two objects from these two different attributegroups.

Any suggestion?

Upvotes: 11

Views: 38467

Answers (3)

Andreas Schlapsi
Andreas Schlapsi

Reputation: 403

Have a look at SelectMany (http://msdn.microsoft.com/en-us/library/bb534336.aspx).

For example:

myClassObjs.SelectMany(o => o.AttributeGroups.SelectMany(g => g.Attributes)).Where(a => a.SomeProp == "A")

This line selects all Attribute objects of all AttributeGroups of all MyClass objects where SomeProp equals "A". a in the lambda expression for Where is of type Attribute.

Upvotes: 3

First select all attributes from all attribute groups, then only select the ones with your property.

IEnumerable<Attribute> attributes =
    myClassInstance
        .AttributeGroups
        .SelectMany(x => x.Attributes)
        .Where(x => x.SomeProperty == 'A');

Other Linq-style syntax:

IEnumerable<Attribute> attributes =
    from attributeGroup in myClassInstance.AttributeGroups
    from attribute in attributeGroup.Attributes
    where attribute.SomeProperty == 'A'
    select attribute;

Upvotes: 28

Marcelo Cantos
Marcelo Cantos

Reputation: 186118

Your example isn't clear; I can't tell what you mean by, "two object from these two different attributegroups". I'll guess that you want the groups that have attributes with the property in question:

from g in MyClassObj.AttributeGroups
where g.Any(attr => attr.SomeProperty == "A")
select g

Upvotes: 0

Related Questions