1

I have to generate combinations for in array like this:

let arr = []
for(let x=1;x<=10;x++) {
    for(let y=1;y<=12;y++) {
        for(let z=1;z<=16;z++) {
            arr.push([x, y, z])
        }
    }
}

return arr

It correctly generates [[1,1,1], [1,1,2]...[10,12,16]].

However i want to make the code looks and feel better.

I try to convert as pretty as I can and use functional approach (map, reduce and so on).

I tried with 3 maps but the code got uglier.

Try to make the code less characters but without neglecting code readabilty.

Any answer is appreciated and you can use lodash/underscore/ramda if you want to.

  • 1
    What are you trying to achieve? – Nelson Owalo Oct 08 '18 at 11:57
  • 1
    The same result as in the example but with functional code - if its possible with less characters. Basically I want to convert the code similar to Haskell style without loops and so on. If need additional info can explain more –  Oct 08 '18 at 12:00

2 Answers2

2

That is called cartesian product.

You can use ES6 features in order to achieve this: reduce and map methods.

function cartesianProduct(...array) {
      return array.reduce((a, b) =>
        a.map(x => b.map(y => x.concat(y)))
        .reduce((a, b) => a.concat(b), []), [[]]);
}

function firstN(n){
    return Array.from({ length: n }, (_, i) => i + 1)
}
console.log(cartesianProduct(firstN(10), firstN(12), firstN(16)));
Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
  • Good answer, but for me the code is less readable than procedure approach and has more characters. I tried to simplify but could not make it :). Nice answer though –  Oct 08 '18 at 12:05
  • @user2693928, this is confusing. You asked for a functional approach with `map` `reduce` "and so on", and when you get it you say it is less readable... – trincot Oct 08 '18 at 12:06
0

This answer has been taken from this SO answer:

let f = (a, b) => [].concat(...a.map(a => b.map(b => [].concat(a, b))));
let cartesian = (a, b, ...c) => b ? cartesian(f(a, b), ...c) : a;

I think thats what you are looking for

Nelson Owalo
  • 2,324
  • 18
  • 37