C# 维上的多维数组求和
假设我有这样的锯齿状数组(3维) 我想在第一维度上求和。我想得到: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表达式。由于使用了锯齿状数组,每个组中最小数组的长度用
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();