0

The JavaScript spread operator can combine arrays like this:

const a = [1,2,3];
const b = [4,5,6];
console.log([...a,...b]);

Can I also use it when the number of arguments is unknown at "compile time"?

In the following example I didn't know how to use the spread operator so I used reduce and concat.

const arrays = [[1,2,3],[4,5,6]];
console.log(arrays.reduce((a,b)=>a.concat(b)));

Is this the intended way or can I use the spread operator in some way with a variable number of arguments like those?

Konrad Höffner
  • 11,100
  • 16
  • 60
  • 118

3 Answers3

3

If you don't know how many things you're spreading, you can't write the code to spread them with .... It's just like + in that way: You can add three things together (a + b + c), but if you don't know how many you're adding, you can't directly write the code for it.

Your reduce could use spread rather than concat (but keep reading):

const arrays = [[1,2,3],[4,5,6]];
console.log(arrays.reduce((a,b)=>[...a, ...b]));

But both that and concat are inefficient (which may or may not matter) because they create a new array and re-copy the elements that have already been copied for every input. If efficiency is a constraint, just use a simple loop:

const arrays = [[1,2,3],[4,5,6]];
const result = [];
for (const entry of arrays) {
  result.push(...entry);
}
console.log(result);

Or if you really like doing it in a single expression, you can shoehorn it into a reduce (because basically any array operation can be shoehorned into a reduce):

const arrays = [[1,2,3],[4,5,6]];
console.log(arrays.reduce((acc,entry) => {
  acc.push(...entry);
  return acc;
}, []));

I'm with Brian Terlson, though: For me, reduce is overused.

In closing, for this specific issue, we're getting flat now:

const arrays = [[1,2,3],[4,5,6]];
console.log(arrays.flat());
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

This is the most concise I can think of:

console.log(...[].concat(...arrays));

The innermost spread will give all the arrays as arguments to concat without the need for reduce.

Another way is using the ES2019 Array.prototype.flat:

console.log(...arrays.flat())

EDIT: I just noticed you're outputting it as an array. Change to console.log([].concat(...arrays)) and console.log(arrays.flat()) for that :)

Amadan
  • 191,408
  • 23
  • 240
  • 301
1

You can use array.flat instead, if you don't pass the parameter depth is considered as 1 and you can manually define depth or you can use Infinity to cover any depths

const arrays = [[1,2,3],[4,5,6]];
console.log(arrays.flat());
Code Maniac
  • 37,143
  • 5
  • 39
  • 60