我有一个具有不同尺寸的通用多维数组。我需要循环遍历它,以便为每个元素保存索引的相对数组和相对值。
如果是两个维度的数组,让我们说4和5,那将是微不足道的:
var d1 = 4;
var d2 = 5;
var array = Array.CreateInstance(typeof (int), new[] {d1, d2});
//...
// code for populating array
//...
for (int i = 0; i < d1; i++)
{
for (int j = 0; j < d2; j++)
{
var value = array.GetValue(new[] { i, j });
var indices = new[] {i, j};
}
}
但我需要对n个不同维度的数组做同样的事情。 我怎样才能实现它?我需要实现递归函数吗?
答案 0 :(得分:3)
访问多维数组中的所有元素并不困难。您可以使用单个索引在整个数组中执行平面迭代。棘手的部分是将这个单个索引映射到相应的多维坐标。
通常,给定具有大小向量D
的矩阵,此矩阵的i
单个索引元素具有坐标向量C_i
,这样:
0 <= n < size(D)
。
实现这一点,IndexToCoordinates
方法是:
static int[] IndexToCoordinates(int i, Array arr)
{
var dims = Enumerable.Range(0, arr.Rank)
.Select(arr.GetLength)
.ToArray();
Func<int, int, int> product = (i1, i2) => i1 * i2;
return dims.Select((d, n) => (i/dims.Take(n).Aggregate(1, product))%d).ToArray();
}
现在,例如,如果您想访问多维数组中的每个项目并输出其坐标,您可以这样做:
static void OutputAllArrayIndices(Array arr)
{
var i = 0;
foreach (int item in arr)
{
var coords = IndexToCoordinates(i++, arr);
Console.WriteLine(string.Join(", ", coords));
}
}
运行OutputAllArrayIndices(new int[3, 2, 4])
然后生成:
0, 0, 0
1, 0, 0
2, 0, 0
3, 0, 0
0, 1, 0
1, 1, 0
2, 1, 0
3, 1, 0
0, 0, 1
1, 0, 1
2, 0, 1
3, 0, 1
0, 1, 1
1, 1, 1
2, 1, 1
3, 1, 1
0, 0, 2
1, 0, 2
2, 0, 2
3, 0, 2
0, 1, 2
1, 1, 2
2, 1, 2
3, 1, 2