使用嵌套的Foreach语句迭代多维数组

问题描述 投票:63回答:11

我认为这可能是一个非常简单的问题,但我还没有弄清楚。如果我有一个像这样的二维数组:

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

使用嵌套的foreach语句迭代数组的每个维度的最佳方法是什么?

c# foreach nested-loops
11个回答
109
投票

如果要迭代数组中的每个项目,就好像它是一个扁平数组,您可以这样做:

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

0
投票
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
投票

如其他地方所述,您可以迭代数组,它将按顺序生成所有维度的所有结果。但是,如果你想知道指数,那么如何使用它 - 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()));
}

20
投票

以下是如何访问二维数组中的每个元素。这是你在找什么?

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

5
投票

使用多维数组,您可以使用相同的方法迭代元素,例如:

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

References


在Java中,多维数组是数组数组,因此以下工作原理:

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

4
投票

我知道这是一篇很老的帖子,但是我通过谷歌发现了这个帖子,玩完之后认为我有一个更简单的解决方案。如果我错了,请指出,“因为我想知道,但这至少对我的目的有用(这是基于ICR的回应):

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

由于两个维度都是有限的,因此任何一个都可以是简单的数字,从而避免嵌套的for循环。我承认我是C#的新手,所以,如果有理由不这样做,请告诉我......


3
投票

C#中的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]);

但是你仍然会使用i和j作为数组的索引值。如果您只是去花园品种for循环,那么可读性将得到更好的保留。


2
投票

两种方式:

  1. 将数组定义为锯齿状数组,并使用嵌套的foreach。
  2. 正常定义数组,并在整个事物上使用foreach。

#2的示例:

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

输出将是1234.即。与从0到n的j和从0到n的j完全相同。


2
投票

你可以使用这样的扩展方法:

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

1
投票

使用LINQ .Cast<int>()将2D数组转换为IEnumerable<int>

LinkPad示例:

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
投票

您也可以使用枚举器。任何维度的每个数组类型都支持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();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.