繁体   English   中英

通过更高阶方法遍历n维数组

[英]Traversal of n-dimensional array via a higher-order method

这是一个扩展方法, 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可以在任何级别的阵列工作?

无法使用任意数量的参数指定泛型,因此您必须将过程传递给索引数组。 最简单的方法是使用递归,所以这是一种递归方式。 由于它使用可选参数,因此需要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));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM