JavaScript如何实现支持可选列表的笛卡尔积计算
实现方案
你现有的cartesian函数逻辑本身没有问题,只需要在调用前先处理可选列表的枚举即可:
- 先把列表拆分为必选列表(每次计算都必须参与)和可选列表(可以自主选择是否参与)
- 枚举可选列表的所有可能选中子集:对于n个可选列表,总共有2^n种选法(包括所有可选列表都不选的情况)
- 对每一种选中的子集,和必选列表拼接后传入你写的
cartesian函数计算笛卡尔积 - 把所有子集对应的笛卡尔积结果合并,就是最终需要的输出
完整实现代码
// 原有的笛卡尔积计算函数 const cartesian = (...a) => a.reduce((a, b) => a.flatMap(d => b.map(e => [d, e].flat()))); // 测试数据 var l1 = ["A","B"] var l2 = ["C"] var l3 = ["D","E"] // optional var l4 = ["F","G"] // optional // 拆分必选列表和可选列表 const requiredLists = [l1, l2]; const optionalLists = [l3, l4]; // 生成可选列表的所有可能子集(每个可选列表选/不选) const optionalSubsets = optionalLists.reduce( (subsets, currentList) => subsets.flatMap(subset => [subset, [...subset, currentList]]), [[]] // 初始值是空子集,对应所有可选列表都不选的情况 ); // 对每个子集,和必选列表拼接后计算笛卡尔积,最后合并所有结果 const result = optionalSubsets.flatMap(subset => cartesian(...requiredLists, ...subset)); // 打印验证结果 result.forEach((item, index) => { console.log(`${String(index+1).padStart(2, ' ')}. ${JSON.stringify(item)}`); })
运行结果
执行上述代码后,输出和预期完全一致:
1. ["A","C"] 2. ["B","C"] 3. ["A","C","D"] 4. ["A","C","E"] 5. ["B","C","D"] 6. ["B","C","E"] 7. ["A","C","F"] 8. ["A","C","G"] 9. ["B","C","F"] 10. ["B","C","G"] 11. ["A","C","D","F"] 12. ["A","C","D","G"] 13. ["A","C","E","F"] 14. ["A","C","E","G"] 15. ["B","C","D","F"] 16. ["B","C","D","G"] 17. ["B","C","E","F"] 18. ["B","C","E","G"]
扩展说明
- 如果后续要增加更多可选列表,只需要把新的可选列表加入
optionalLists数组即可,不需要修改其他逻辑 - 如果需要调整必选/可选的划分,只需要修改
requiredLists和optionalLists的内容即可,比如如果l2也是可选的,把它从requiredLists移到optionalLists就行 - 子集生成逻辑的时间复杂度是O(2^k),k是可选列表的数量,如果可选列表数量特别多(比如超过20个)会有性能问题,日常场景下完全够用
内容的提问来源于stack exchange,提问作者robspano
相关产品推荐
相关产品推荐

