-5

I'm using node.js currently, and i would like to find / try all the unique possibilities resulting from the combinations of data stored in an array.

Example :

// source array
var array = [0,1,2];

// what i need :
0
1
2
00
01
02
10
11
12
20
21
22
000
001
002
etc, up to a configurable length.

I've looked on the forums and didn't manage to find something like this.

I've searched on npm and found some librairies that are doing similar things, but never all the possibilities i need. I'm feeling like my need is very similar to a bubble sorting algorithm, but i don't know how to do this.

Also it would be very much better to do it without storing the whole output in a variable at the same time, as the idea is that my code needs to work with larger arrays.

Any idea or solution i missed would help at this point !

Edit : Also, i would like to continuously try combination until i decide it's enough, such as 500 try or if the last combination length is 5 for example.

NoxWorld
  • 13
  • 1
  • 6
  • 4
    What do you have so far? How can we be of assistance? – Igor Dimchevski Feb 20 '18 at 15:22
  • Possible duplicate of [Javascript - Generating all combinations of elements in a single array (in pairs)](https://stackoverflow.com/questions/43241174/javascript-generating-all-combinations-of-elements-in-a-single-array-in-pairs) – Reed Feb 20 '18 at 15:27
  • Sorry, i've posted too fast, was trying to put the tags and accidentally put enter... I made a few tries with a foreach loop and ended up with a code very similar to a bubble sorting. But that's just not enough because i would need to check all the possibilities of the array with some kind of limit (let's say after X combination we stop, or if the combination length is above Y). – NoxWorld Feb 20 '18 at 15:27
  • Depending what it is you want to do with the results, you might find [`yield`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield) helpful. – JDB Feb 20 '18 at 15:29
  • You're looking for some kind of recursive algorithm. Possible duplicate of: https://stackoverflow.com/questions/29650834/using-recursion-to-search-all-combinations-of-elements-in-an-array-of-integers – mbrandau Feb 20 '18 at 15:38
  • Is there a reason you don't include `012` in the results? – Scott Sauyet Feb 20 '18 at 15:38
  • @scottSauyet No , i just forgot the 0xx ... The point is that i need absolutely every unique combination of the array, one by one , up to a result of X length. I will edit my question to add the 0xx results, thanks for noticing, i actually managed to fail my question ... – NoxWorld Feb 20 '18 at 15:44
  • 1
    @mbrandau Yes this seems to be very similar, except that i will work with characters too. I will investigate this post, i didn't see it when i was looking. Thanks for your help ! – NoxWorld Feb 20 '18 at 15:48

2 Answers2

0
function variations(arr, length) {
    if (length == 0)
        return [];
    else if (length == 1)
        return arr.map(e => e.toString());

    let result = [];
    for (let i = 0; i < arr.length; i++) {
        for (let tail of variations(arr, length - 1))
            result.push(arr[i].toString() + tail);
    }
    return result;
}

function variations2(arr, maxLength) {
    let result = [];
    for (let i = 0; i <= maxLength; i++)
        result = result.concat(variations(arr, i));
    return result;
}

Example:

var array = [0,1,2];
console.log(variations2(array, 2));

Output:

["0", "1", "2", "00", "01", "02", "10", "11", "12", "20", "21", "22"]
krisz
  • 2,686
  • 2
  • 11
  • 18
  • Note that `permute` is probably not a good name for this, as that implies that there are n! results, and that the values are each used only once per output. – Scott Sauyet Feb 20 '18 at 16:26
0

Another approach, with several reusable functions:

const flatten = arrays => [].concat.apply([], arrays);
const range = (lo, hi) => [...new Array(hi - lo + 1)].map((_, i) => i + lo)
const join = joiner => list => list.join(joiner)

const charSeqs = (n, chars) => (n < 1) 
    ? [[]]
    : flatten(chars.map(char => charSeqs(n - 1, chars).map(
        seq => flatten([char].concat(seq))
      )))

const allCharSeqs = (n, chars) => flatten(range(1, n).map(i => charSeqs(i, chars)))

console.log(allCharSeqs(3, [0, 1, 2]).map(join('')))
Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103