Iterar Matriz Multidimensional con la Instrucción Foreach Anidada


Creo que esta podría ser una pregunta bastante simple, pero aún no he sido capaz de entenderla. Si tengo una matriz de 2 dimensiones como así:

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

¿Cuál es la mejor manera de iterar a través de cada dimensión de la matriz con una instrucción anidada foreach?

Author: phil13131, 2010-05-24

11 answers

Si desea iterar sobre cada elemento de la matriz como si fuera una matriz aplanada, simplemente puede hacer:

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

Que imprimiría

123456

Si quieres conocer también los índices x e y, tendrás que hacer lo siguiente:

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

Alternativamente, podría usar una matriz dentada en su lugar (una matriz de matrices):

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

O

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]);
    }
}
 99
Author: ICR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-23 20:41:08

Aquí es cómo visitar cada elemento en una matriz de 2 dimensiones. ¿Esto es lo que estabas buscando?

for (int i=0;i<array.GetLength(0);i++)
{
    for (int j=0;j<array.GetLength(1);j++)
    {
        int cell = array[i,j];
    }
}
 18
Author: Daniel Plaisted,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-23 20:29:38

Con matrices multidimensionales, puede usar el mismo método para iterar a través de los elementos, por ejemplo:

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

La salida de este ejemplo es:

9 99 3 33 5 55

Referencias


En Java, las matrices multidimensionales son matrices de matrices, por lo que funciona lo siguiente:

    int[][] table = {
            { 1, 2, 3 },
            { 4, 5, 6 },
    };
    for (int[] row : table) {
        for (int el : row) {
            System.out.println(el);
        }
    }
 4
Author: polygenelubricants,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-23 20:34:46

Sé que este es un post antiguo, pero lo encontré a través de Google, y después de jugar con él creo que tengo una solución más fácil. Si me equivoco por favor señalarlo, ' porque me gustaría saber, pero esto funcionó para mis propósitos al menos (Se basa en la respuesta de ICR):

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

Dado que las dos dimensiones son limitadas, cualquiera de ellas puede ser números simples, y así evitar un bucle for anidado. Admito que soy nuevo en C#, así que por favor, si hay una razón para no hacerlo, por favor dime...

 4
Author: Keven M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-28 02:27:03

La matriz 2D en C# no se presta bien a un foreach anidado, no es el equivalente de una matriz dentada (una matriz de matrices). Usted podría hacer algo como esto para utilizar un 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]);

Pero todavía usaría i y j como valores de índice para la matriz. La legibilidad se conservaría mejor si simplemente optara por el bucle garden variety for en su lugar.

 3
Author: Anthony Pegram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-23 20:30:56

De dos maneras:

  1. Defina el array como un array dentado, y use foreachs anidados.
  2. Defina la matriz normalmente, y use foreach en toda la cosa.

Ejemplo de #2:

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

La salida será 1234. IE. exactamente lo mismo que hacer i de 0 a n, y j de 0 a n.

 2
Author: Rubys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-23 20:35:07

Puedes usar un método de extensión como este:

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

Y luego:

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

Será un poco más lento que usar bucles for, pero probablemente no será un problema en la mayoría de los casos. No estoy seguro de si hace las cosas más legibles.

Tenga en cuenta que los arrays de c# pueden ser distintos de los basados en cero, por lo que puede usar un bucle for como este:

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
Author: Johan Larsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-28 06:53:19

Use LINQ .Cast<int>() para convertir matriz 2D a IEnumerable<int>.

Ejemplo de LINQPad:

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

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

Salida:

La secuencia es 1,2,3,4,5,6

 1
Author: angularsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-26 12:11:12

También puede usar enumeradores. Cada matriz-tipo de cualquier dimensión soporta la matriz.Método GetEnumerator. La única advertencia es que usted tendrá que lidiar con el boxeo / unboxing. Sin embargo, el código que necesita escribir será bastante trivial.

Aquí está el código de ejemplo:

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();
    }
}
 0
Author: code4life,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-22 20:03:36
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
 0
Author: Sohel Ahmed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-26 12:36:35

Como se mencionó en otra parte, solo puede iterar sobre la matriz y producirá todos los resultados en orden en todas las dimensiones. Sin embargo, si desea conocer los índices también, entonces ¿qué tal usar esto?http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx

Luego hacer algo como:

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
Author: Daniel Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-17 14:40:38