2011-02-03 143 views
2

我試圖能夠運行鋸齒陣列,但陣列深度不是恆定的。我正在尋找一種乾淨的方式來通過數組中的每個對象。現在我有一個簡單的開關盒,可以通過將它的Rank作爲整數來處理不同的級別。遍歷n維鋸齒陣列

但是有一段時間數組是2級深度,有時候是5級深度。我不想爲每個深度級別寫一個案例。例如,我有一個對象名myObj,有時它是myObj []或myObj [] []或myObj [] [] [] [];使用

任一的foreach或IEnumerator的僅遍歷數組

+1

「myObj,有時它是myObj []或myObj [] []或myObj [] [] [] []」。你知道這是錯誤的語法。向我們展示一段代碼顯示或讀取這些數組的位置。 – Euphoric 2011-02-03 15:35:27

回答

0

你的答案是遞歸的第一尺寸。我不認爲這有效。如果你有一個有孩子收藏的課程,它會工作。

int main() 
{ 
    CheckObj(myObject, 0); 
} 

void CheckObj(object myObject, int level) 
{ 
    if(!(myObject is myObj[])) 
    { 
     foreach(myObj[] o in (myObj[][])myObject) 
     { 
      CheckObj(o, level + 1); 
     } 
    } 
    else 
    { 
     //do what you need to do with myObj[] 
    } 
} 
+0

如果是「myObj [] [] [] []」,當您嘗試將「myObject」強制轉換爲「myObj [] []」時,在我腦海中編譯時不會出現轉換錯誤? – Chris 2011-02-03 16:05:36

1

是這樣的嗎?

static void Main(string[] args) 
    { 
     int[][][] x = new int[][][] 
     { 
      new int[][] 
      { 
       new int [] { 1, 2, 3, 4 }, 
       new int [] { 5, 6 }, 
       new int [] { 7 } 
      }, 
      new int[][] 
      { 
       new int [] { 8 }, 
       new int [] { 9, 10 }, 
       new int [] { 11, 12, 13, 14 } 
      } 
     }; 

     DeepEnumerateArray(x); 
     Console.ReadLine(); 
    } 

    static void DeepEnumerateArray(Array x) 
    { 
     if (x.Length == 0) 
      return; 

     object first = x.GetValue(0); 
     if (first is Array) 
     { 
      foreach (Array y in x) 
       DeepEnumerateArray(y); 
     } 
     else 
     { 
      foreach (object z in x) 
       Console.WriteLine(z); 
     } 
    } 
2

這應該這樣做。 。 。

private static void EnumerateObjects(Array items) 
{ 
    foreach (var item in items) 
    { 
     if (item is Array) 
     { 
      EnumerateObjects((Array)item); 
     } 
     else if (item is MyObject) 
     { 
      Console.WriteLine(item); 
     } 
    } 
} 
4

下面是一個擴展方法來遍歷鋸齒狀/多維數組 (類似於大衛B.一個的,但有產率,空值處理和壓鑄類):

public static class Extensions 
{ 
    public static IEnumerable<T> Traverse<T>(this Array array) 
    { 
     foreach (object val in array) 
     { 
      if (val == null) 
       continue; //null means empty sub-array --> skip it 
      if (val is Array) 
      { 
       var subArray = (Array)val; 
       foreach (var value in subArray.Traverse<T>()) 
        yield return value; 
      } 
      else 
      { 
       yield return (T)val; 
      } 
     } 
    } 
} 

用例:

class Program 
{ 
    static void Main(string[] args) 
    { 
     int[][][] jagged = new int[4][][]; 

     jagged[0] = new int[2][] { new[] { 0, 1 }, new[] { 2, 3, 4 } }; 
     jagged[1] = new int[3][] { new[] { 5, 6, 7 }, new[] { 8, 9, 10 }, new[] { 11, 12 } }; 
     jagged[3] = new int[4][] { new[] { 13, 14 }, null, new[] { 15, }, new[] { 16 } }; 

     var jaggedElements = jagged.Traverse<int>().ToList(); 
     // contains: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 

     int[, ,] multi = new[, ,] { { { 1, 2 }, { 3, 4 } }, 
         { { 4, 5 }, { 6, 7 } }, 
         { { 8, 9 }, { 10, 11 } } }; 


     var multiElements = multi.Traverse<int>().ToList(); 
     // contains: 1,2,3,4,5,6,7,8,9,10,11 

    } 
} 
+1

爲什麼你會在方法結束時有這種「產量突破」?這完全沒有必要。 – svick 2013-09-11 00:30:38