2011-02-03 116 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