这是一个扩展方法each
,可用于将Action<int, int, T>
应用于每个元素,并且它是二维数组的相应索引:
static public void each<T>(this T[,] a, Action<int, int, T> proc)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
proc(i, j, a[i, j]);
}
使用示例:
var arr = new int[3, 3];
arr.each((x, y, val) => arr[x, y] = x + y);
arr.each((x, y, val) => Console.WriteLine("{0} {1} {2}", x, y, val));
是否可以编写each
的版本,可以在任何级别的数组上工作?
答案 0 :(得分:3)
无法使用任意数量的参数指定泛型,因此您必须将过程传递给索引数组。最简单的方法是使用递归,所以这是一种递归方式。由于它使用可选参数,因此需要C#4.0或更高版本。
static class Arrays
{
public static void Each<T>(this Array a,
Action<int[], T> proc,
int[] startAt = null)
{
int rank = startAt == null ? 0 : startAt.Length;
int[] indices = new int[rank + 1];
if (rank > 0)
startAt.CopyTo(indices, 0);
for (int i = a.GetLowerBound(rank); i <= a.GetUpperBound(rank); i++)
{
indices[rank] = i;
if (rank == a.Rank - 1)
proc(indices, (T)a.GetValue(indices));
else
Each(a, proc, indices);
}
}
}
你会这样称呼:
var array = new int[1, 2, 3, 4, 5];
array.Each<int>((indices, data) => array.SetValue(indices.Sum(), indices));
array.Each<int>((indices, data) =>
Console.WriteLine(string.Join(", ", indices) + ": " + data));