我认为这可能是一个非常简单的问题,但我还没有弄清楚。如果我有一个像这样的二维数组:
int[,] array = new int[2,3] { {1, 2, 3}, {4, 5, 6} };
使用嵌套的foreach语句遍历数组的每个维度的最佳方法是什么?
我认为这可能是一个非常简单的问题,但我还没有弄清楚。如果我有一个像这样的二维数组:
int[,] array = new int[2,3] { {1, 2, 3}, {4, 5, 6} };
使用嵌套的foreach语句遍历数组的每个维度的最佳方法是什么?
如果你想迭代数组中的每个项目,就好像它是一个扁平数组一样,你可以这样做:
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]);
}
}
下面介绍如何访问二维数组中的每个元素。这是你要找的吗?
for (int i=0;i<array.GetLength(0);i++)
{
for (int j=0;j<array.GetLength(1);j++)
{
int cell = array[i,j];
}
}
对于多维数组,您可以使用相同的方法来遍历元素,例如:
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);
}
}
我知道这是一篇旧帖子,但我通过谷歌找到了它,在玩过它之后,我认为我有一个更简单的解决方案。如果我错了,请指出,'因为我想知道,但这至少对我的目的有用(它基于 ICR 的回复):
for (int x = 0; x < array.GetLength(0); x++)
{
Console.Write(array[x, 0], array[x,1], array[x,2]);
}
由于两个维度都是有限的,因此任何一个都可以是简单的数字,从而避免嵌套的 for 循环。我承认我是 C# 的新手,所以请,如果有理由不这样做,请告诉我......
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 的例子:
int[,] arr = { { 1, 2 }, { 3, 4 } }; foreach(int a in arr) Console.Write(a);
输出将是 1234。即。与 i 从 0 到 n 和 j 从 0 到 n 完全相同。
您可以使用这样的扩展方法:
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();
}
您也可以使用枚举器。任何维度的每个数组类型都支持 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();
}
}
如其他地方所述,您只需遍历数组,它将在所有维度上按顺序生成所有结果。但是,如果您也想知道索引,那么如何使用它 - https://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/
然后做类似的事情:
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()));
}
我正在寻找一种解决方案来在编译时枚举一个未知数组,并可以访问每个元素索引集。我看到了有收益的解决方案,但这是另一个没有收益的实现。它采用老式的简约方式。在此示例中 AppendArrayDebug() 只是将所有元素打印到 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;
}
}
例如,以下数组将产生以下输出:
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
*/
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