二维数组的和列

时间:2014-04-15 15:47:13

标签: c# linq sum

我有一个IEnumerable<IEnumerable<double>>,它基本上可以被认为是一个二维的二维数组,我想要做的是得到一个1D数组(或列表或其他),这是我的所有列的总和原创系列。换句话说,如果我有:

1   2   3   4
2   3   1   6
3   4   5   6
-------------
6   9   9   16

我想要最后一行(显然不是原始集合的一部分)。

有没有一种简单的方法可以使用LINQ来实现这一点,这样我就不必遍历整个事情了?我知道我可以使用.Sum总计一行或一列,但我想总计每一行。

我已经看到了一些其他问题(主要是处理数据库查询),建议使用group,但这似乎对我不起作用。我试过这个:

            var totals = from p in toTotal
                         group p by 1 into g
                         select g.Sum(t => t.First()); 

但这只是一切。

有一种聪明的方法吗?

编辑:例如,如果toTotal定义为:

    List<List<double>> toTotal = new List<List<double>>() {
        new List<double> {1,   2,   3,   4},
        new List<double> {2,   3 ,  1,   6},
        new List<double> {3 ,  4,   5 ,  6}
    };

2 个答案:

答案 0 :(得分:4)

确定。我想我已经碰到了它:

var totals = toTotal.Aggregate((prev, next) => prev.Zip(next, (a, b) => a + b));

诀窍在于我正在寻找Fold(或Reduce)函数,但在LINQ中它被称为Aggregate

这是fiddle显示此行和@Habib的行总计代码(用于比较)。与我在这里(以及我在实际代码中使用的内容)的唯一变化是,我需要.ToList .Zip的结果,因为对于此测试用例,我有一个List<List<double>>如果您没有显式转换为列表,这似乎会扰乱编译器。在我的实际代码中toTotalIEnumerable<IEnumerable<double>>,不需要转换。

答案 1 :(得分:3)

编辑:

你可以这样做:

List<List<double>> toTotal = new List<List<double>>() {
new List<double> {1,   2,   3,   4},
new List<double> {2,   3 ,  1,   6},
new List<double> {3 ,  4,   5 ,  6}
                                };

var res = toTotal.Select(r => r.Select((t, i) => new { Column = i, Value = t }))
                 .SelectMany(r => r)
                 .GroupBy(r => r.Column)
                 .Select(grp => new
                 {
                     Column = grp.Key,
                     Sum = grp.Select(r => r.Value).Sum(),
                 });

foreach (var item in res)
{
    Console.WriteLine("Column: {0}, Sum: {1}", item.Column, item.Sum);
}

你会得到:

Column: 0, Sum: 6
Column: 1, Sum: 9
Column: 2, Sum: 9
Column: 3, Sum: 16

旧答案

IEnumerable Sum的每个元素都需要toTotal,你可以得到它:

double[]totals = toTotal.Select(r => r.Sum()).ToArray();