如何用 LINQ 重写笛卡尔积
Posted
技术标签:
【中文标题】如何用 LINQ 重写笛卡尔积【英文标题】:How to rewrite cartesian product with LINQ 【发布时间】:2021-07-17 02:15:27 【问题描述】:我有三个函数,一个使用来自 2 个数组的循环生成笛卡尔积,另一个使用来自 3 个数组的循环,以及一个使用 LINQ 和 2 个数组生成笛卡尔积。我想编写一个 LINQ 解决方案来获得 3 个数组。
private static string[][] CartesianProductSmart(string[] arr1, string[] arr2)
// for each s1 in arr1, extract arr2,
// then pass s1 and s2 into a newly-made string array.
return arr1.SelectMany(s1 => arr2, (s1, s2) => new string[] s1, s2 )
.ToArray();
private static string[][] CartesianProductDumb(string[] arr1, string[] arr2)
// the dumb way; nested foreach
string[][] combos = new string[arr1.Length * arr2.Length][];
int ii = 0;
foreach (var strOne in arr1)
foreach (var strTwo in arr2)
string[] combo = new string[2];
combo[0] = strOne;
combo[1] = strTwo;
combos[ii] = combo;
ii++;
return combos;
private static string[][] CartesianProductDumbX3(string[] arr1, string[] arr2, string[] arr3)
// the dumb way; nested foreach
string[][] combos = new string[arr1.Length * arr2.Length * arr3.Length][];
int ii = 0;
foreach (var strOne in arr1)
foreach (var strTwo in arr2)
foreach (var strThree in arr3)
string[] combo = new string[3];
combo[0] = strOne;
combo[1] = strTwo;
combo[2] = strThree;
combos[ii] = combo;
ii++;
return combos;
前两个函数的行为相同 - 它们都返回 2 个数组的笛卡尔积。第三个是用三个数组做的,我怎样才能用 LINQ 重写那个函数? (最终我想写它以便我可以给它任何数组编号,但现在只有 3 就足够了。
【问题讨论】:
Just for reference. 【参考方案1】:我不确定这是否是您要查找的内容,但它对我来说似乎是最简单和最易读的:
private static string[][] CartesianProductLinq(string[] arr1, string[] arr2,
string[] arr3)
return (from s1 in arr1
from s2 in arr2
from s3 in arr3
select new[] s1, s2, s3).ToArray();
如果您更喜欢方法链语法,它可能类似于:
private static string[][] CartesianProductLinq(string[] arr1, string[] arr2,
string[] arr3)
return arr1
.SelectMany(s1 => arr2, (s1, s2) => new s1, s2)
.SelectMany(result => arr3, (result, s3) => new[] result.s1, result.s2, s3)
.ToArray();
请注意,方法名称已更改,因为 Linq 并非天生“聪明”,循环也并非天生“愚蠢”(在某些情况下,循环可能更有效)
【讨论】:
以上是关于如何用 LINQ 重写笛卡尔积的主要内容,如果未能解决你的问题,请参考以下文章