【问题标题】:Understanding LINQ subquery了解 LINQ 子查询
【发布时间】:2018-04-26 09:54:56
【问题描述】:

我在foreach 中使用了普通查询来达到我的目标,但我认为还有更好的方法。

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

如何使用纯 LINQ 获取所有子列表的 max? (Animalclass Animal 内的 class AnimalList AreaList 并包含一个名为 IDInt32)Erm,欢迎使用 Lambda,所以不要急于回答,因为您只知道lambda 答案 ;)

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;}
}

只有简短的形式,所以没有人会感到困惑;)

【问题讨论】:

    标签: c# list linq lambda


    【解决方案1】:

    虽然SelectMany 有效,但我觉得在这种情况下查询更具可读性。

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

    【讨论】:

    • 谢谢。我不知道的那个(来自 x in y 和 x.a 中的 a)对我来说是新的,谢谢。
    【解决方案2】:

    您正在寻找嵌套的SelectMany

    SelectMany 将从多个“内部”Ienumerable&lt;T&gt; 返回一个 IEnumerable&lt;T&gt; - 所以 Zoo.SelectMany(a =&gt; a.AreaList) 将返回一个包含来自 Area 属性的所有 IEnumerable&lt;Area&gt; 的单个 IEnumerable&lt;Area&gt; - 然后你做在Area 类中的List&lt;Animal&gt; 再来一次:

    样本数据:

    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 查询:

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

    结果:1​​1

    在查询语法中,您可以通过链接from 子句来执行SelectMany,如gxp 的答案所示。 (就我个人而言,我更喜欢方法链接语法,所以我花了一些时间才弄清楚……)

    【讨论】:

    • 很高兴为您提供帮助 :-)
    • @ZoharPeled 我想出了这个zoo.AreaList.SelectMany(x =&gt; x.AnimalList.Select(y =&gt; y.Id.Max())).Max(); 解决方案,但是由于已经选择了答案,所以我没有发布它。但是你能解释一下你和我的方法之间的比较吗?
    • 这基本上是我的和 zᴉɹɥƆ 的答案之间的组合 - 你做一个SelectMany 来展平一个列表,然后得到最大值的最大值。
    • @ZoharPeled 是的,我通过阅读所有答案了解到这一点(这就是我没有回答的原因),而且我还阅读了您对 zᴉɹɥƆ 答案的评论。我在问这个“SelectMany 可以展平一个列表,然后得到最大值的最大值”,结果有利于空间复杂度吗?
    • @Amit 我不知道,我认为这并不重要。您应该编写代码以提高可读性。除非处理大量数据,否则空间复杂性在 2018 年应该无关紧要。
    【解决方案3】:
    var max = zoo.AreaList.Max(arl => arl.AnimalList.Max(anl => anl.Id)).Max();
    

    所有AnimalLists的最大值中的最大值,以及它们的最大值。

    这实际上与 ZoharPeled 的 SelectMany 相同,只是他将列表展平并取所有项目的最大值,而我一次又一次地取每个列表的最大值。

    【讨论】:

    • 不错!我希望我自己能想到那个:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 2016-09-26
    相关资源
    最近更新 更多