是否有一些优雅的方法可以从IEnumerable创建多维数组。我知道怎么写这样的函数
program holler
use ISO_FORTRAN_ENV
integer(INT32) ID
! holler.txt should exist in the current directory
! and contain at least 4 characters
open(10,file='holler.txt',status='old')
read(10,'(A4)') ID
! write(*,'(*(g0))') 'ID == 4HEOT = ',ID == 4HEOT ! Fails
! write(*,'(*(g0))') 'ID == 4HEOT = ',ID == int(4HEOT ,KIND(ID)) ! Fails
write(*,'(*(g0))') 'ID == 4HEOT = ',ID == transfer(4HEOT ,ID) ! Success
BLOCK
integer(kind(ID)) compare
compare = 4HEOT ! Note trailing space
write(*,'(*(g0))') 'ID == 4HEOT = ',ID == compare ! Success
END BLOCK
end program holler
看起来不太好。做到这一点的一种优雅方法是:
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;
}
但这不是很好,因为在内存中创建了附加数组(ienumerable.ToArray())。
因此,我正在寻找一种解决问题的优雅方法(就像第二种方法一样),而且在时间/内存方面也很有效。
答案 0 :(得分:1)
不幸的是,LINQ不能直接处理2D数组,因此如果您坚持使用double[,]
返回类型,则需要循环。您的方法很好;一种替代方法是使用两个嵌套循环来避免使用除法和取模来计算索引:
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的预期大小相比,序列中元素太多或太少时,此方法不会引发异常。此外,其代码结构反映了返回值的结构(即,两个嵌套循环填充2D数组),这使代码更易于理解。