Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 维上的多维数组求和_C#_Arrays_Linq_Sum_Jagged Arrays - Fatal编程技术网

C# 维上的多维数组求和

C# 维上的多维数组求和,c#,arrays,linq,sum,jagged-arrays,C#,Arrays,Linq,Sum,Jagged Arrays,假设我有这样的锯齿状数组(3维) 我想在第一维度上求和。我想得到: new int[][] { new int[] {1+7, 2+8, 3+9}, new int[] {4+10, 5+11, 6+12} }; 我想在二维上求和 new int[][] { new int{1+4, 2+5, 3+6}, new int{7+10, 8+11, 9+12} } 这两件事怎么办?我不想要循环,而是LINQ表达式。由于使用了锯齿状数组,每个组中最小数组的长度用

假设我有这样的锯齿状数组(3维)

我想在第一维度上求和。我想得到:

new int[][] 
{
    new int[] {1+7, 2+8, 3+9},
    new int[] {4+10, 5+11, 6+12}
};
我想在二维上求和

new int[][] 
{
    new int{1+4, 2+5, 3+6},
    new int{7+10, 8+11, 9+12}
}

这两件事怎么办?我不想要循环,而是LINQ表达式。

由于使用了锯齿状数组,每个组中最小数组的长度用于索引,以避免出现
索引自动失效异常

// I want to sum it over first dimension.
var firstDimensionSums = tab
    .Aggregate((a, b) => Enumerable.Range(0, Math.Min(a.Length, b.Length))
        .Select(i0 => Enumerable.Range(0, Math.Min(a[i0].Length, a[i0].Length))
            .Select(i1 => a[i0][i1] + b[i0][i1])
            .ToArray())
        .ToArray());

// I want to sum it over second dimension.
var secondDimensionSums = tab
    .Select(nested => nested
        .Aggregate((a,b) => Enumerable.Range(0, nested.Min(x => x.Length))
            .Select(index => a[index] + b[index])
            .ToArray()))
    .ToArray();

这很像APL reduce操作符,它有一个很酷的功能,可以让您在任何维度上进行缩减(例如,
+/tab
+/[1]tab

在第一个维度上,LINQ已经有了一个等价物,
Aggregate
函数。通过其他一些扩展功能,您可以使用它来执行您想要的操作:

public static class Ext {
    public static int[] Add(this int[] v1, int[] v2) => v1.Zip(v2, (v1v, v2v) => v1v+v2v).ToArray();
    public static int[][] Add(this int[][] a1, int[][] a2) => a1.Zip(a2, (a1r, a2r) => a1r.Add(a2r)).ToArray();

    public static TSource Reduce<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func) => source.Aggregate(func);
    public static IEnumerable<T> Reduce2<T>(this IEnumerable<IEnumerable<T>> src, Func<T, T, T> op) => src.Select(s => s.Reduce(op));
}
使用
Reduce2
功能,您可以跨第二维度进行缩减,添加1D数组:

var ans2 = tab.Reduce2((a1, a2) => a1.Add(a2)).ToArray();

既然我写的
Reduce
/
Reduce2
IEnumerable
上的泛型,你必须将
Reduce2
答案转换回数组。

“我不想要循环,而是LINQ表达式”
--你认为LINQ在引擎盖下做什么?你没有多维数组,你有锯齿阵列。一个三维数组看起来像
int[3,3,3]
。而且,这个代码甚至不会编译。我知道如何使用循环,但我希望我的代码更短-你希望什么代码更短?你没有发布任何循环代码。你没有请求帮助,你已经请求某人为你做这项工作。你没有在你的问题中尝试解决这个问题,你已经向我们规定你只想要LINQ答案,尽管这不是最好的选择。你应该试着解决这个问题。这就是为什么你需要在你的问题中加入一个答案。
var ans1 = tab.Reduce((a1, a2) => a1.Add(a2));
var ans2 = tab.Reduce2((a1, a2) => a1.Add(a2)).ToArray();