Iterate Multi-Dimensional Array with Nested Foreach Statement

爱⌒轻易说出口 提交于 2019-11-26 18:33:33

If you want to iterate over every item in the array as if it were a flattened array, you can just do:

foreach (int i in array) {
    Console.Write(i);
}

which would print

123456

If you want to be able to know the x and y indexes as well, you'll need to do:

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

Alternatively you could use a jagged array instead (an array of arrays):

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

or

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

Here's how to visit each element in a 2-dimensional array. Is this what you were looking for?

for (int i=0;i<array.GetLength(0);i++)
{
    for (int j=0;j<array.GetLength(1);j++)
    {
        int cell = array[i,j];
    }
}

With multidimensional arrays, you can use the same method to iterate through the elements, for example:

int[,] numbers2D = new int[3, 2] { { 9, 99 }, { 3, 33 }, { 5, 55 } };
foreach (int i in numbers2D)
{
    System.Console.Write("{0} ", i);
}

The output of this example is:

9 99 3 33 5 55

References


In Java, multidimensional arrays are array of arrays, so the following works:

    int[][] table = {
            { 1, 2, 3 },
            { 4, 5, 6 },
    };
    for (int[] row : table) {
        for (int el : row) {
            System.out.println(el);
        }
    }

I know this is an old post, but I found it through Google, and after playing with it think I have an easier solution. If I'm wrong please point it out, 'cuz I'd like to know, but this worked for my purposes at least (It's based off of ICR's response):

for (int x = 0; x < array.GetLength(0); x++)
{
    Console.Write(array[x, 0], array[x,1], array[x,2]);
}

Since the both dimensions are limited, either one can be simple numbers, and thus avoid a nested for loop. I admit I'm new to C#, so please, if there's a reason not to do it, please tell me...

The 2D array in C# does not lend itself well to a nested foreach, it is not the equivalent of a jagged array (an array of arrays). You could do something like this to use a 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]);

But you would still use i and j as index values for the array. Readability would be better preserved if you just went for the garden variety for loop instead.

Two ways:

  1. Define the array as a jagged array, and use nested foreachs.
  2. Define the array normally, and use foreach on the entire thing.

Example of #2:

int[,] arr = { { 1, 2 }, { 3, 4 } };
foreach(int a in arr)
    Console.Write(a);

Output will be 1234. ie. exactly the same as doing i from 0 to n, and j from 0 to n.

Johan Larsson

You can use an extension method like this:

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

And then:

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

It will be a bit slower than using for loops but probably not an issue in most cases. Not sure if it makes things more readable.

Note that c# arrays can be other than zero-based so you can use a for loop like this:

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

Use LINQ .Cast<int>() to convert 2D array to IEnumerable<int>.

LINQPad example:

var arr = new int[,] { 
  { 1, 2, 3 }, 
  { 4, 5, 6 } 
};

IEnumerable<int> values = arr.Cast<int>();
Console.WriteLine(values);

Output:

You can also use enumerators. Every array-type of any dimension supports the Array.GetEnumerator method. The only caveat is that you will have to deal with boxing/unboxing. However, the code you need to write will be quite trivial.

Here's the sample code:

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

As mentioned elsewhere, you can just iterate over the array and it will produce all results in order across all dimensions. However, if you want to know the indices as well, then how about using this - http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx

then doing something like:

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()));
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!