如何将数组列表转换为多维数组

我需要将以下集合转换为double [,]:

var ret = new List(); 

列表中的所有数组都具有相同的长度。 最简单的方法ret.ToArray()产生double [] [],这不是我想要的。 当然,我可以手动创建一个新数组,并在循环中复制数字,但是有更优雅的方式吗?

编辑:我的库是从另一种语言Mathematica调用的,该语言尚未在.Net中开发。 我不认为该语言可以利用锯齿状数组。 我必须返回一个多维数组。

我不相信框架内置了任何内容来实现这一点 – 即使在这种情况下Array.Copy失败了。 但是,通过循环编写代码很容易:

 using System; using System.Collections.Generic; class Test { static void Main() { List list = new List { new[] { 1, 2, 3 }, new[] { 4, 5, 6 }, }; int[,] array = CreateRectangularArray(list); foreach (int x in array) { Console.WriteLine(x); // 1, 2, 3, 4, 5, 6 } Console.WriteLine(array[1, 2]); // 6 } static T[,] CreateRectangularArray(IList arrays) { // TODO: Validation and special-casing for arrays.Count == 0 int minorLength = arrays[0].Length; T[,] ret = new T[arrays.Count, minorLength]; for (int i = 0; i < arrays.Count; i++) { var array = arrays[i]; if (array.Length != minorLength) { throw new ArgumentException ("All arrays must be the same length"); } for (int j = 0; j < minorLength; j++) { ret[i, j] = array[j]; } } return ret; } } 

您可以执行以下扩展名:

  ///  /// Conerts source to 2D array. ///  ///  /// The type of item that must exist in the source. ///  ///  /// The source to convert. ///  ///  /// Thrown if source is null. ///  ///  /// The 2D array of source items. ///  public static T[,] To2DArray(this IList> source) { if (source == null) { throw new ArgumentNullException("source"); } int max = source.Select(l => l).Max(l => l.Count()); var result = new T[source.Count, max]; for (int i = 0; i < source.Count; i++) { for (int j = 0; j < source[i].Count(); j++) { result[i, j] = source[i][j]; } } return result; } 

没有简单的方法可以做到这一点,因为在你所描述的情况下,没有什么能阻止列表中的double[]数组成为不同的大小,这与二维矩形数组不兼容。 但是,如果您确保double[]数组都具有相同的维度,则可以按如下方式构造二维数组:

 var arr = new double[ret.Count(),ret[0].Count()]; for( int i=0; i 

如果列表中的任何double[]数组比第一个数组短,则会产生运行时错误,如果任何数组大于第一个数组,则会丢失数据。

如果您确实要将锯齿状数组存储在矩形数组中,则可以使用“魔术”值来表示该位置没有值。 例如:

 var arr = new double[ret.Count(),ret.Max(x=>x.Count())]; for( int i=0; i 

在编辑上,我认为这是一个非常糟糕的想法™; 当你去使用矩形arrays时,你必须一直检查Double.NaN 。 此外,如果您想将Double.NaN用作数组中的合法值,该怎么办? 如果你有一个锯齿状arrays,你应该把它留作锯齿状arrays。

如果你打算复制(我想不出更好的方法)

 var width = ret[0].length; var length = ret.Count; var newResult = new double[width, length] Buffer.BlockCopy(ret.SelectMany(r => r).ToArray(), 0, newResult, 0, length * width); return newResult; 

编辑

我几乎肯定是循环而不是使用SelectManyToArray更快。

我知道我什么时候受到了抨击。