Итерация многомерного массива с вложенным оператором Foreach - PullRequest
63 голосов
/ 24 мая 2010

Я думаю, что это может быть довольно простой вопрос, но я пока не смог разобраться. Если у меня есть двумерный массив, например, так:

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

Какой лучший способ перебрать каждое измерение массива с помощью вложенного оператора foreach ?

Ответы [ 11 ]

109 голосов
/ 24 мая 2010

Если вы хотите выполнить итерацию по каждому элементу в массиве, как если бы это был плоский массив, вы можете просто сделать:

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]);
    }
}
20 голосов
/ 24 мая 2010

Вот как можно посетить каждый элемент в двумерном массиве. Это то, что вы искали?

for (int i=0;i<array.GetLength(0);i++)
{
    for (int j=0;j<array.GetLength(1);j++)
    {
        int cell = array[i,j];
    }
}
5 голосов
/ 24 мая 2010

С многомерными массивами вы можете использовать один и тот же метод для перебора элементов, например:

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

Ссылки


В Java многомерные массивы являются массивом массивов, поэтому следующиеработы:

    int[][] table = {
            { 1, 2, 3 },
            { 4, 5, 6 },
    };
    for (int[] row : table) {
        for (int el : row) {
            System.out.println(el);
        }
    }
4 голосов
/ 28 июля 2011

Я знаю, что это старый пост, но я нашел его через Google, и после игры с ним, думаю, у меня есть более простое решение. Если я ошибаюсь, пожалуйста, укажите это, потому что я хотел бы знать, но это сработало, по крайней мере, для моих целей (это основано на ответе ICR):

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

Поскольку оба измерения ограничены, любое из них может быть простым числом и, таким образом, избегать вложенного цикла for. Я признаю, что я новичок в C #, поэтому, пожалуйста, если есть причина не делать этого, пожалуйста, скажите мне ...

3 голосов
/ 24 мая 2010

2D-массив в 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.

2 голосов
/ 28 апреля 2016

Вы можете использовать метод расширения следующим образом:

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

Это будет немного медленнее, чем использование циклов for, но, вероятно, не является проблемой в большинстве случаев. Не уверен, что это делает вещи более читабельными.

Обратите внимание, что массивы 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();
}
2 голосов
/ 24 мая 2010

Два способа:

  1. Определите массив как зубчатый массив и используйте вложенные foreachs.
  2. Определите массив как обычно и используйте foreach для всего этого.

Пример # 2:

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

Выход будет 1234. т.е. точно так же, как делает i от 0 до n, а j от 0 до n.

1 голос
/ 26 августа 2016

Используйте LINQ .Cast<int>() для преобразования 2D-массива в IEnumerable<int>.

Пример LINQPad:

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

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

Выход:

Sequence is 1,2,3,4,5,6

0 голосов
/ 13 декабря 2014

Как уже упоминалось в другом месте, вы можете просто перебрать массив, и он будет производить все результаты в порядке по всем измерениям. Однако, если вы хотите узнать и индексы, то как насчет этого - 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()));
}
0 голосов
/ 26 октября 2014
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
...