5

我需要遍历任意等级的数组。这既适用于阅读又适用于写作,因此GetEnumerator不起作用。

Array.SetValue(object, int)不适用于多维数组。 Array.SetValue(object, params int[])将需要过多的算术来遍历多维空间。它还需要动态调用来绕过params签名的一部分。

我很想固定数组并用指针对其进行迭代,但我找不到任何说明多维数组保证是连续的文档。如果他们在维度的末尾有填充,那么这将不起作用。我也希望避免不安全的代码。

有没有一种简单的方法可以只使用一个索引来顺序寻址多维数组?

4

3 回答 3

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
于 2010-08-04T18:52:42.877 回答
1

您可以使用RankandGetUpperBound属性/方法来创建可以传递给数组的SetValueGetValue方法的索引数组:

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);
}
于 2010-08-04T19:31:26.153 回答
-1

也许您可以将它们全部加入一个临时集合中,然后对其进行迭代。

于 2010-08-04T18:50:12.727 回答