可以LINQ构造并返回多维数组

本文关键字:数组 返回 LINQ 可以 | 更新日期: 2023-09-27 18:25:56

是的,我知道锯齿状数组[][]和多维数组[,]之间的区别。

是的,我找过重复的,发现了这些:

  • 如何在多维数组上使用LINQ以';展开';阵列
  • 转换二维数组
  • c#linq从linq返回一个多维数组

其中最后一个包含一个函数来完成这项工作。但我的问题仍然是:有没有任何方法(无论多么扭曲或做作)说服LINQ以多维数组的形式构建并返回结果(而不是锯齿状数组)?


它实际上与这个问题无关,但导致这里的问题是一个看起来像是"为LINQ而生"的小作业,只是我需要调用的函数是用多维数组参数定义的。将答案生成为锯齿状数组的LINQ代码大约需要5分钟的编写时间,然后呢?是我错过了什么,还是LINQ真的没有办法完成这项工作?


我想我应该说:除了用旧的方式写一大块代码并将其嵌入为lambda或将其作为扩展方法调用之外。目前看来,LINQ既不能生成也不能使用多维数组,我的问题的答案是否定的。

可以LINQ构造并返回多维数组

嗯。。好当然如果可能的话,这是一个如何将整数列表转换为二维数组的示例。

void Main()
{
    var wat = new[]{2, 4, 5, 6, 7, 8}
        .Select(x => new { dummy=1, val= x})
        .GroupBy(x => x.dummy) // group everything into one, "UNFLATTEN"
        .Select(gr => 
            {
                var elements = gr.Select(x => x.val).ToList();
                if(elements.Count == 0 || elements.Count % 2 != 0)
                    throw new NotSupportedException("I don't know what to do.");
                var halfSize = elements.Count / 2;
                int[,] ret = new int[2, halfSize];
                for(var k = 0; k < halfSize; k++){
                    ret[0, k] = elements[k];
                    ret[1, k] = elements[elements.Count - halfSize + k];
                }
                return ret;
            }
        ).First();
    wat.Dump();
}

输出:

_0 1 2

02 4 5

16 7 8

正如其他人所说,最好创建新的扩展方法:

static class LinqExtensions
{
    public static T[,] ToRectangularArray<T>(this IEnumerable<IEnumerable<T>> arrays)
    {
        // TODO: Validation and special-casing for arrays.Count == 0
        // TODO: Rename "arrays"
        // TODO: Make sure that Count() is used only once,
        // TODO: ElementAt() does not work everywhere, you're better off using ToList() before!
        int minorLength = arrays.First().Count();
        T[,] ret = new T[arrays.Count(), minorLength];
        for (int i = 0; i < arrays.Count(); i++)
        {
            var array = arrays.ElementAt(i);
            if (array.Count() != minorLength)
            {
                throw new ArgumentException
                    ("All arrays must be the same length");
            }
            for (int j = 0; j < minorLength; j++)
            {
                ret[i, j] = array.ElementAt(j);
            }
        }
        return ret;
    }
}
void Main()
{
    var wat = new[]{new[]{2, 4, 5}, new[]{6, 7, 8}}.ToRectangularArray();
    wat.Dump();
}

为了方便起见,您可能需要为IEnumerable<T>添加相同的扩展方法,并这样调用它:ToRectangularArray<T>(this IEnumerable<T> input, int dimensions = 2)

我想我应该说:除了写一大块代码来做这件事旧方法,并将其嵌入为lambda或将其作为扩展调用方法目前看来,LINQ既不能生产也不能使用多维数组,而我的问题的答案是否定的。

不是。大多数LINQ方法都是IEnumerable<T>的扩展方法。锯齿状数组(比如int[int[]])实现IEnumerable<int[]>,而多维数组不实现IEnumerable<T>,因此不能使用任何LINQ扩展方法。

您唯一能做的就是使用投影(Select)最终返回一个多维数组。