用嵌套的Foreach语句迭代multidimensional array
我认为这可能是一个非常简单的问题,但我还没有弄清楚。 如果我有这样的二维数组:
int[,] array = new int[2,3] { {1, 2, 3}, {4, 5, 6} };
用嵌套的foreach语句遍历数组的每个维度的最佳方法是什么?
如果你想迭代数组中的每一项,就好像它是一个扁平数组一样,你可以这样做:
foreach (int i in array) { Console.Write(i); }
这将打印
123456
如果你想能够知道x和y索引,你需要做:
for (int x = 0; x < array.GetLength(0); x += 1) { for (int y = 0; y < array.GetLength(1); y += 1) { Console.Write(array[x, y]); } }
或者,您可以使用锯齿状数组(而不是数组):
int[][] array = new int[2][] { new int[3] {1, 2, 3}, new int[3] {4, 5, 6} }; foreach (int[] subArray in array) { foreach (int i in subArray) { Console.Write(i); } }
要么
int[][] array = new int[2][] { new int[3] {1, 2, 3}, new int[3] {4, 5, 6} }; for (int j = 0; j < array.Length; j += 1) { for (int k = 0; k < array[j].Length; k += 1) { Console.Write(array[j][k]); } }
以下是如何访问二维数组中的每个元素。 这是你在找什么?
for (int i=0;i<array.GetLength(0);i++) { for (int j=0;j<array.GetLength(1);j++) { int cell = array[i,j]; } }
使用multidimensional array,您可以使用相同的方法遍历元素,例如:
int[,] numbers2D = new int[3, 2] { { 9, 99 }, { 3, 33 }, { 5, 55 } }; foreach (int i in numbers2D) { System.Console.Write("{0} ", i); }
这个例子的输出是:
9 99 3 33 5 55
参考
- MSDN:使用foreach与数组
在Java中,multidimensional array是数组的数组,所以下面的工作:
int[][] table = { { 1, 2, 3 }, { 4, 5, 6 }, }; for (int[] row : table) { for (int el : row) { System.out.println(el); } }
我知道这是一个旧的post,但我通过谷歌发现它,玩过之后觉得我有一个更简单的解决scheme。 如果我错了,请指出,“因为我想知道,但这至less对我来说是有效的(这是基于ICR的回应):
for (int x = 0; x < array.GetLength(0); x++) { Console.Write(array[x, 0], array[x,1], array[x,2]); }
由于这两个维度是有限的,任何一个都可以是简单的数字,从而避免嵌套的循环。 我承认我是C#的新手,所以请,如果有理由不这样做,请告诉我…
C#中的二维数组本身并不适合嵌套的foreach,它不等同于锯齿状数组(数组数组)。 你可以做这样的事情来使用foreach
foreach (int i in Enumerable.Range(0, array.GetLength(0))) foreach (int j in Enumerable.Range(0, array.GetLength(1))) Console.WriteLine(array[i, j]);
但是你仍然会使用i和j作为数组的索引值。 可读性将会更好地保留下来,如果你只是去花园品种for
循环来代替。
两种方式:
- 将数组定义为锯齿状数组,并使用嵌套的foreach。
- 通常定义数组,并在整个事物上使用foreach。
#2的例子:
int[,] arr = { { 1, 2 }, { 3, 4 } }; foreach(int a in arr) Console.Write(a);
输出将是1234。 与从0到n,从0到n完全相同。
你可以使用这样的扩展方法:
internal static class ArrayExt { public static IEnumerable<int> Indices(this Array array, int dimension) { for (var i = array.GetLowerBound(dimension); i <= array.GetUpperBound(dimension); i++) { yield return i; } } }
接着:
int[,] array = { { 1, 2, 3 }, { 4, 5, 6 } }; foreach (var i in array.Indices(0)) { foreach (var j in array.Indices(1)) { Console.Write(array[i, j]); } Console.WriteLine(); }
它会比使用循环慢一点,但在大多数情况下可能不是问题。 不知道它是否使事情更可读。
请注意,C#数组可以不是基于零的,所以你可以使用一个for循环,如下所示:
int[,] array = { { 1, 2, 3 }, { 4, 5, 6 } }; for (var i = array.GetLowerBound(0); i <= array.GetUpperBound(0); i++) { for (var j= array.GetLowerBound(1); j <= array.GetUpperBound(1); j++) { Console.Write(array[i, j]); } Console.WriteLine(); }
使用LINQ .Cast<int>()
将二维数组转换为IEnumerable<int>
。
LINQPad例子:
var arr = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } }; IEnumerable<int> values = arr.Cast<int>(); Console.WriteLine(values);
输出:
你也可以使用枚举器。 任何维度的每个数组types都支持Array.GetEnumerator方法。 唯一的警告是,你将不得不处理拳击/拆箱。 然而,你需要写的代码将是相当微不足道的。
以下是示例代码:
class Program { static void Main(string[] args) { int[,] myArray = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 } }; var e = myArray.GetEnumerator(); e.Reset(); while (e.MoveNext()) { // this will output each number from 1 to 6. Console.WriteLine(e.Current.ToString()); } Console.ReadLine(); } }
int[,] arr = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; for(int i = 0; i < arr.GetLength(0); i++){ for (int j = 0; j < arr.GetLength(1); j++) Console.Write( "{0}\t",arr[i, j]); Console.WriteLine(); } output: 1 2 3 4 5 6 7 8 9
正如其他地方所提到的,你可以迭代数组,它会在所有维度上按顺序产生所有结果。 然而,如果你也想知道指数,那么使用这个怎么样 – http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with- linq.aspx
然后做这样的事情:
var dimensionLengthRanges = Enumerable.Range(0, myArray.Rank).Select(x => Enumerable.Range(0, myArray.GetLength(x))); var indicesCombinations = dimensionLengthRanges.CartesianProduct(); foreach (var indices in indicesCombinations) { Console.WriteLine("[{0}] = {1}", string.Join(",", indices), myArray.GetValue(indices.ToArray())); }