2009-12-07 22 views
6

塗りつぶし多次元矩形配列の書き込み拡張メソッドが必要です。私は、測定の固定数を持つ配列のためにそれを行う方法を知っている:C#の塗りつぶし矩形配列の拡張メソッド

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; 
} 

は、私はすべての多次元長方形の配列のために1 fillメソッドを書くことができますか?

+0

すべての例は、ギザギザではなく長方形の配列です。ギザギザの配列の問題を解決してもよろしいですか? –

+0

申し訳ありませんが、私は私の質問で間違いを犯しました。既に固定 – AndreyAkinshin

答えて

5

任意の配列に拡張子を配置できるように、固定寸法パラメータをArrayパラメータに変更できます。次に、配列の各位置を反復するために再帰を使用しました。ここで

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); 
     } 
    } 
} 
+0

良い解決策。どのようにして、*安全でないコードの*へのポインタの多次元配列で動作するようにあなたのソリューションを修正しますか? –

1

は、再帰を使用しないソリューションです(とそれほど複雑である):

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と同様のレベルの正当性を持ち、(いくつかのスポットチェックに基づいて)正常に機能するように見えます。

関連する問題