如何从 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 值的结构(即填充二维数组的两个嵌套循环),这使得代码更易于理解。