C#:在具有任意维度的数组中设置所有值

Jus*_*xel 3 c# c#-4.0

我正在寻找一种将多维数组中的每个值设置为单个值的方法。问题是在编译时维度数是未知的——它可能是一维的,也可能是 4 维的。既然foreach不允许你设定值,那么我可以实现这个目标的一种方法是什么?非常感谢。

LBu*_*kin 5

虽然这个问题表面上看起来很简单,但实际上比看起来要复杂得多。然而,通过认识到访问多维(甚至锯齿状)数组中的每个位置是对数组索引集的笛卡尔积运算- 我们可以简化解决方案……并最终编写一个更优雅的解决方案。

我们将利用Eric Lippert 的 LINQ Cartesian Product实现来完成繁重的工作。如果你愿意,你可以在他的博客上阅读更多关于它是如何工作的。

虽然此实现特定于访问多维数组的单元格 - 应该相对容易了解如何扩展它以访问锯齿状数组。

public static class EnumerableExt
{
    // Eric Lippert's Cartesian Product operator...
    public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(
          this IEnumerable<IEnumerable<T>> sequences)
    {
        IEnumerable<IEnumerable<T>> emptyProduct = 
                   new[] { Enumerable.Empty<T>() };
        return sequences.Aggregate(
          emptyProduct,
          (accumulator, sequence) =>
            from accseq in accumulator
            from item in sequence
            select accseq.Concat(new[] { item }));
    }
}

class MDFill
{
    public static void Main()
    {
        // create an arbitrary multidimensional array
        Array mdArray = new int[2,3,4,5];

        // create a sequences of sequences representing all of the possible
        // index positions of each dimension within the MD-array
        var dimensionBounds = 
            Enumerable.Range(0, mdArray.Rank)
               .Select(x => Enumerable.Range(mdArray.GetLowerBound(x),
                      mdArray.GetUpperBound(x) - mdArray.GetLowerBound(x)+1));

        // use the cartesian product to visit every permutation of indexes
        // in the MD array and set each position to a specific value...
        int someValue = 100;
        foreach( var indexSet in dimensionBounds.CartesianProduct() )
        {
            mdArray.SetValue( someValue, indexSet.ToArray() );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在很容易将这段代码分解成一个可重用的方法,该方法可用于锯齿状或多维数组……或任何可被视为矩形数组的数据结构。