Итерационный многомерный массив с вложенным выражением Foreach
Я думаю, что это может быть довольно простой вопрос, но я еще не смог понять это. Если у меня есть 2-мерный массив, например:
int[,] array = new int[2,3] { {1, 2, 3}, {4, 5, 6} };
Какой лучший способ выполнить итерацию каждого измерения массива с помощью вложенного выражения foreach?
Ответы
Ответ 1
Если вы хотите перебирать все элементы массива, как если бы это был сплющенный массив, вы можете просто сделать:
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]);
}
}
Ответ 2
Здесь, как посетить каждый элемент в двумерном массиве. Это то, что вы искали?
for (int i=0;i<array.GetLength(0);i++)
{
for (int j=0;j<array.GetLength(1);j++)
{
int cell = array[i,j];
}
}
Ответ 3
С многомерными массивами вы можете использовать один и тот же метод для итерации по элементам, например:
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
Я знаю, что это старый пост, но я нашел его через Google, и после игры с ним думаю, что у меня есть более легкое решение. Если я ошибаюсь, укажите это, потому что я хотел бы знать, но это сработало для моих целей как минимум (оно основано на ответе ICR):
for (int x = 0; x < array.GetLength(0); x++)
{
Console.Write(array[x, 0], array[x,1], array[x,2]);
}
Поскольку оба измерения ограничены, либо одно может быть простым числом, и, таким образом, избегать вложенных циклов. Я признаю, что я новичок в С#, поэтому, пожалуйста, если есть причина не делать этого, пожалуйста, скажите мне...
Ответ 5
2D-массив в С# не подходит для вложенного 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]);
Но вы все равно будете использовать я и j в качестве значений индекса для массива. Удобство чтения было бы лучше сохранено, если бы вы просто отправились на садовую пару for
.
Ответ 6
Два способа:
- Определите массив как зубчатый массив и используйте вложенные foreachs.
- Определите массив обычно и используйте foreach для всего объекта.
Пример # 2:
int[,] arr = { { 1, 2 }, { 3, 4 } };
foreach(int a in arr)
Console.Write(a);
Выход будет 1234. Т.е. точно так же, как делать я от 0 до n и j от 0 до n.
Ответ 7
Вы можете использовать метод расширения следующим образом:
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 следующим образом:
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();
}
Ответ 8
Используйте 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);
Вывод:
![Последовательность - 1,2,3,4,5,6]()
Ответ 9
Вы также можете использовать счетчики. Каждый тип массива любого измерения поддерживает метод 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();
}
}
Ответ 10
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
Ответ 11
Как уже упоминалось в другом месте, вы можете просто перебирать массив, и он будет производить все результаты по порядку во всех измерениях. Однако, если вы хотите знать и индексы, то как об использовании этого - 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()));
}