Instantly share code, notes, and snippets.

# axelpale/combinations.js Last active Jun 10, 2020

JavaScript functions to calculate combinations of elements in Array.

### agrimnigam21 commented Nov 6, 2013

 I think it doesnt work for 4 elements

### hardcoremore commented Nov 8, 2013

 It works great. Thanks. I tested it for 4 elements as well and it works great. Thanks.

### chrisgoddard commented Aug 9, 2014

 So it works but only generates combinations in the same original order - how could you get all combinations in any order?

### ghost commented Aug 18, 2014

 thanks a lot

### skibulk commented Sep 10, 2015

 @chrisgoddard you're looking for a permutations function, not a combinations function.

### danbars commented Sep 28, 2015

 @chrisgoddard you can run each combination through a permutation algorithm with something like this: https://github.com/eriksank/permutation-engine Or, use permutation/combination engine, like this one: https://github.com/dankogai/js-combinatorics

### rhalff commented Feb 23, 2016

 Is the above gist available on npm somewhere? I want to use it in my library, right now I've just copy & pasted it.

### sallar commented Feb 24, 2016

 @danbars Thanks for the links. +1

### foluis commented Aug 5, 2016

 Does Not work for this set "ababb" it repeats elements and also "abbba", "babab" are missing

### ComethTheNerd commented Oct 25, 2016

 @foluis all member elements must be considered unique in order to form a set mathematically

### imVinayPandya commented Mar 31, 2017

 possible combination of 1, 2, 3 are following,may be i am wrong , , , [1, 2], [1, 3], [2, 3], [2, 1], [3, 1], [3, 2], [1, 2, 3], [3, 2, 1]

### douglasFranco commented Apr 2, 2017

 Thanks a lot!

### ragamufin commented May 5, 2017

 Thanks!

### t1mduma5 commented Jul 22, 2017

 @imVinayPandya Looks like he is using N choose K which should only return unique combinations. Such as 1,2 and 2,1 are the same. Also, you are setting the number of members for the k combination. Thus this will only return single member combinations, or double member combinations or triple member combinations etc etc etc.

### regevbr commented Feb 20, 2018

 thanks!

### regevbr commented Feb 20, 2018

 Here is a short hand version using underscore and some es6 syntax for readability ```"use strict"; //https://gist.github.com/axelpale/3118596 const _ = require('underscore'); const elemTransform = elem => [elem]; const tailcombPush = (combs, elem) => tailcomb => combs.push([elem, ...tailcomb]); const k_combPush = combs => k_komb => combs.push(k_komb); function k_combinations(set, k) { const setLen = set.length; if (k > setLen || k <= 0) { return []; } if (k === setLen) { return [set]; } if (k === 1) { return _.map(set, elemTransform); } const combs = []; for (let i = 0; i < setLen - k + 1; i++) { _.each(k_combinations(set.slice(i + 1), k - 1), tailcombPush(combs, set[i])); } return combs; } function combinations(set) { const combs = []; for (let k = 1; k <= set.length; k++) { _.each(k_combinations(set, k), k_combPush(combs)); } return combs; } module.exports = { k_combinations, combinations };```

### morenoh149 commented Feb 28, 2018 • edited

 Here's an es6 version ```const k_combinations = (set, k) => { if (k > set.length || k <= 0) { return [] } if (k === set.length) { return [set] } const combs = [] if (k === 1) { for (let i = 0; i < set.length; i++) { combs.push([set[i]]) } return combs } for (let i = 0; i < set.length - k + 1; i++) { const head = set.slice(i, i + 1) const tailcombs = k_combinations(set.slice(i + 1), k - 1) for (let j = 0; j < tailcombs.length; j++) { combs.push(head.concat(tailcombs[j])) } } return combs } const combinations = (set) => { const combs = []; for (let k = 1; k <= set.length; k++) { const k_combs = k_combinations(set, k) for (let i = 0; i < k_combs.length; i++) { combs.push(k_combs[i]) } } return combs }```

### luispaulorsl commented Nov 5, 2018

 ES6 version: ```const k_combinations = (set, k) => { if (k > set.length || k <= 0) { return [] } if (k == set.length) { return [set] } if (k == 1) { return set.reduce((acc, cur) => [...acc, [cur]], []) } let combs = [], tail_combs = [] for (let i = 0; i <= set.length - k + 1; i++) { tail_combs = k_combinations(set.slice(i + 1), k - 1) for (let j = 0; j < tail_combs.length; j++) { combs.push([set[i], ...tail_combs[j]]) } } return combs } const combinations = set => { return set.reduce((acc, cur, idx) => [...acc, ...k_combinations(set, idx + 1)], []) }```

### cardamon commented Dec 10, 2019 • edited

 And here is a (generic) typescript version, based on the ES6 version by @luispaulorsl: ```export const k_combinations = (set: T[], k: number) => { if (k > set.length || k <= 0) { return []; } if (k === set.length) { return [set]; } if (k === 1) { return set.reduce((acc, cur) => [...acc, [cur]], [] as T[][]); } const combs = [] as T[][]; let tail_combs = []; for (let i = 0; i <= set.length - k + 1; i++) { tail_combs = k_combinations(set.slice(i + 1), k - 1); for (let j = 0; j < tail_combs.length; j++) { combs.push([set[i], ...tail_combs[j]]); } } return combs; }; export const combinations = (set: T[]) => { return set.reduce((acc, _cur, idx) => [...acc, ...k_combinations(set, idx + 1)], [] as T[][]); };```