【问题标题】:Linq: How to query items from a collection until the sum reaches a certain valueLinq:如何从集合中查询项目直到总和达到某个值
【发布时间】:2009-10-30 21:20:42
【问题描述】:

给定以下对象:

public class Product {
   string Name {get;} 
   int Quantity {get;}
}

使用 Linq,我将如何查询 List<Product>,直到我得到一个给定数量的总和 >=?换句话说,如果我的列表看起来像

Name     Quantity
-----------------
prod1       5
prod2       6
prod7       7

我想查询 List 并提取实例,直到我得到 Sum >=8。在这种情况下,我会得到列表中的前两项。如果我想要 sum >= 12,我会得到全部三个。

我知道我可以编写一个循环来为我执行此操作,但我幻想有一些巧妙的单线使用 Linq 来实现同样的事情。

谢谢

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    这是一个快速的 2 班轮。

    var sum = 0;
    var query = col.Where(x => { var temp = sum; sum += x.Quantity; return temp < 500; });
    

    将 500 替换为您选择的常量或变量。

    编辑

    这是 mquander 更有效的解决方案

    var sum = 0;
    var query = col.TakeWhile(x => { var temp = sum; sum += x.Quantity; return temp < 500; });
    

    【讨论】:

    • 使用 .TakeWhile() 代替 .Where() 并检查开始时的总和是否大于 500,而不是在结束(否则你会采取一个太少的元素。)然后当 500 障碍被打破时迭代将停止。
    • TakeWhile() 要好得多。好一个@mquander!
    • 附注:“LINQ to SQL”无法做到这一点:A lambda expression with a statement body cannot be converted to an expression tree
    • @Legends 在TakeWhileWhere 之前使用AsEnumerable() 来解决此错误
    【解决方案2】:

    您只需创建一个变量来保存总和,然后在使用 where 子句测试列表中的每个项目时添加到它:

    int sum = 0;
    from product in list where (sum += product.Quantity) < 8 select product
    

    【讨论】:

    • 有趣的是,我使用 Linq 越多,我发现自己越倾向于扩展方法语法,除非我以非常 sql-ish 的方式查询源代码。我想知道这是否是 linq 使用的常见模式?
    • 可能 - 对我来说还为时尚早。
    • 这种使用模式是我所经历的......如果您只想过滤,那么编写 from 和 select 子句没有什么意义。我恢复到查询理解语法以使用“let”子句。
    猜你喜欢
    • 2019-10-03
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 2018-02-24
    • 1970-01-01
    相关资源
    最近更新 更多