![](/img/trans.png)
[英]How to convert a matrix in matlab to a double[,] array in C#/.NET?
[英]How to convert a double [][] (jagged array) to a double[,] (matrix) in C#
以下代码用于将“锯齿状数组”(即double [] [])转换为矩阵double [,]。
static T[,] To2D<T>(T[][] source)
{
try
{
int FirstDim = source.Length;
int SecondDim = source.GroupBy(row => row.Length).Single().Key; // throws InvalidOperationException if source is not rectangular
var result = new T[FirstDim, SecondDim];
for (int i = 0; i < FirstDim; ++i)
for (int j = 0; j < SecondDim; ++j)
result[i, j] = source[i][j];
return result;
}
catch (InvalidOperationException)
{
throw new InvalidOperationException("The given jagged array is not rectangular.");
}
}
我想知道如何进行逆运算,即从double [,]转换为double [] []。
第一步,您只能创建第一级数组。 然后,您需要一个一个地创建第二级数组:
var result = new T[FirstDim][];
for (int i = 0; i < FirstDim; i++) {
var a = new T[SecondDim];
result[i] = a;
for (int j = 0; j < SecondDim; j++) {
a[j] = source[i,j];
}
}
即使所得的锯齿状数组为矩形,此过程也没有捷径,因为理论上每一行都可以指向不同长度的数组(甚至为null
)。 这就是为什么它被称为锯齿状数组的原因。
请注意,使用new T[size][]
创建数组时,每个result[i]
都会初始化为null
。
Se还: 锯齿状数组(C#编程指南)
这是优化的扩展:
static class extensions
{
public static T[][] toJagged<T>(this T[,] source)
{
int rows = source.GetLength(0);
int columns = source.GetLength(1);
int size = System.Runtime.InteropServices.Marshal.SizeOf<T>();
var result = new T[rows][];
for (int r = 0; r < rows; r++)
{
var temp = new T[columns];
Buffer.BlockCopy(source, r * columns * size, temp, 0, columns * size);
result[r] = temp;
}
return result;
}
public static T[,] to2D<T>(this T[][] source)
{
int rows = source.Length;
int columns = source.Select(i => i == null ? 0 : i.Length).Max(); // the longest row
var result = new T[rows, columns];
int size = System.Runtime.InteropServices.Marshal.SizeOf<T>();
int offset = 0;
foreach(var row in source)
{
if (row != null)
Buffer.BlockCopy(row, 0, result, offset * size, row.Length * size);
offset += columns;
}
return result;
}
} // end of class extensions
样品使用和测试:
double[,] d2 = { { 1, 2, 3 }, { 4, 5, 6 } };
double[][] dj = d2.toJagged();
Debug.Print(string.Join(", ", dj.SelectMany(i => i))); // 1, 2, 3, 4, 5, 6
int[][] ij = { new[] { 1, 2 }, new[] { 3, 4, 5 }, new[] { 6, 7, 8, 9 } };
int[,] i2 = ij.to2D();
Debug.Print(string.Join(", ", i2.Cast<int>())); // 1, 2, 0, 0, 3, 4, 5, 0, 6, 7, 8, 9
这些工作无需使用pinvoke:
static T[][] ToJag<T>(T[,] source)
{
try
{
int FirstDim = source.GetLength(0); // rows
int SecondDim = source.GetLength(1); // cols
var result = new T[FirstDim][]; // only acceptable syntax ???
for (int i = 0; i < FirstDim; ++i)
{
result[i] = new T[source.GetLength(1)]; // just for columns
for (int j = 0; j < SecondDim; ++j)
{
result[i][j] = source[i, j];
}
}
return result;
}
catch (InvalidOperationException)
{
throw new InvalidOperationException("Invalid operation error.");
}
}
static T[,] To2D<T>(T[][] source)
{
try
{
int FirstDim = source.Length;
int SecondDim = source.GroupBy(row => row.Length).Single().Key; // throws InvalidOperationException if source is not rectangular
var result = new T[FirstDim, SecondDim];
for (int i = 0; i < FirstDim; ++i)
for (int j = 0; j < SecondDim; ++j)
result[i, j] = source[i][j];
return result;
}
catch (InvalidOperationException)
{
throw new InvalidOperationException("The given jagged array is not rectangular.");
}
}
注意:需要使用System.Linq才能使T [,] To2D(T [] []源)正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.