【问题标题】:How to select a single object using Linq in vb.net如何在 vb.net 中使用 Linq 选择单个对象
【发布时间】:2011-03-18 22:54:29
【问题描述】:

我已经对看似简单的 LINQ 问题进行了大量搜索,但我无法弄清楚如何在不求助于指定最小值(或最大值)的集合中抓取对象排序如下:

dim customers= GetCustomers()

dim youngest = (From c in customers
                 Order By c.age Ascending).ToList.First

这个(未经测试的代码)结构可以正常工作,但必须对整个客户数组进行排序并放入列表中,以便提取第一个值。这不是获得最小值的最佳方法!

请注意,在这种情况下,我想要整个 c 记录,不是可以这样完成的客户的最小年龄(典型示例):

dim customers= GetCustomers()

dim youngest = (From c in customers
                 Select c.age).Min

甚至

dim customers= GetCustomers()

dim youngest = (From c in customers
                 Select c).Min(Function(x) x.age)

我一生都无法弄清楚如何在不诉诸排序的情况下获取整个对象(甚至索引)...

【问题讨论】:

    标签: vb.net linq lambda minimum


    【解决方案1】:

    同样,C# 代码,我不确定我在 VB.NET 中是否正确

    C#

      Customer youngest = customers.Aggregate((c1, c2) => (c1.age < c2.age) ? c1 : c2);
    

    VB.NET

      dim youngest = customers.Aggregate( Function(ByVal c1, ByVal c2) IF( (c1.age < c2.age) , c1 , c2  ) );
    

    【讨论】:

    • 已编辑我第一次答错了,现在是 O(n) 选择。
    • 我最终使用了聚合,它看起来很干净。谢谢。
    • 我认为这是您的第一个问题,您需要接受一个解决您问题的答案。
    【解决方案2】:

    在常规 LINQ 中没有这样的运算符可以避免对整个 IEnumerable 进行排序。但你不是第一个需要解决方案的人。例如在这里查看 Jason 的答案(虽然它是 MaxBy 和 C#,但你会明白的):Simple LINQ question in C#

    MinBy 来自MoreLinq

    【讨论】:

    • 聚合是一次迭代,聚合后你可以选择不排序,检查我的答案。
    • @Sanje,是的,同意。大多数使用Aggregate 的查询看起来有点复杂,但仍然可以。感谢您的想法
    【解决方案3】:

    你快到了。你应该会发现

    dim youngest = (From c in customers
                    Order By c.age Ascending
                    Select c).First
    

    做你正在寻找的东西。 (我是 C# 人,不是 VB.NET 人,所以我的语法可能有点不对。)

    【讨论】:

    • 这基本上就是我的第一个查询所做的。因为您正在执行“按 c.age 排序”,所以有一个隐含的排序,它增加了 O(NlogN) 性能影响与我希望使用 Min 函数看到的 O(N) 行为。
    • 我知道这有一个隐含的排序。我读过你的问题意味着你试图避免 ToList,而不是你想要完全避免这种排序。其他答案给出了 O(N) 行为,所以我更新我的没有任何好处。
    • 实际上没有理由假设首先对列表进行排序。第一次也是唯一一次调用 MoveNext() 可能只返回最小的项目,而不是对整个列表进行排序,这将是 O(N)。这对于具有 ToList 的原始版本是不可能的。在像 Haskell 这样的惰性 eval 语言中,它不会首先对列表进行排序,这将是 O(N)。可悲的是,即使在 .NET 4.0 中,QSORT 似乎也会首先让人们使用 LINQ 玩游戏,而不是声明式
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 2018-11-08
    • 1970-01-01
    • 2019-11-26
    相关资源
    最近更新 更多