具有lambda表达式C#的对象列表中的累积和

时间:2018-03-01 01:19:18

标签: c# lambda sum aggregate

我需要使用lambda表达式在列表中显示累积和。你知道我怎么做吗? 我有这个回报:

[
{
    "dt_created": "2018-02-25",
    "qtNewItens": 1
},
{
    "dt_created": "2018-02-26",
    "qtNewItens": 1
},
{
    "dt_created": "2018-02-27",
    "qtNewItens": 2
}

但我必须显示:

[
{
    "dt_created": "2018-02-25",
    "qtNewItens": 1
},
{
    "dt_created": "2018-02-26",
    "qtNewItens": 2
},
{
    "dt_created": "2018-02-27",
    "qtNewItens": 4
}

我不知道是否可以使用GroupBy或Aggregate

我尝试这样的事情,但错了:

var newItensByDay = ctx.Itens
                    .GroupBy(x => new { Data = x.dt_created, x.Id })
                    .Select(g => new {
                        Qt = g.Select(x => x.Id).Count(),
                        Dt_created = g.Select(x => x.dt_created).FirstOrDefault()
                    })
                    .GroupBy(x => new { x.Qt, x.Dt_created })
                    .Select(grp => new {
                        dt_created = grp.Key.Dt_created,
                        qtNewItens = grp.Sum(x => x.Qt)
                    });

3 个答案:

答案 0 :(得分:1)

在分组

后考虑以下累积选择
var itemsByDay = ctx.Itens
                    .GroupBy(x => x.dt_created)
                    .Select(g => new {
                        Qt = g.Count(),
                        Dt_created = g.Key
                    });

var count = 0;
var cumulativeByDay = itemsByDay.Select(x => {
    count += x.Qt;
    var result = new {
        dt_created = x.Dt_created,
        qtNewItens = count
    };
    return result;
});

答案 1 :(得分:1)

这应该做你想要的:

var runningTotal = 0;
dataList.Select(x=>new Data(){dt_created = x.dt_created, qtNewItems = (runningTotal+=x.qtNewItems)}).Dump();

本质上,它将一个变量用作runningTotal,然后在投影中使用runningTotal+=x.qtNewItems将值添加到运行总计中,然后将其分配给新对象。

答案 2 :(得分:1)

如果您希望客户端代码是一个表达式,您可以创建一个通用的AccumulatingSelect迭代器并像这样使用它:

source.AccumulatingSelect (
    0, 
    (s, a) => s.qtNewItens + a, 
    (s, a) => new { s.dt_created, TotalToDate = a })

public static class Extensions {
    public static IEnumerable<V> AccumulatingSelect<T, U, V>(
      this IEnumerable<T> source, 
      U seed, 
      Func<T, U, U> accumulator, 
      Func<T, U, V> projector)
    {
        U acc = seed;
        foreach (var value in source)
        {
            acc = accumulator(value, acc);
            yield return projector(value, acc);
        }
    }
}

这是@Chris gave

的过度版本