Appending to an array within an array
Jia Yi ยท 12 January 2022
2 min read
You may come across the need to create an array filled with X number of an array and update it subsequently.
Creating an array of objects
Using ES6 notation
const menu = [...Array(2)].map(() => []);
const menu = Array.from([...Array(2)], () => []);
Good ol' for-loop
const menu = [];
for (let i = 0; i < 2; i++) menu.push([]);
Avoid Array.fill
Do NOT use fill ๐ โโ๏ธ when working with objects.
const menu = new Array(2).fill([]); // More on why later on.
Updating array values
You can update the nested array values like how you would update an array.
const menu = [...Array(2)].map(() => []);
menu[0].push("๐");
menu[1].push("๐");
menu; // [ [ '๐' ], [ '๐' ] ]
menu[0][0] = "๐ฎ";
menu; // [ [ '๐ฎ' ], [ '๐' ] ]
Note that...
Be cautious when working with objects. Know whether you need to make a shallow or a deep clone for a nested object.
Why Array.fill should not be used for objects
If you had assigned the variable with Array.fill:
const menu = [...Array(2)].map(() => []);
const menu2 = new Array(2).fill([]);
menu[0].push("๐");
menu2[0].push("๐");
menu[1].push("๐");
menu2[1].push("๐");
menu[0][0] = "๐ฎ";
menu2[0][0] = "๐ฎ";
menu; // [ [ '๐ฎ' ], [ '๐' ] ] // โ๏ธ Correct
menu2; // [ [ '๐ฎ', '๐' ], [ '๐ฎ', '๐' ] ] // โ Wrong!
Blimey! What happened?
It turns out fill would result in every element referencing the same object (array).
Array.fill will work just fine for Primitive.
const menu = [...Array(2)].map(() => false);
const menu2 = new Array(2).fill(false);
menu[0] = true;
menu2[0] = true;
menu; // [ true, false ] // โ๏ธ Correct
menu2; // [ true, false ] // โ๏ธ Correct
If somehow you must use Array.fill,
You could use concat or splice as both return a new array.
const menu = new Array(2).fill([]);
menu[0] = menu[0].concat("๐");
menu[1].splice(0, 0, "๐");
menu; // [ [ '๐' ], [ '๐' ] ] โ๏ธ Correct
menu[0][0] = "๐ฎ";
menu; // [ [ '๐ฎ' ], [ '๐' ] ] โ๏ธ Correct