Combinations Of Size N From An Array
Solution 1:
Doing this by yourself might be rather tough, because I've tried that. There's already a js tool that does this for you, combinations.js
/**
* Copyright 2012 Akseli Palén.
* Created 2012-07-15.
* Licensed under the MIT license.
*/functionk_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;
}
functioncombinations(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>";
Solution 2:
Well i have to say i hate JS sometimes. I definitely hate push()
that for sure. When you do functional you need more and more a reference to the mutated objects. A method mutating an object it's called upon shall return a reference to that object.
Anyways the code could have been much simpler looking but alas... this is as far as it gets. It's nothing more than a simple recursive run. The complicated looking parts are actually the stupid parts such as;
a.slice(0,i).concat(a.slice(i+1))
in fact means delete the element at index position i and return the resulting array. When you need to use this functionality as a single instruction or a chainable instruction as an argument to a function this seems to be the only way. Just like the
(t.push(c),t)
instruction. Which means push c to t array and return t array. Silly push(c) would return the length... I hate it. You give me the reference man i can get the length from that if needed. So the rest is easy to understand.
So i have two solutions one for the permutations and one for the combinations.
var xarray = ["19", "21", "42", "23", "25", "28"],
n = 4;
functiongetPermutations(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>");
And now the combinations...
var xarray = ["19", "21", "42", "23", "25", "28"],
n = 4;
functiongetCombinations(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>");
Solution 3:
I offer two solutions, the first with a result which includes the items at any place.
functioncombine(array, length) {
functionc(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>');
The second which returns only one item at in original order. This result set is shorter then the above and like the answer of akinuri.
functioncombine(array, length) {
functionc(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>');
Post a Comment for "Combinations Of Size N From An Array"