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.

2
  • 1
    What are you trying to achieve? Commented Oct 8, 2018 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 Commented Oct 8, 2018 at 12:00

2 Answers 2

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)));

Sign up to request clarification or add additional context in comments.

2 Comments

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
@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...
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

3 Comments

Instead of answering you should really refer the OP to the original answer via a comment and close-vote.
@trincot I did mark the question as a dublicate
I don't see you did that (with the "close" button), but the more important thing is: don't answer in that case.