これは非常に単純な質問かもしれませんが、私はまだそれを理解できていません。次のような2次元配列がある場合:
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]);
}
}
2次元配列の各要素にアクセスする方法は次のとおりです。これはあなたが探していたものですか?
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);
}
}
これは古い投稿であることは知っていますが、Googleで見つけたので、遊んだ後は簡単な解決策があると思います。私が間違っている場合、「知りたいので、それを指摘してください、しかしこれは少なくとも私の目的のために働いた(それはICRの応答に基づいている):
for (int x = 0; x < array.GetLength(0); x++)
{
Console.Write(array[x, 0], array[x,1], array[x,2]);
}
両方の次元が制限されているため、どちらか一方が単純な数値になり、ネストされたforループを回避できます。私はC#を初めて使用することを認めていますので、それをしない理由があれば教えてください...
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の例:
int[,] arr = { { 1, 2 }, { 3, 4 } }; foreach(int a in arr) Console.Write(a);
出力は1234になります。 0〜nのi、0〜nのjを実行するのとまったく同じです。
次のような拡張メソッドを使用できます。
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();
}
}
別の場所で述べたように、配列を反復処理するだけで、すべてのディメンションにわたってすべての結果が順番に生成されます。ただし、インデックスも知りたい場合は、これを使用してみてください- 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()));
}
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