我正在尝试构建一个javascript函数来从数组中获取大小为N的所有组合。 让我说我得到了:
const Xarray = ["19", "21","42","23", "25", "28"];
const n = 4;
combinationsOfN(Xarray, n) =>
[ ["19", "21", "42", "23"],
["19", "21", "42", "25"],
["19", "21", "42", "28"],
["19", "21", "23", "25"],
["19", "21", "23", "28"],
["19", "21", "25", "28"],
…. ]
答案 0 :(得分:2)
自己这样做可能会相当艰难,因为我已经尝试过了。已经有一个js工具可以为您执行此操作combinations.js
/**
* Copyright 2012 Akseli Palén.
* Created 2012-07-15.
* Licensed under the MIT license.
*/
function k_combinations(set, k) {
var i, j, combs, head, tailcombs;
if (k > set.length || k <= 0) {
return [];
}
if (k == set.length) {
return [set];
}
if (k == 1) {
combs = [];
for (i = 0; i < set.length; i++) {
combs.push([set[i]]);
}
return combs;
}
combs = [];
for (i = 0; i < set.length - k + 1; i++) {
head = set.slice(i, i+1);
tailcombs = k_combinations(set.slice(i + 1), k - 1);
for (j = 0; j < tailcombs.length; j++) {
combs.push(head.concat(tailcombs[j]));
}
}
return combs;
}
function combinations(set) {
var k, i, combs, k_combs;
combs = [];
for (k = 1; k <= set.length; k++) {
k_combs = k_combinations(set, k);
for (i = 0; i < k_combs.length; i++) {
combs.push(k_combs[i]);
}
}
return combs;
}
var array = ["19", "21","42","23", "25", "28"];
document.body.innerHTML += "<pre>" + JSON.stringify(k_combinations(array, 4), false, "\t") + "</pre>";
&#13;
答案 1 :(得分:1)
我提供两种解决方案,第一种是结果,其中包括任何地方的物品。
function combine(array, length) {
function c(l, r) {
var i, ll;
if (r.length === length) {
result.push(r);
return;
}
for (i = 0; i < l.length; i++) {
ll = l.slice();
c(ll, r.concat(ll.splice(i, 1)));
}
}
var result = [];
c(array, []);
return result;
}
document.write('<pre>' + JSON.stringify(combine(["19", "21", "42", "23", "25", "28"], 4), 0, 4) + '</pre>');
&#13;
第二个按原始顺序仅返回一个项目。此结果集比上面的更短,就像akinuri的答案一样。
function combine(array, length) {
function c(l, r) {
var ll = l.slice();
if (r.length === length) {
result.push(r);
return;
}
while (ll.length) {
c(ll, r.concat(ll.shift()));
}
}
var result = [];
c(array, []);
return result;
}
document.write('<pre>' + JSON.stringify(combine(["19", "21", "42", "23", "25", "28"], 4), 0, 4) + '</pre>');
&#13;
答案 2 :(得分:1)
我不得不说我有时讨厌JS。我肯定非常讨厌push()
。当你执行功能时,你需要越来越多的对变异对象的引用。改变它所调用的对象的方法应该返回对该对象的引用。
无论如何,代码本来可以简单得多,但是唉......这就是它的功能。它只不过是一个简单的递归运行。复杂的外观部分实际上是愚蠢的部分,如;
a.slice(0,i).concat(a.slice(i+1))
实际上意味着删除索引位置i处的元素并返回结果数组。当您需要将此功能用作单个指令或可链式指令作为函数的参数时,这似乎是唯一的方法。就像
一样(t.push(c),t)
指令。这意味着将c推送到t数组并返回t数组。傻推(c)将返回长度...我讨厌它。你给我一个参考人,如果需要,我可以从中获得长度。所以其余的很容易理解。
所以我有两个解决方案,一个用于排列,一个用于组合。
var xarray = ["19", "21", "42", "23", "25", "28"],
n = 4;
function getPermutations(a,n,s=[],t=[]){
return a.reduce((p,c,i,a) => { n > 1 ? getPermutations(a.slice(0,i).concat(a.slice(i+1)), n-1, p, (t.push(c),t))
: p.push((t.push(c),t).slice(0));
t.pop();
return p},s)
}
document.write("<pre>" + JSON.stringify(getPermutations(xarray,n),null,2) + "</pre>");
&#13;
现在组合......
var xarray = ["19", "21", "42", "23", "25", "28"],
n = 4;
function getCombinations(a,n,s=[],t=[]){
return a.reduce((p,c,i,a) => { n > 1 ? getCombinations(a.slice(i+1), n-1, p, (t.push(c),t))
: p.push((t.push(c),t).slice(0));
t.pop();
return p},s)
}
document.write("<pre>" + JSON.stringify(getCombinations(xarray,n),null,2) + "</pre>");
&#13;