如何获得包含列表的列表的笛卡尔积?

How to get a Cartesian product of a list containing lists?

我能够使用 C# 中的 Linq 获得硬编码/已知列表的笛卡尔积,如下所示。但是我需要得到一个列表的笛卡尔产品,它本身包含一个元素列表。有人可以帮助使用 Linq 查询吗?请看下面。在第一部分中,我得到了很好的笛卡尔积,但是如何使用列表的列表复制行为?

static void Main(string[] args)
        {
            int[] list1 = { 11, 12, 13};
            int[] list2 = { 21, 22, 23 };
            int[] list3 = { 31, 32, 33 };

            Console.Write("\nLINQ : Generate a Cartesian Product of three sets : ");
            Console.Write("\n----------------------------------------------------\n");

            var cartesianProduct = from n1 in list1
                                   from n2 in list2
                                   from n3 in list3
                                   select new { n1, n2, n3};

            Console.Write("The Cartesian Product are : \n");
            foreach (var ProductList in cartesianProduct)
            {
                Console.WriteLine(ProductList);
            }

            // The above code works; now I want the same results but by using a list containing lists.

            List<long> List1 = new List<long>();
            List1.Add(11);
            List1.Add(12);
            List1.Add(13);

            List<long> List2 = new List<long>();
            List2.Add(21);
            List2.Add(22);
            List2.Add(23);

            List<long> List3 = new List<long>();
            List3.Add(31);
            List3.Add(32);
            List3.Add(33);

            List<List<long>> bigList = new List<List<long>>();
            bigList.Add(List1);
            bigList.Add(List2);
            bigList.Add(List3);

            // How to get the cartesian product of a bigList that may contain multiple lists in Linq?


            Console.ReadLine();
        }

这是一个使用 Aggregate 的 LINQ 扩展方法:

public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) =>
    sequences.Aggregate(
        Enumerable.Empty<T>().AsSingleton(),
        (accumulator, sequence) => accumulator.SelectMany(
            accseq => sequence,
            (accseq, item) => accseq.Append(item)));

您需要扩展方法AsSingleton:

public static IEnumerable<T> AsSingleton<T>(this T item) => new[] { item };

这是基于@EricLippert 的this answer