在没有组的对象上执行Linq求和
本文关键字:执行 Linq 求和 对象 | 更新日期: 2023-09-27 18:20:51
这看起来很简单,但由于某种原因我没有理解。
给定:
public class Foo
{
public List<Bar> Bars { get; private set; }
public Bar Totals { get; private set; }
public Foo()
{
// Blah blah something to populate List of Bars
this.Bars = new List<Bar>()
{
new Bar("Some dude", 50, 1),
new Bar("Some other dude", 60,25)
};
// Calculate Total
var totals = Bars
.GroupBy(gb => gb.CustomerName) // When I comment out line i get "Bar does not contain a definition for "Sum" and no extension...." I want the sum of this without the group.
.Select(s => new
{
Cost = s.Sum(x => x.Cost),
Donation = s.Sum(x => x.Donation),
}
).ToList();
Totals = new Bar("Totals", totals[0].Cost, totals[0].Donation);
}
}
public class Bar
{
public string CustomerName { get; private set; }
public int Cost { get; private set; }
public int Donation { get; private set; }
public int Total { get { return Cost + Donation; } }
public Bar(string customerName, int cost, int donation)
{
this.CustomerName = customerName;
this.Cost = cost;
this.Donation = donation;
}
}
我在这里遇到了一些问题:
-这对按分组有效,但如果我按取出分组,这是我的最终目标,我会得到"Bar不包含"Sum"的定义,也没有扩展……"。我希望整个集合都有这个和,所以不希望按.分组
-在放入Bar之前,我正在创建一个anon对象,因为我不知道如何在没有无参数构造函数的情况下创建Bar(而且我不能向这个特定类添加一个)
-我不喜欢使用索引0访问"var totals"数据——我最后不应该是ToListing吗?如果没有,我如何访问属性?总计。成本不起作用。
请帮我找出解决问题的正确方法(特别是本段以上的3个要点)。对于流利的(以及一般的linq)语法来说,这是一个很新的东西,我正在努力找出正确的方法
编辑:
感谢大家的回复。综合几个答案真的让我达到了我的最终目标(但最感谢的是D Stanley)
这就是我现在的实现方式:
public Foo()
{
// ....
// Calculate Total
Totals = new Bar("Totals", Bars.Sum(s => s.Cost), Bars.Sum(s => s.Donation));
}
我想我只是让它变得比需要的更复杂!:O
如果删除GroupBy
,lambda中的s
变量的类型为Bar
。在您的情况下,您希望它是List<Bar>
。所以,我认为你想要的是:
var totalCosts = Bars.Sum(x => x.Cost);
var totalDonations = Bars.Sum(x => x.Donation);
但是如果我通过"我得到"取出组,条形图不包含"总和"的定义
这是因为当您取出GroupBy
时,您正在对单个项进行迭代,而不是对组的集合进行迭代。如果你想对整个集合求和,请使用
var totals = new
{
Cost = Bars.Sum(x => x.Cost),
Donation = Bars.Sum(x => x.Donation),
}
;
或者,如果你想要一个只有一个项目的集合,只需更改你的GroupBy
:
var totals = Bars
.GroupBy(gb => true) // trivial grouping
.Select(s => new Bar
{
Cost = s.Sum(x => x.Cost),
Donation = s.Sum(x => x.Donation),
}
).ToList();
-在放入Bar之前,我将强制转换为一个anon对象,因为我不知道如何在没有无参数构造函数的情况下强制转换它(而且我不能向这个特定类添加一个)
只需将您的投影更改为
var totals = new Bar("Totals", Bars.Sum(x => x.Cost), Bars.Sum(x => x.Donation));
我不喜欢使用索引0访问"var totals"数据——我最后不应该是ToListing吗?如果没有,我如何访问属性?总计。成本不起作用。
如果你把旁边的小组拿出来,你最终只得到一个物体。如果你有一个项目的集合,你可以使用First
:
Totals = new Bar("Totals", totals.First().Cost, totals.First().Donation);
我想把这笔钱记在整个集合上,所以不想一组通过。
然后在集合上使用Sum
Bars.Sum(x => x.Cost)
在放入Bar之前,我将强制转换为一个anon对象,因为我不知道如何在没有无参数构造函数的情况下强制转换它(而且我不能向这个特定类添加一个)
你没有铸造,你正在创建匿名对象
我不喜欢使用索引0访问"var totals"数据——我最后不应该是ToListing吗?如果没有,我如何访问属性?总计。成本不起作用。
如果您想要单个结果,请使用First
。
很简单,当您执行Bars.Select(s =>
时,s的类型为Bar
,而Bar
没有Sum
的定义。如果你想在没有任何分组的情况下得到所有的总和,你可以这样做:
Bars.Sum(b => b.Cost);
Bars.Sum(b => b.Donation);
您只需要这个:
Totals = new Bar("Totals", Bars.Sum(o => o.Cost), Bars.Sum(o => o.Donation));