JavaScript中如何从对象数组的数组生成所有可能组合?
实现对象数组的笛卡尔积组合
给定一个包含对象数组的嵌套数组,结构示例如下:
[{a:1}, {a:2}, {a:3}], [{b:1}, {b:2}], [{c:1}, {c:2}]
需要生成包含所有对象组合的新数组,每个组合是从每个子数组中取一个对象合并后的结果,示例输出:
[ { a:1, b:1, c:1 }, { a:1, b:1, c:2 }, { a:1, b:2, c:1 }, { a:1, b:2, c:2 }, { a:2, b:1, c:1 }, { a:2, b:1, c:2 }, { a:2, b:2, c:1 }, { a:2, b:2, c:2 }, { a:3, b:1, c:1 }, { a:3, b:1, c:2 }, { a:3, b:2, c:1 }, { a:3, b:2, c:2 } ]
高效实现方案
可以利用数组的reduce和flatMap方法实现笛卡尔积,无需手动嵌套循环,能适配任意数量的子数组和子数组内的对象数量:
function combineObjects(arrays) { return arrays.reduce((acc, current) => { return acc.flatMap(item => { return current.map(obj => ({ ...item, ...obj })); }); }, [{}]); } // 测试示例 const input = [[{a:1}, {a:2}, {a:3}], [{b:1}, {b:2}], [{c:1}, {c:2}]]; const result = combineObjects(input); console.log(result);
逻辑说明
- 初始值
[{}]是包含空对象的数组,作为合并的起始点。 reduce遍历每个子数组:- 对当前累积的每个对象(
acc中的item),和当前子数组的每个对象(current中的obj)用扩展运算符{...item, ...obj}完成浅拷贝合并。 flatMap扁平化每次合并生成的二维数组,确保累积结果始终是一维数组。
- 对当前累积的每个对象(
这种方法的时间复杂度为O(n1 * n2 * ... * nk)(n1到nk为各子数组长度),是生成笛卡尔积的最优时间复杂度,因为必须遍历所有可能的组合。
内容的提问来源于stack exchange,提问作者daggett
相关产品推荐
相关产品推荐

