如何从2D数组中获取1D列数组和1D行数组? (C#.NET)

时间:2022-11-01 01:37:50

i have double[,] Array;. Is it possible to get something like double[] ColumnArray0 = Array[0,].toArray() and double[] RowArray1 = Array[,1].toArray() without making a copy of every elemet(using for)?

我有双[,]数组;。是否有可能得到像double [] ColumnArray0 = Array [0,]。toArray()和double [] RowArray1 = Array [,1] .toArray()而不制作每个elemet的副本(使用for)?

Thanks.

谢谢。

2 个解决方案

#1


1  

Arrays are a memory area where all entries are stored in a consecutive way. Depending on the data layout in memory this is only possible for either rows or columns.

数组是一个存储区,所有条目都以连续的方式存储。根据内存中的数据布局,这仅适用于行或列。

Instead of the 2d array double[,] type it is in your case better to use an array of arrays double[][]

而不是2d数组double [,]类型在你的情况下更好地使用数组double [] []

double[][] Array2d = new double[10][];
Array2d[0] = new double[10];
Array2d[1] = new double[10];
...

and then:
double[] RowArray0 = Array2d[0];

Depending on how you put the data in your array, you can also treat the Array2d as a column array. But to have both at the same time is not possible.

根据您将数据放入数组的方式,您还可以将Array2d视为列数组。但同时拥有两者是不可能的。

Also have a look here: Multidimensional Array [][] vs [,]

另外看看这里:多维数组[] [] vs [,]

#2


5  

Although being very late, I want to provide an alternative answer to the question.

虽然很晚,但我想提出另一个问题的答案。

The first important part of the question was to be able to access complete rows OR columns of the matrix. One possibility of doing this is by using extension methods:

问题的第一个重要部分是能够访问矩阵的完整行或列。这样做的一种可能性是使用扩展方法:

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];
  }
}

Usage example:

用法示例:

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.

First thing to note is that you can use these generic methods with any kind of [,]-matrices and corresponding []-vectors. Imagine replacing the Ts with doubles, and you would get the specific version for 'double' (as was asked by the OP).

首先要注意的是,您可以将这些通用方法与任何类型的[,] - 矩阵和相应的[] - 向量一起使用。想象一下用双打替换Ts,你会得到'双'的特定版本(正如OP所要求的那样)。

Second thing is, that getting and setting the rows uses Array.Copy, while getting and setting the columns uses a loop. This is due to the Row-Major order of C#, which allows the first, but not the second. Of course both can be implemented with a loop, as seen commented out.

第二件事是,获取和设置行使用Array.Copy,而获取和设置列使用循环。这是由于C#的Row-Major顺序,它允许第一个,但不允许第二个。当然,两者都可以用循环实现,如上所述。

Make sure to pass correct dimensions for the set-Methods, or the program will crash (error and dimension checking can be added easily). The whole logic could as well be implemented for jagged arrays like double[][], however, the OP specificially asked for multidimensional ones.

确保为set-Methods传递正确的尺寸,否则程序将崩溃(可以轻松添加错误和尺寸检查)。整个逻辑也可以实现为像[double [] []这样的锯齿状数组,但OP特别要求多维数组。

As for the second part of the question: If your matrix consists of double, and since double is a value type, the values will always be copied. So your desired behaviour of not copying the values would not be possible. However, if using objects as T, only the reference pointing to the object will be copied, and not the object itself (so beware of mutating the 'copied' object).

至于问题的第二部分:如果矩阵由double组成,并且double是值类型,则将始终复制值。因此,您无法复制值的所需行为。但是,如果将对象用作T,则只会复制指向对象的引用,而不会复制对象本身(因此要注意改变'复制'对象)。

Lastly, if you really don't want to copy the double-values, I'd suggest passing your whole matrix (only the reference is passed), and then directly looping through the desired columns and/or rows.

最后,如果你真的不想复制双值,我建议传递整个矩阵(只传递引用),然后直接循环遍历所需的列和/或行。

#1


1  

Arrays are a memory area where all entries are stored in a consecutive way. Depending on the data layout in memory this is only possible for either rows or columns.

数组是一个存储区,所有条目都以连续的方式存储。根据内存中的数据布局,这仅适用于行或列。

Instead of the 2d array double[,] type it is in your case better to use an array of arrays double[][]

而不是2d数组double [,]类型在你的情况下更好地使用数组double [] []

double[][] Array2d = new double[10][];
Array2d[0] = new double[10];
Array2d[1] = new double[10];
...

and then:
double[] RowArray0 = Array2d[0];

Depending on how you put the data in your array, you can also treat the Array2d as a column array. But to have both at the same time is not possible.

根据您将数据放入数组的方式,您还可以将Array2d视为列数组。但同时拥有两者是不可能的。

Also have a look here: Multidimensional Array [][] vs [,]

另外看看这里:多维数组[] [] vs [,]

#2


5  

Although being very late, I want to provide an alternative answer to the question.

虽然很晚,但我想提出另一个问题的答案。

The first important part of the question was to be able to access complete rows OR columns of the matrix. One possibility of doing this is by using extension methods:

问题的第一个重要部分是能够访问矩阵的完整行或列。这样做的一种可能性是使用扩展方法:

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];
  }
}

Usage example:

用法示例:

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.

First thing to note is that you can use these generic methods with any kind of [,]-matrices and corresponding []-vectors. Imagine replacing the Ts with doubles, and you would get the specific version for 'double' (as was asked by the OP).

首先要注意的是,您可以将这些通用方法与任何类型的[,] - 矩阵和相应的[] - 向量一起使用。想象一下用双打替换Ts,你会得到'双'的特定版本(正如OP所要求的那样)。

Second thing is, that getting and setting the rows uses Array.Copy, while getting and setting the columns uses a loop. This is due to the Row-Major order of C#, which allows the first, but not the second. Of course both can be implemented with a loop, as seen commented out.

第二件事是,获取和设置行使用Array.Copy,而获取和设置列使用循环。这是由于C#的Row-Major顺序,它允许第一个,但不允许第二个。当然,两者都可以用循环实现,如上所述。

Make sure to pass correct dimensions for the set-Methods, or the program will crash (error and dimension checking can be added easily). The whole logic could as well be implemented for jagged arrays like double[][], however, the OP specificially asked for multidimensional ones.

确保为set-Methods传递正确的尺寸,否则程序将崩溃(可以轻松添加错误和尺寸检查)。整个逻辑也可以实现为像[double [] []这样的锯齿状数组,但OP特别要求多维数组。

As for the second part of the question: If your matrix consists of double, and since double is a value type, the values will always be copied. So your desired behaviour of not copying the values would not be possible. However, if using objects as T, only the reference pointing to the object will be copied, and not the object itself (so beware of mutating the 'copied' object).

至于问题的第二部分:如果矩阵由double组成,并且double是值类型,则将始终复制值。因此,您无法复制值的所需行为。但是,如果将对象用作T,则只会复制指向对象的引用,而不会复制对象本身(因此要注意改变'复制'对象)。

Lastly, if you really don't want to copy the double-values, I'd suggest passing your whole matrix (only the reference is passed), and then directly looping through the desired columns and/or rows.

最后,如果你真的不想复制双值,我建议传递整个矩阵(只传递引用),然后直接循环遍历所需的列和/或行。