简体   繁体   中英

Understanding LINQ subquery

I used a normal query inside a foreach to reach my goal, but I think there is a better way.

int max = 0;
foreach(Area area in myZoo.AreaList)
{
    max = (from a in area.AnimalList
           select a.ID).Max();
}
return max;

How can I use a pure LINQ to get the max of all sublists? ( Animal is a List of the class Animal inside the AreaList and contains an Int32 called ID ) Erm, and Lambda is welcome, so don't hastitate to answer only because you only know the lambda answer ;)

public class Zoo
{
    public List<Area> AreaList {get; set;}
}

public class Area
{
    public List<Animal> AnimalList {get; set;}
}

public class Animal
{
    public List<int> Id {get; set;}
}

Only the short form so no one gets confused ;)

Although SelectMany works, I feel query is more readable in such case.

var max = (from area in myZoo.AreaList
           from animal in area.AnimalList
           from id in animal.Id
           select id).Max();

You are looking for a nested SelectMany .

SelectMany will return a single IEnumerable<T> from the many "inner" Ienumerable<T> - so Zoo.SelectMany(a => a.AreaList) will return a single IEnumerable<Area> containing all the IEnumerable<Area> from the Area property - then you do it one more time for the List<Animal> in the Area class:

Sample data:

var zoo = new Zoo() {
    AreaList = new List<Area>()
    {
        new Area() 
        {
            AnimalList = new List<Animal>()
            {
                new Animal() {Id = new List<int>() {1, 2, 3}},
                new Animal() {Id = new List<int>() {4, 5, 6}}
            }
        },
        new Area() 
        {
            AnimalList = new List<Animal>()
            {
                new Animal() {Id = new List<int>() {7, 8, 9}},
                new Animal() {Id = new List<int>() {10, 11}}
            }
        },
    }
};

Linq query:

var max = zoo.AreaList.SelectMany(a => a.AnimalList).SelectMany(a => a.Id).Max();

Console.WriteLine(max);

Result: 11

In query syntax you can do SelectMany by chaining from clauses, as shown in gxp's answer. (Personally, I prefer the method chaining syntax, so it took me some time to figure that one out...)

var max = zoo.AreaList.Max(arl => arl.AnimalList.Max(anl => anl.Id)).Max();

The maximum value of all maximum values of all AnimalLists , and the Max of them.

That's effectievly the same as ZoharPeled's SelectMany , except he flattens the list and takes the max of all items where I take the max of each list again and again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM