2009-12-07 58 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; 
} 

我可以寫一個填充方法爲所有多維矩形陣列?

+0

你所有的例子都是矩形數組,而不是參差不齊的數組。你確定你想解決鋸齒陣列的問題嗎? – 2009-12-07 15:05:05

+0

對不起,我在我的問題中犯了一個錯誤。已經修復 – AndreyAkinshin 2009-12-07 15:17:30

回答

5

您可以將固定尺寸參數更改爲Array參數,以便您可以將擴展名置於任何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

不錯的解決方案。你將如何修改你的解決方案,使其能夠在不安全的代碼中使用*指向整數*的指針的多維數組? – 2009-12-07 16:13:29

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具有類似的正確性,並且(基於幾次抽查)看起來運行良好。