C#中是否有LINQ函数可实现多个List集合的笛卡尔积运算
C# 多泛型List集合笛卡尔积的LINQ实现方案
C# 原生LINQ没有内置直接支持任意数量集合笛卡尔积运算的方法,不过可以通过LINQ的SelectMany算子实现通用的笛卡尔积逻辑,同时针对固定数量的集合可以直接用LINQ查询语法快速实现。
固定数量集合的简单实现
如果需要做笛卡尔积的集合数量是固定的(比如你示例中的3个集合),可以直接用嵌套from的LINQ查询语法,代码最简洁:
// 针对示例中的3个集合直接计算笛卡尔积 var fixedResult = from c1 in list1 from c2 in list2 from c3 in list3 select new [] { c1, c2, c3 };
任意数量集合的通用实现
如果需要适配传入任意数量集合的场景(即你示例中List<List<Color>>类型的入参),可以封装通用的LINQ扩展方法,如下:
1. 通用笛卡尔积扩展方法
public static class EnumerableExtensions { public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) { // 初始化基准空集合 IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() }; foreach (var sequence in sequences) { // 每次迭代累加新集合的所有组合 result = result.SelectMany( existing => sequence, (existing, item) => existing.Concat(new[] { item }) ); } return result; } }
2. 适配你的Result方法实现
针对你代码中返回Color[,]二维数组的签名,只需要把扩展方法返回的可枚举集合转换成二维数组即可:
private Color[,] Result(List<List<Color>> colors) { // 计算笛卡尔积 var product = colors.CartesianProduct().ToList(); if (!product.Any()) return new Color[0, 0]; int rowCount = product.Count; int colCount = product.First().Count(); var resArray = new Color[rowCount, colCount]; // 转换为二维数组 for (int i = 0; i < rowCount; i++) { var currentRow = product[i].ToList(); for (int j = 0; j < colCount; j++) { resArray[i, j] = currentRow[j]; } } return resArray; }
3. 结果验证
运行你的测试方法后,遍历返回的二维数组输出名称,即可完全匹配你注释中列出的12条组合结果:
var result = Result(CompleteList); for (int i = 0; i < result.GetLength(0); i++) { var nameList = new List<string>(); for (int j = 0; j < result.GetLength(1); j++) { nameList.Add(result[i,j].Name); } Console.WriteLine(string.Join(", ", nameList)); }
内容的提问来源于stack exchange,提问作者user1742179
相关产品推荐
相关产品推荐

