1

我想构建一个方法或扩展方法,它采用多个列表并按以下方式组合它们:

假设我有两个列表:

        int[] list1 =  {3, 1, 2};
        int[] list2 =  {5, 4 };

我希望得到一个数组列表,结果如下:

[1,4]
[1,5]
[2,4]
[2,5]
[3,4]
[3,5]

我的结果数组列表中的列数将由传递的列表数量决定,并且两列都需要排序。行数就是(列表 A 的长度)*(列表 B 的长度)*(列表 N 的长度)

在此示例中为 3 * 2 = 6 行。2 列(因为 2 个输入列表)。

用 linq 做这件事的优雅方式是什么?

谢谢!

4

3 回答 3

3

尝试交叉连接

int[] list1 =  {3, 1, 2};
int[] list2 =  {5, 4 }; 

var result = (from l1 in list1
             from l2 in list2
             select new [] {l1, l2}).ToList()
于 2013-10-22T15:36:40.510 回答
2

使用SelectMany

var combinations = list1.SelectMany(i1 => list2.Select(i2 => new[] { i1, i2 }));

或者如果你喜欢

var combinations = list1.SelectMany(i1 => list2, (i1, i2) => new[] { i1, i2 });

OrderBy如果您想按特定顺序获得结果,您可以使用etc进行跟进。

于 2013-10-22T15:36:25.783 回答
2

感谢@Jon 为我指出了正确的来源,@EricLippert 为他提供了聪明的解决方案:

    public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
    {
        IEnumerable<IEnumerable<T>> emptyProduct =
          new[] { Enumerable.Empty<T>() };
        return sequences.Aggregate(
          emptyProduct,
          (accumulator, sequence) =>
            from accseq in accumulator
            from item in sequence
            select accseq.Concat(new[] { item }));
    }

http://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/

适用于整数和字符串:

        string[] list1 =  {"1", "2", "3"};
        string[] list2 =  { "4","5" };

        var lists = new List<string[]>(){list1,list2};

        var result = lists.CartesianProduct();
于 2013-10-22T16:10:55.017 回答