在没有组的对象上执行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

在没有组的对象上执行Linq求和

如果删除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));