如何在JavaScript中实现多个数组的笛卡尔乘积?
举个例子,
cartesian([1, 2], [10, 20], [100, 200, 300]) 应该返回
[
[1, 10, 100],
[1, 10, 200],
[1, 10, 300],
[2, 10, 100],
[2, 10, 200]
...
]发布于 2016-03-26 18:31:03
以下是@viebel代码的修改版本,使用纯Javascript编写,不使用任何库:
function cartesianProduct(arr) {
return arr.reduce(function(a,b){
return a.map(function(x){
return b.map(function(y){
return x.concat([y]);
})
}).reduce(function(a,b){ return a.concat(b) },[])
}, [[]])
}
var a = cartesianProduct([[1, 2,3], [4, 5,6], [7, 8], [9,10]]);
console.log(JSON.stringify(a));
发布于 2012-09-07 01:16:37
似乎社区认为这是微不足道的和/或很容易找到参考实现。然而,经过简单的检查,我找不到一个,…要么是因为我喜欢重新发明轮子,要么是因为我喜欢解决类似课堂的编程问题。无论哪种方式,今天都是你的幸运日:
function cartProd(paramArray) {
function addTo(curr, args) {
var i, copy,
rest = args.slice(1),
last = !rest.length,
result = [];
for (i = 0; i < args[0].length; i++) {
copy = curr.slice();
copy.push(args[0][i]);
if (last) {
result.push(copy);
} else {
result = result.concat(addTo(copy, rest));
}
}
return result;
}
return addTo([], Array.prototype.slice.call(arguments));
}
>> console.log(cartProd([1,2], [10,20], [100,200,300]));
>> [
[1, 10, 100], [1, 10, 200], [1, 10, 300], [1, 20, 100],
[1, 20, 200], [1, 20, 300], [2, 10, 100], [2, 10, 200],
[2, 10, 300], [2, 20, 100], [2, 20, 200], [2, 20, 300]
]完全参考实现,这是相对高效的…
关于效率:你可以通过把if从循环中去掉并有两个单独的循环来获得一些,因为它在技术上是常量,你可以帮助分支预测和所有的混乱,但这一点在JavaScript中是没有意义的。
发布于 2015-04-12 11:40:35
下面是一个简单明了的递归解决方案:
function cartesianProduct(a) { // a = array of array
var i, j, l, m, a1, o = [];
if (!a || a.length == 0) return a;
a1 = a.splice(0, 1)[0]; // the first array of a
a = cartesianProduct(a);
for (i = 0, l = a1.length; i < l; i++) {
if (a && a.length)
for (j = 0, m = a.length; j < m; j++)
o.push([a1[i]].concat(a[j]));
else
o.push([a1[i]]);
}
return o;
}
console.log(cartesianProduct([[1, 2], [10, 20], [100, 200, 300]]));
// [
// [1,10,100],[1,10,200],[1,10,300],
// [1,20,100],[1,20,200],[1,20,300],
// [2,10,100],[2,10,200],[2,10,300],
// [2,20,100],[2,20,200],[2,20,300]
// ]
https://stackoverflow.com/questions/12303989
复制相似问题