如何从 IEnumerable 创建多维数组
How to create multidimensional array from IEnumerable
是否有一些优雅的方法可以从 IEnumerable 创建多维数组。我知道怎么写这样的函数
double[,] GetMultidimesionalArray(IEnumerable<double> ienumerable, int nRows, int nColumns)
{
var toReturn = new double[nRows,nColumns];
var e = ienumerable.Select((x, i) => new { el = x, id = i });
foreach (var item in e)
toReturn[item.id / nColumns, item.id % nColumns] = item.el;
return toReturn;
}
看起来不太好。一种优雅的方法是:
Buffer.BlockCopy(ienumerable.ToArray(), 0, toReturn, 0, nRows * nColumns * sizeof(double));
但这并不好,因为附加数组 (ienumerable.ToArray()) 是在内存中创建的。
所以,我正在寻找解决它的优雅方法(如第二种方法),但在 time/memory.
方面也很有效
不幸的是,LINQ 不直接处理二维数组,因此如果您坚持使用 double[,]
return 类型,则需要循环。你的方法很好;另一种方法是使用两个嵌套循环来避免使用除法和模数计算索引:
double[,] GetMultidimesionalArray(IEnumerable<double> ienumerable, int nRows, int nColumns) {
var res = new double[nRows,nColumns];
using (var iter = ienumerable.GetEnumerator()) {
for (var r = 0 ; r != nRows ; r++) {
for (var c = 0 ; c != nColumns; c++) {
if (!iter.MoveNext()) {
break;
}
res[r,c] = iter.Current;
}
}
}
return res;
}
当序列中的元素与 nRows × nColumns 的预期大小相比过多或过少时,此方法不会引发异常。此外,其代码结构反映了 return 值的结构(即填充二维数组的两个嵌套循环),这使得代码更易于理解。
是否有一些优雅的方法可以从 IEnumerable 创建多维数组。我知道怎么写这样的函数
double[,] GetMultidimesionalArray(IEnumerable<double> ienumerable, int nRows, int nColumns)
{
var toReturn = new double[nRows,nColumns];
var e = ienumerable.Select((x, i) => new { el = x, id = i });
foreach (var item in e)
toReturn[item.id / nColumns, item.id % nColumns] = item.el;
return toReturn;
}
看起来不太好。一种优雅的方法是:
Buffer.BlockCopy(ienumerable.ToArray(), 0, toReturn, 0, nRows * nColumns * sizeof(double));
但这并不好,因为附加数组 (ienumerable.ToArray()) 是在内存中创建的。
所以,我正在寻找解决它的优雅方法(如第二种方法),但在 time/memory.
方面也很有效不幸的是,LINQ 不直接处理二维数组,因此如果您坚持使用 double[,]
return 类型,则需要循环。你的方法很好;另一种方法是使用两个嵌套循环来避免使用除法和模数计算索引:
double[,] GetMultidimesionalArray(IEnumerable<double> ienumerable, int nRows, int nColumns) {
var res = new double[nRows,nColumns];
using (var iter = ienumerable.GetEnumerator()) {
for (var r = 0 ; r != nRows ; r++) {
for (var c = 0 ; c != nColumns; c++) {
if (!iter.MoveNext()) {
break;
}
res[r,c] = iter.Current;
}
}
}
return res;
}
当序列中的元素与 nRows × nColumns 的预期大小相比过多或过少时,此方法不会引发异常。此外,其代码结构反映了 return 值的结构(即填充二维数组的两个嵌套循环),这使得代码更易于理解。