88

これはかなり単純な質問かもしれませんが、まだ理解できていません。次のような 2 次元配列がある場合:

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

ネストされたforeachステートメントを使用して配列の各次元を反復処理する最良の方法は何ですか?

4

12 に答える 12

147

フラット化された配列であるかのように、配列内のすべての項目を反復処理する場合は、次のようにします。

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]);
    }
}
于 2010-05-23T20:41:08.717 に答える
23

2 次元配列の各要素にアクセスする方法を次に示します。これはあなたが探していたものですか?

for (int i=0;i<array.GetLength(0);i++)
{
    for (int j=0;j<array.GetLength(1);j++)
    {
        int cell = array[i,j];
    }
}
于 2010-05-23T20:29:38.200 に答える
8

多次元配列では、同じメソッドを使用して要素を反復処理できます。次に例を示します。

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);
        }
    }
于 2010-05-23T20:27:09.700 に答える
4

私はこれが古い投稿であることを知っていますが、私はそれをグーグルを通して見つけました、そしてそれで遊んだ後、私はより簡単な解決策があると思います。私が間違っている場合は、それを指摘してください。'知りたいのですが、これは少なくとも私の目的には役立ちました(ICRの応答に基づいています):

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

両方の次元が制限されているため、どちらか一方を単純な数値にすることができ、ネストされたforループを回避できます。私はC#を初めて使用することを認めますので、それを行わない理由がある場合は、教えてください...

于 2011-07-28T02:27:03.230 に答える
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代わりにガーデン バラエティー ループを選択した方が読みやすさは維持されます。

于 2010-05-23T20:30:56.860 に答える
2

ふたつのやり方:

  1. 配列をジャグ配列として定義し、ネストされた foreach を使用します。
  2. 通常どおり配列を定義し、全体で foreach を使用します。

#2 の例:

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

出力は 1234 になります。i を 0 から n に、j を 0 から n にするのとまったく同じです。

于 2010-05-23T20:35:07.687 に答える
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 ループを使用するよりも少し遅くなりますが、ほとんどの場合問題にはなりません。読みやすくなるかどうかはわかりません。

次のように for ループを使用できるように、C# 配列はゼロベース以外の場合があることに注意してください。

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();
}
于 2016-04-28T06:53:19.370 に答える
2

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 です

于 2016-08-26T12:11:12.803 に答える
1

列挙子を使用することもできます。任意の次元のすべての配列型は、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();
    }
}
于 2011-05-22T20:03:36.553 に答える
1

他の場所で述べたように、配列を反復処理するだけで、すべての次元にわたってすべての結果が順番に生成されます。ただし、インデックスも知りたい場合は、これを使用してみてください - 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()));
}
于 2014-12-13T05:01:07.260 に答える
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
于 2014-10-26T12:36:35.907 に答える