Creo que esta puede ser una pregunta bastante simple, pero aún no he podido resolverla. Si tengo una matriz bidimensional como esta:
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 foreach anidada ?
c#
foreach
nested-loops
Tyler Murry
fuente
fuente
Respuestas:
Si desea iterar sobre cada elemento de la matriz como si fuera una matriz plana, puede hacer lo siguiente:
foreach (int i in array) { Console.Write(i); }
que imprimiría
Si desea poder conocer los índices xey también, deberá 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, puede usar una matriz irregular 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]); } }
fuente
A continuación, se explica cómo visitar cada elemento en una matriz bidimensional. 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]; } }
fuente
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); } }
fuente
int[,]
es una matriz de 2 dimensiones yint[][]
es una matriz dentada de matrices y no se requiere que cada matriz dada tenga la misma longitud. Puede hacer fácilmente un foreach en la matriz dentada, pero una matriz 2D no es el mismo tipo de estructura. En cualquier caso, su segundo fragmento no se ajusta a este problema, el primer fragmento no está anidado.Sé que esta es una publicación antigua, pero la encontré a través de Google, y después de jugar con ella creo que tengo una solución más fácil. Si me equivoco, indíquelo, porque me gustaría saberlo, pero esto funcionó al menos para mis propósitos (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 ambas dimensiones son limitadas, cualquiera de las dos puede ser números simples y, por lo tanto, evitar un bucle for anidado. Admito que soy nuevo en C #, así que por favor, si hay alguna razón para no hacerlo, dígame ...
fuente
La matriz 2D en C # no se presta bien a un foreach anidado, no es el equivalente a una matriz dentada (una matriz de matrices). Podrías hacer algo como esto para usar 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 aún usaría i y j como valores de índice para la matriz. La legibilidad se conservaría mejor si simplemente optara por el
for
bucle de variedad de jardín .fuente
[]
. Es idiomático Python iterar sobre los valores directamente. También tenga en cuenta que no hay matrices o listas multidimensionales en Python (solo irregulares).Dos caminos:
Ejemplo de # 2:
La salida será 1234. es decir. exactamente lo mismo que hacer i de 0 an, y j de 0 an.
fuente
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 entonces:
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 sea un problema en la mayoría de los casos. No estoy seguro si hace las cosas más legibles.
Tenga en cuenta que las matrices de c # pueden ser distintas a las basadas 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(); }
fuente
Como se mencionó en otra parte, puede iterar sobre la matriz y producirá todos los resultados en orden en todas las dimensiones. Sin embargo, si también desea conocer los índices, ¿qué tal si usa esto? Http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with- linq.aspx
luego haciendo 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())); }
fuente
Utilice LINQ
.Cast<int>()
para convertir una matriz 2D aIEnumerable<int>
.Ejemplo de LINQPad:
var arr = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } }; IEnumerable<int> values = arr.Cast<int>(); Console.WriteLine(values);
Salida:
fuente
También puede utilizar enumeradores. Cada tipo de matriz de cualquier dimensión admite el método Array.GetEnumerator. La única advertencia es que tendrás que lidiar con el boxeo / unboxing. Sin embargo, el código que necesita escribir será bastante trivial.
Aquí está el código de muestra:
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(); } }
fuente
Using foreach is recommended, instead of directly manipulating the enumerator.
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
fuente
Estaba buscando una solución para enumerar una matriz de un rango desconocido en el tiempo de compilación con acceso a cada conjunto de índices de elementos. Vi soluciones con rendimiento, pero aquí hay otra implementación sin rendimiento. Es al estilo minimalista de la vieja escuela. En este ejemplo AppendArrayDebug () simplemente imprime todos los elementos en el búfer StringBuilder.
public static void AppendArrayDebug ( StringBuilder sb, Array array ) { if( array == null || array.Length == 0 ) { sb.Append( "<nothing>" ); return; } int i; var rank = array.Rank; var lastIndex = rank - 1; // Initialize indices and their boundaries var indices = new int[rank]; var lower = new int[rank]; var upper = new int[rank]; for( i = 0; i < rank; ++i ) { indices[i] = lower[i] = array.GetLowerBound( i ); upper[i] = array.GetUpperBound( i ); } while( true ) { BeginMainLoop: // Begin work with an element var element = array.GetValue( indices ); sb.AppendLine(); sb.Append( '[' ); for( i = 0; i < rank; ++i ) { sb.Append( indices[i] ); sb.Append( ' ' ); } sb.Length -= 1; sb.Append( "] = " ); sb.Append( element ); // End work with the element // Increment index set // All indices except the first one are enumerated several times for( i = lastIndex; i > 0; ) { if( ++indices[i] <= upper[i] ) goto BeginMainLoop; indices[i] = lower[i]; --i; } // Special case for the first index, it must be enumerated only once if( ++indices[0] > upper[0] ) break; } }
Por ejemplo, la siguiente matriz producirá la siguiente salida:
var array = new [,,] { { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } }, { { 13, 14, 15 }, { 16, 17, 18 }, { 19, 20, 21 }, { 22, 23, 24 } } }; /* Output: [0 0 0] = 1 [0 0 1] = 2 [0 0 2] = 3 [0 1 0] = 4 [0 1 1] = 5 [0 1 2] = 6 [0 2 0] = 7 [0 2 1] = 8 [0 2 2] = 9 [0 3 0] = 10 [0 3 1] = 11 [0 3 2] = 12 [1 0 0] = 13 [1 0 1] = 14 [1 0 2] = 15 [1 1 0] = 16 [1 1 1] = 17 [1 1 2] = 18 [1 2 0] = 19 [1 2 1] = 20 [1 2 2] = 21 [1 3 0] = 22 [1 3 1] = 23 [1 3 2] = 24 */
fuente