我需要遍历任意排名的数组。这适用于阅读和写作,因此GetEnumerator
将无效。
Array.SetValue(object, int)
不适用于多维数组。
Array.SetValue(object, params int[])
需要过多的算术来迭代多维空间。它还需要动态调用来绕过签名的params
部分。
我很想固定数组并用指针迭代它,但我找不到任何文档说多维数组保证是连续的。如果他们在维度的末尾有填充,那么这将无效。我也更愿意避免不安全的代码。
是否有一种简单的方法可以仅使用单个索引顺序寻址多维数组?
答案 0 :(得分:5)
保证多维数组是连续的。来自ECMA-335:
数组元素应按行主要顺序排列在数组对象中(即,与最右边的数组维度相关联的元素应从最低到最高的索引连续布局。)
这样可行:
int[,,,] array = new int[10, 10, 10, 10];
fixed (int* ptr = array)
{
ptr[10] = 42;
}
int result = array[0, 0, 1, 0]; // == 42
答案 1 :(得分:1)
您可以使用Rank
和GetUpperBound
属性/方法创建一个可以传递给数组的SetValue
和GetValue
方法的索引数组:
int[] Indices(Array a, int idx)
{
var indices = new int[a.Rank];
for (var i = 0; i < a.Rank; i++)
{
var div = 1;
for (var j = i + 1; j < a.Rank; j++)
{
div *= a.GetLength(j);
}
indices[i] = a.GetLowerBound(i) + idx / div % a.GetLength(i);
}
return indices;
}
..并像这样使用它:
for (var i = 0; i < array.Length; i++)
{
var indices = Indices(array, i);
array.SetValue(i, indices);
var val = array.GetValue(indices);
}
答案 2 :(得分:-1)
也许你可以将它们全部加入到一个临时集合中,然后迭代它。