You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用LINQ对未知数量的字符串数组执行交叉连接?

在LINQ中对n个字符串数组执行交叉连接(笛卡尔积)

当然可以!当你需要对n个字符串数组执行交叉连接(也就是笛卡尔积)时,LINQ完全能实现这个需求——核心是用迭代累积或者递归的方式动态构建结果,而不用写死固定数量的Join或SelectMany。

方法一:使用迭代+SelectMany累积构建

最直观的方式是用循环配合SelectMany,从一个初始的“空结果”开始,逐个和后续的数组做交叉连接,逐步组合出最终的笛卡尔积。

以下是实现代码:

public static IEnumerable<string[]> CrossJoin(params string[][] arrays)
{
    // 初始值:一个仅包含空数组的集合,作为笛卡尔积的起始基准
    IEnumerable<string[]> result = new[] { Array.Empty<string>() };

    foreach (var array in arrays)
    {
        // 跳过空数组,避免直接得到空结果(可选,根据你的业务需求调整)
        if (!array.Any())
            return Enumerable.Empty<string[]>();

        // 将当前累积的结果与下一个数组的每个元素交叉组合
        result = result.SelectMany(prevCombination => array, 
            (prevItems, currentItem) => prevItems.Concat(new[] { currentItem }).ToArray());
    }

    return result;
}

代码说明:

  • 初始的result是一个只有空数组的集合,这样第一次循环时,会把空数组和第一个数组的每个元素组合,得到第一个数组的所有元素(每个元素作为单独的数组)。
  • 后续每次循环,都会把之前的所有组合结果,和当前数组的每个元素重新组合,最终得到n个数组的完整笛卡尔积。
  • 额外加了空数组判断,如果输入中存在空数组,直接返回空结果(符合笛卡尔积的数学定义:只要有一个集合为空,结果就为空)。

使用示例:

var group1 = new[] { "a", "b" };
var group2 = new[] { "1", "2" };
var group3 = new[] { "x", "y" };
var group4 = new[] { "!", "@" };

// 传入任意数量的数组
var crossJoinedResult = CrossJoin(group1, group2, group3, group4);

// 输出的每个元素都是一个组合数组,比如 ["a","1","x","!"]、["a","1","x","@"] 等等
foreach (var combination in crossJoinedResult)
{
    Console.WriteLine(string.Join(", ", combination));
}

方法二:递归实现

如果你更喜欢递归的写法,也可以通过递归拆分问题:每次处理第一个数组,然后递归处理剩下的数组,再把两者的结果组合起来。

代码示例:

public static IEnumerable<string[]> CrossJoinRecursive(IEnumerable<string[]> arrays)
{
    var arrayList = arrays.ToList();
    
    // 递归终止条件:没有剩余数组时,返回包含空数组的集合
    if (arrayList.Count == 0)
    {
        yield return Array.Empty<string>();
        yield break;
    }

    var firstArray = arrayList[0];
    var remainingArrays = arrayList.Skip(1);

    // 遍历第一个数组的每个元素,和剩余数组的递归结果组合
    foreach (var item in firstArray)
    {
        foreach (var subCombination in CrossJoinRecursive(remainingArrays))
        {
            yield return new[] { item }.Concat(subCombination).ToArray();
        }
    }
}

代码说明:

  • 当没有剩余数组时,返回空数组作为递归的“基础组合”。
  • 对于每个数组,先取第一个数组的元素,再递归得到剩下数组的所有组合,最后把当前元素和每个子组合拼接,得到完整的组合结果。

注意事项

  • 如果输入的数组数量为0,两种方法都会返回一个包含空数组的集合(你可以根据需求调整这个行为)。
  • 笛卡尔积的结果数量是所有数组长度的乘积,当数组数量多或每个数组元素多的时候,结果会非常庞大,要注意内存和性能问题。

内容的提问来源于stack exchange,提问作者Asken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:57:03