代码之家  ›  专栏  ›  技术社区  ›  AndreyAkinshin

C中填充矩形阵列的扩展方法#

  •  7
  • AndreyAkinshin  · 技术社区  · 15 年前

    我要为填充多维矩形数组编写扩展方法。我知道如何对具有固定数量测量值的阵列执行此操作:

    public static void Fill<T>(this T[] source, T value)
    {
        for (int i = 0; i < source.Length; i++)
            source[i] = value;
    }
    public static void Fill<T>(this T[,] source, T value)
    {
        for (int i = 0; i < source.GetLength(0); i++)
            for (int j = 0; j < source.GetLength(1); j++)
                source[i, j] = value;
    }
    public static void Fill<T>(this T[,,] source, T value)
    {
        for (int i = 0; i < source.GetLength(0); i++)
            for (int j = 0; j < source.GetLength(1); j++)
                for (int k = 0; k < source.GetLength(2); k++)
                    source[i, j, k] = value;
    }
    

    我可以为所有多维矩形数组编写一个填充方法吗?

    2 回复  |  直到 15 年前
        1
  •  5
  •   Jake Pearson    15 年前

    可以将固定维度参数更改为数组参数,以便可以将扩展名放在任何数组上。然后我使用递归遍历数组的每个位置。

    public static void Fill<T>(this Array source, T value)
    {
        Fill(0, source, new long[source.Rank], value);
    }
    
    static void Fill<T>(int dimension, Array array, long[] indexes, T value)
    {
        var lowerBound = array.GetLowerBound(dimension);
        var upperBound = array.GetUpperBound(dimension);
        for (int i = lowerBound; i <= upperBound; i++)
        {
            indexes[dimension] = i;
            if (dimension < array.Rank - 1)
            {
                Fill(dimension + 1, array, indexes, value);
            }
            else
            {
                array.SetValue(value, indexes);
            }
        }
    }
    
        2
  •  1
  •   Robert Venables    15 年前

    这里有一个不使用递归(更不复杂)的解决方案:

       public static void FillFlex<T>(this Array source, T value)
        {
    
            bool complete = false;
            int[] indices = new int[source.Rank];
            int index = source.GetLowerBound(0);
            int totalElements = 1;
    
            for (int i = 0; i < source.Rank; i++)
            {
                indices[i] = source.GetLowerBound(i);
                totalElements *= source.GetLength(i);
            }
            indices[indices.Length - 1]--;
            complete = totalElements == 0;
    
            while (!complete)
            {
                index++;
    
                int rank = source.Rank;
                indices[rank - 1]++;
                for (int i = rank - 1; i >= 0; i--)
                {
                    if (indices[i] > source.GetUpperBound(i))
                    {
                        if (i == 0)
                        {
                            complete = true;
                            return;
                        }
                        for (int j = i; j < rank; j++)
                        {
                            indices[j] = source.GetLowerBound(j);
                        }
                        indices[i - 1]++;
                    }
                }
    
                source.SetValue(value, indices);
            }
        }
    

    这是根据System.Array.ArrayEnumerator建模的。这个实现应该具有与arrayEnumerator类似的正确性级别,并且(基于一些抽查)似乎可以正常工作。