遍历两个变量的所有排列组合

5
我需要调用以下函数cross 4次,对于所有由值1和-1的xy变量的排列组合;
我的方法:
var p = [-1, 1];

p.forEach(function(x) {
  p.forEach(function(y) {
    cross(x, y);
  });
});

有没有更短的方法来做这件事?


3
「您所说的更短是指代码行数更少,还是执行时间更快(更高效)?」 - Alvaro Montoro
1
我认为这个问题更适合在代码审查上提问,因为在Javascript数组中找到所有元素的排列组合已经有答案了(https://dev59.com/oGkw5IYBdhLWcg3wV5ID)。 - alex
4
实际上他不是在寻找排列,而是在寻找该数组的笛卡尔积 - Bergi
3
这段话的意思是:“这段代码可能会被视为‘示例代码’,并且在Code Review上被关闭,因为不符合主题”。 - Simon Forsberg
1
@SimonAndréForsberg +1 fair enough - alex
显示剩余7条评论
4个回答

3

如果你想更加实用,可以使用map函数并将数组缩减成一个。我认为这种方式并不比现在的方法更高效,也没有更加简单(只是更加实用而已)。

var d = [-1, 1];

var r = d.reduce(function(p, x) {
  return p.concat(d.map(function(y) {
    return cross(x, y);
  }));
}, []);

document.getElementById('r').textContent = JSON.stringify(r);
<pre id=r></pre>

我真的认为没有比O(n^2)更高效的算法来生成n^2种组合。


2

既然您已经知道数组p的长度,就不需要循环了。最快的解决方案是:

var p = [-1, 1];
cross(p[0], p[0]);
cross(p[0], p[1]);
cross(p[1], p[0]);
cross(p[1], p[1]);

2
这是特定情况下最明显的解决方案,已点赞! - Filipe Borges
你为什么使用 0 而不是 -1 - Mulan
@naomik:它是位置0,而不是值0。 - Brian Stephens
2
嘿,这个数组是静态的,所以最好不要访问它,而是执行 cross(-1,-1); cross(-1,1); cross(1,-1); cross(1,1); :-) - Bergi
那会更快。 - bhspencer

1

调用函数会有一些额外开销,例如将返回指针放在堆栈上。使用两个for循环而不是回调函数来进行forEach可能会稍微快一些。

var p = [-1, 1];
for (var x = 0; x < p.length; x++) {
    for (var y = 0; y < p.length; y++) {
        cross(p[x], p[y]);
    } 
}

1
这将更快:
for (var n = 0; n < 4; ++n) 
     cross(n & 2 ? 1:-1, n & 1 ? -1:1);

但是它更短吗?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接