私は_double[,] Array;
_を持っています。すべての要素のコピーを作成せずに(forを使用して)double[] ColumnArray0 = Array[0,].toArray()
やdouble[] RowArray1 = Array[,1].toArray()
のようなものを取得することは可能ですか?
ありがとう。
配列は、すべてのエントリが連続して格納されるメモリ領域です。メモリ内のデータレイアウトに応じて、これは行または列のいずれかでのみ可能です。
2D配列double[,]
タイプの代わりに、配列double[][]
の配列を使用することをお勧めします。
double[][] Array2d = new double[10][];
Array2d[0] = new double[10];
Array2d[1] = new double[10];
...
and then:
double[] RowArray0 = Array2d[0];
配列へのデータの配置方法によっては、Array2d
を列配列として扱うこともできます。しかし、両方を同時に持つことは不可能です。
こちらもご覧ください: 多次元配列[] [] vs [、]
非常に遅れていますが、私は質問に対する別の答えを提供したいと思います。
質問の最初の重要な部分は、マトリックスの完全な行OR列にアクセスできるようにすることでした。これを行う1つの可能性は、拡張メソッドを使用することです。
public static class MatrixExtensions
{
/// <summary>
/// Returns the row with number 'row' of this matrix as a 1D-Array.
/// </summary>
public static T[] GetRow<T>(this T[,] matrix, int row)
{
var rowLength = matrix.GetLength(1);
var rowVector = new T[rowLength];
for (var i = 0; i < rowLength; i++)
rowVector[i] = matrix[row, i];
return rowVector;
}
/// <summary>
/// Sets the row with number 'row' of this 2D-matrix to the parameter 'rowVector'.
/// </summary>
public static void SetRow<T>(this T[,] matrix, int row, T[] rowVector)
{
var rowLength = matrix.GetLength(1);
for (var i = 0; i < rowLength; i++)
matrix[row, i] = rowVector[i];
}
/// <summary>
/// Returns the column with number 'col' of this matrix as a 1D-Array.
/// </summary>
public static T[] GetCol<T>(this T[,] matrix, int col)
{
var colLength = matrix.GetLength(0);
var colVector = new T[colLength];
for (var i = 0; i < colLength; i++)
colVector[i] = matrix[i, col];
return colVector;
}
/// <summary>
/// Sets the column with number 'col' of this 2D-matrix to the parameter 'colVector'.
/// </summary>
public static void SetCol<T>(this T[,] matrix, int col, T[] colVector)
{
var colLength = matrix.GetLength(0);
for (var i = 0; i < colLength; i++)
matrix[i, col] = colVector[i];
}
}
使用例:
double[,] myMatrix = ... // Initialize with desired size and values.
double[] myRowVector = myMatrix.GetRow(2); // Gets the third row.
double[] myColVector = myMatrix.GetCol(1); // Gets the second column.
myMatrix.SetCol(2, myColVector); // Sets the third column to the second column.
最初に注意することは、これらのジェネリックメソッドを任意の種類の[、]-行列および対応する[]-ベクトルで使用できることです。 T
sをdouble
sに置き換えると、「double」の特定のバージョンが得られると想像してください(OPからの質問に応じて)。
2つ目は、行の取得と設定ではArray.Copy
を使用し、列の取得と設定ではループを使用することです。これは、C#の Row-Major order が原因で、最初の処理は許可されますが、2番目の処理は許可されません。もちろん、コメントアウトされているように、両方ともループで実装できます。
Set-Methodsに正しいディメンションを渡すようにしてください。そうしないと、プログラムがクラッシュします(エラーとディメンションのチェックを簡単に追加できます)。ロジック全体は、double[][]
のようなギザギザの配列にも実装できますが、OPは特に多次元配列を要求しました。
質問の2番目の部分については、行列がdoubleで構成されていて、doubleが値型であるため、値は常にコピーされます。したがって、値をコピーしないという望ましい動作は不可能です。ただし、オブジェクトをT
として使用する場合は、オブジェクトを指す参照のみがコピーされ、オブジェクト自体はコピーされません(したがって、「コピーされた」オブジェクトの変更に注意してください)。
最後に、本当にdouble値をコピーしたくない場合は、行列全体を渡して(参照のみが渡される)、目的の列や行を直接ループすることをお勧めします。