次のオブジェクトがあります
int [,] oGridCells;
これは、固定の最初のインデックスでのみ使用されます
int iIndex = 5;
for (int iLoop = 0; iLoop < iUpperBound; iLoop++)
{
//Get the value from the 2D array
iValue = oGridCells[iIndex, iLoop];
//Do something with iValue
}
.NETに、固定の最初のインデックスの値を(値をループする以外に)単一の次元配列に変換する方法はありますか?
配列が1回だけループされている場合、コードが高速化されるとは思えません(また、速度が低下する可能性もあります)。ただし、配列が頻繁に操作されている場合は、多次元配列よりも単一次元配列の方が効率的です。
質問をする主な理由は、本番コードに使用するのではなく、実行できるかどうか、どのように実行できるかを確認することです。
次のコードは、16バイト(4 int)を2次元配列から1次元配列にコピーする方法を示しています。
int[,] oGridCells = {{1, 2}, {3, 4}};
int[] oResult = new int[4];
System.Buffer.BlockCopy(oGridCells, 0, oResult, 0, 16);
正しいバイトオフセットを指定することにより、配列から1行だけを選択的にコピーすることもできます。この例では、3行の2次元配列の中央の行をコピーします。
int[,] oGridCells = {{1, 2}, {3, 4}, {5, 6}};
int[] oResult = new int[2];
System.Buffer.BlockCopy(oGridCells, 8, oResult, 0, 8);
編集:
方法があることに気づきました!確かに、それはおそらくそれだけの価値はありません。 安全でないコード を使用します。完全な例、両方の方法を示していますが、以下は安全ではありません。
public class MultiSingleUnsafe
{
public static unsafe void Main(String[] a)
{
int rowCount = 6;
int iUpperBound = 10;
int [,] oGridCells = new int[rowCount, iUpperBound];
int iIndex = rowCount - 2; // Pick a row.
for(int i = 0; i < iUpperBound; i++)
{
oGridCells[iIndex, i] = i;
}
for (int iLoop = 0; iLoop < iUpperBound; iLoop++)
{
//Get the value from the 2D array
int iValue = oGridCells[iIndex, iLoop];
Console.WriteLine("Multi-dim array access iValue: " + iValue);
//Do something with iValue
}
fixed(int *lastRow = &(oGridCells[iIndex,0]))
{
for (int iLoop = 0; iLoop < iUpperBound; iLoop++)
{
int iValue = lastRow[iLoop];
Console.WriteLine("Pointer access iValue: " + iValue);
}
}
}
}
C#で多次元配列を一次元配列にキャストする方法はありません。もちろん、新しい1次元配列を作成してそこにコピーすることもできます。ただし、値を複数回ループしても、パフォーマンスが向上するとは思いません。ダレンが言ったように、内部的にはとにかくそれはすべてポインタ演算です。確実にしたい場合は、プロファイルを作成します。
あなたはこれを試すことができます:
int[,] twoD = new int[2,2];
twoD[0, 0] = 1;
twoD[0, 1] = 2;
twoD[1, 0] = 3;
twoD[1, 1] = 4;
int[] result = twoD.Cast<int>().Select(c => c).ToArray();
結果は、データを含む整数配列になります。
1, 2, 3, 4
各配列への参照を取得することはできません。ただし、 ギザギザの配列 を使用することはできます。
「しかし、配列が頻繁に操作されている場合は、多次元配列よりも単一次元配列の方が効率的です。」
去年の夏に正確にプロファイリングを行いましたが、2Dアレイと1Dアレイのパフォーマンスに大きな違いがないことに驚きました。
ギザギザの配列のパフォーマンスはテストしていません。
可能であれば驚かれることでしょう。oGridCells[iIndex, iLoop]
はoGridCells[iIndex * iLoop]
の一種の省略形(内部的にはMSIL)であり、多次元配列はこのための構文糖衣です。
質問に答えるには:いいえ。値をループする必要があります。