从List<double[]>转换为double[,]

5
有没有一个一行代码的方法(无需循环)将 List<double[]> 转换为 double[,]

2
这完全取决于你想要多长的行 :) (我怀疑超过80个字符)。 - leppie
@leppie:想知道80个字符长度是否是某种标准? - abatishchev
@abatishchev:在过去,它是这样的,但现在,我认为人们更喜欢120。 - leppie
@leppie:从来没有理解过这样小的尺寸。19英寸显示器已经非常普遍了。许多开发人员拥有比19英寸、21英寸和25英寸更大的显示器。所以在我看来,查看140到240个字符很容易忽略。 - abatishchev
@abatishchev:在旧时代,文本终端的显示范围被限制在80 x 25 - 50(垂直行)之间。 - leppie
显示剩余2条评论
5个回答

5

将列表转换为 double[,] 只能通过循环遍历进行,并且要求列表中包含的所有数组大小相同:

double[,] arr = new double[list.Count, list[0].Length];
for (int i = 0; i < list.Count; i++)
{
    for (int j = 0; j < list[0].Length; j++)
    {
        arr[i, j] = list[i][j];
    }
}

当然,您可以通过调用.ToArray()轻松创建一个不规则的double[][]数组:
double[] array = new double[] { 1.0, 2.0, 3.0 };
double[] array1 = new double[] { 4.0, 5.0, 6.0 };

List<double[]> list = new List<double[]>();
list.Add(array);
list.Add(array1);

double[][] jaggedArray = list.ToArray();

如果数组大小不符合要求,您还可以添加末尾的零。 - abatishchev
@abatishchev:是的,说得好。这需要额外的遍历来首先找到列表中最长的条目,以便确定所需的数组大小。 - Dirk Vollmar
在列表中找到最长的数组首先最好使用list[0]。 - Cheng Chen
@Danny:我认为多迭代一次比修剪所有长度大于第一个数组的更好。 - abatishchev
1
@Danny: new List<double[]>().Max(a => a.Length) - abatishchev

3

嗯,也许你无法避免使用循环来实现它,但你可以使使用成为一行代码:

double[,] array = list.To2DArray();

To2DArray是一个扩展方法,实现如下:

public static class ExtensionMethods
{
    public static T[,] To2DArray<T>(this IEnumerable<IEnumerable<T>> source)
    {
        var jaggedArray = source.Select(r => r.ToArray()).ToArray();
        int rows = jaggedArray.GetLength(0);
        int columns = jaggedArray.Max(r => r.Length);
        var array = new T[rows, columns];
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < jaggedArray[i].Length; j++)
            {
                array[i, j] = jaggedArray[i][j];
            }
        }
        return array;
    }
}

请注意,此代码仅适用于C# 4,因为早期版本不支持协变。这个变体应该可以在C# 3中工作,但更具体:
public static T[,] To2DArray<T>(this IEnumerable<T[]> source)
{
    var jaggedArray = source.ToArray();
    // same code from here
}

你可以直接使用 int rows = source.Count(); int columns = source.Max(r => r.Count());,而不需要先创建一个交错数组。 - Dirk Vollmar
是的,但我之后需要使用不规则数组来访问数据(我可以使用ElementAt方法,但对于只能枚举一次的可枚举对象它不起作用)。 - Thomas Levesque

0
public static T[,] ToMultidimensional<T>(this T[][] arr, int maxSize)
{
    T[,] md = (T[,])Array.CreateInstance(typeof(double), arr.Length, maxSize);

    for (int i = 0; i < arr.Length; i++)
    for (int j = 0; j < arr[i].Length; j++)
        md[i, j] = arr[i][j];

    return md;
}

var arr = new List<double[]>
{
    new double[] { 1, 2, 3 },
    new double[] { 4, 5 }
}
.ToArray();

var j = arr.ToMultidimensional(arr.Max(a => a.Length));

0
这个语法应该可以工作: return new List{new double[] { minX, minY }, new double[] { maxX, maxY }};


0
如果要从一维数组列表创建二维数组,则需要循环,尽管在调用站点上可能看不出来。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接