Javascript code:
const bigArray2 = [
[1, 2, 3],
[2, 4, 6],
[3, 6, 9],
];
//creates single-layer array containing all elements of every array within bigArray2
const combinedArray = bigArray2.reduce((accumulated, current) => {
for (element of current) {
accumulated.push(element);
}
return accumulated;
});
console.log(combinedArray);
// outputs [ 1, 2, 3, 2, 4, 6, 3, 6, 9 ] as intended
console.log(bigArray2);
// outputs [ [ 1, 2, 3, 2, 4, 6, 3, 6, 9 ], [ 2, 4, 6 ], [ 3, 6, 9 ] ]
Somehow bigArray2[0] is assigned a value of combinedArray. How and why? .reduce() is not supposed to change the original array
2
Answers
You’re not passing an initial value to your
reduce()
function.As noted on MDN:
When you then modify your
accumulator
, you’re actually modifying the first value of your input array, in this case[1, 2, 3]
. Note that the original array indeed does remain unchanged. After thereduce()
operation, the original array still contains the same 3 elements, i.e. the same 3 references to its sub-arrays. It’s just that by not passing an initial value, your logic ends up modifying the contents of the first of those sub-arrays.To fix, initialize your accumulator with an empty array (
[]
):It is perfectly possible for
.reduce()
to change the original array; it is more about what you do within your callback that determines whether the original array is changed or not.In your case, since you’re omitting the second argument to
.reduce()
(ie: the initial value),.reduce()
will first call your callback with an accumulator set to the first item in your array. In this case, that references your first array, ie:[1, 2, 3]
. As a result, since you keep on returning this same array reference value from your.reduce()
callback you end up with all the values being pushed to the first array.To fix this, you can provide an empty array as an initial value, this way your callback will be initially called with the empty array as the accumulator, thus modifying that rather than your first element:
As a side note, a task like this is better done with
.flat()
: