遍历一个n维数组

3

我有一个通用的多维数组,不同的维度。我需要循环遍历它,以便为每个元素保存相关的索引数组和相关值。

对于一个二维数组,比如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个元素数组上执行相同的操作。我该如何实现?是否需要实现递归函数?


你已经有一个 n 维数组,只需要编写迭代它的代码吗? - Asad Saeeduddin
是的,给定了n维数组。我需要独立于其维度的数量和大小对其进行迭代。 - user3778737
给定一个n维数组,您可以通过对数组进行平坦迭代,并使用模运算符来确定您所在的索引。 - Asad Saeeduddin
谢谢Asad的回答。你能写一个例子吗?我不确定如何使用模运算符来获取值和索引。 - user3778737
1
我可以假设每个维度的下限为0,上限为该维度的大小吗? - Asad Saeeduddin
显示剩余2条评论
1个回答

5
访问多维数组中的所有元素并不困难。您可以通过单个索引对整个数组进行扁平迭代。棘手的部分是将此单个索引映射到相应的多维坐标。
通常,给定大小向量D的矩阵,该矩阵的第i个单索引元素具有坐标向量Ci,如下所示: 对于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

谢谢Asad。你的代码真的很好,尽管我认为维度不应该被反转,因为坐标数组被错误地反转了。你也可以在你发布的输出中注意到这种行为。 - user3778737

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接