Nested Arrays and flat()

JavaScript ES2024 · ✓ verified by execution on 2026-08-13

Arrays in JavaScript are versatile. They can hold numbers, strings, and even other arrays. An array that contains other arrays is called a nested array or a multidimensional array.

These are extremely useful for representing grids, matrices, or any data with multiple dimensions—like a spreadsheet or a chess board.

Accessing Nested Arrays

You can access elements within nested arrays by chaining bracket notation [][]. The first set of brackets selects the inner array, and the second set selects the item inside it.

javascript
const grid = [
  [1, 2],
  [3, 4]
];

// Accessing the second element of the first array
console.log(grid[0][1]);
Output
2

Because inner arrays are just regular arrays, you can loop over a 2D array using nested loops. Step through the execution of this nested loop to see how row and col change:

javascript · visualize
const grid = [
  [1, 2],
  [3, 4]
];

for (let row = 0; row < grid.length; row++) {
  for (let col = 0; col < grid[row].length; col++) {
    console.log(`grid[${row}][${col}] = ${grid[row][col]}`);
  }
}

The Reference Trap (Bug Hunt Preview)

A common mistake when dynamically creating grids is using Array.fill().

Predict the output javascript

Read the code. What exactly will it print? Commit to an answer before you look.

const grid = Array(2).fill([]);

grid[0].push("X");
console.log(grid);
Output
[ [ 'X' ], [ 'X' ] ]

You might expect only the first array to get the "X". Instead, fill() evaluates the [] just once and copies that exact same memory reference into every slot. When you modify one, you modify them all! To fix this, you will need to generate independent arrays, such as by using Array.from() (as you will see in the challenge).

Flattening Arrays with flat()

Sometimes you receive a nested array, but you actually just need a single, flat list of all the values. That is where flat() comes in.

javascript
const arr = [1, [2, 3], 4];
const flatArr = arr.flat();

console.log(flatArr);
Output
[ 1, 2, 3, 4 ]

The flat() method returns a brand new array with all sub-array elements concatenated into it recursively up to a specified depth. It does not mutate the original array. By default, it flattens exactly one level deep.

javascript
const deepArr = [1, [2, [3, [4]]]];

console.log(deepArr.flat());
console.log(deepArr.flat(2));
Output
[ 1, 2, [ 3, [ 4 ] ] ]
[ 1, 2, 3, [ 4 ] ]

To flatten a deeply nested array of unknown depth completely, you can pass Infinity:

javascript
const deepestArr = [1, [2, [3, [4]]]];
console.log(deepestArr.flat(Infinity));
Output
[ 1, 2, 3, 4 ]

Removing Empty Slots

An interesting edge case is that flat() will automatically remove empty slots (holes) in sparse arrays:

javascript
const sparse = [1, 2, , 4, 5];
console.log(sparse.flat());
Output
[ 1, 2, 4, 5 ]

Visualizing 2D Arrays

To understand how elements are laid out in a nested array, think of the outer array as rows and the inner arrays as columns.

Nested Array: grid[row][col] [0][0] [0][1] [0][2] [1][0] [1][1] [1][2]
A two-dimensional array addressed as grid[row][col]: the first index selects the inner array, the second selects a position inside it.

Check yourself

What does the array.flat() method do?

Reveal answer

Creates a new array with all sub-array elements concatenated into it up to a specified depth — The flat() method returns a new array with sub-array elements concatenated into it recursively up to a specified depth. It does not mutate the original array.

What happens if you initialize a grid with Array(3).fill([]) and push an item to the first inner array?

Reveal answer

All three inner arrays receive the item — Array.fill() evaluates the argument once and assigns that exact same reference to every index. Modifying one inner array modifies them all.

By default, how deep does the flat() method flatten an array?

Reveal answer

It flattens only 1 level deep — By default, flat() has a depth of 1, meaning it only flattens the immediate sub-arrays.

Challenges

Challenge 1 +15 XP

Use `flat()` to completely flatten the deeply nested array.

javascript
  • Test 1 — expects "[ 1, 2, 3, 4, 5 ]"
Need a hint? (−25% XP)

You can use `Infinity` as the depth to flatten any depth of nested arrays.

Show solution (0 XP)
const data = [1, [2, [3, [4, 5]]]];
const flatData = data.flat(Infinity);
console.log(flatData);

🐞 Bug Hunt +25 XP

This code tries to create a 3x3 grid of zeroes, but setting the first cell sets the whole column! Fix the initialization so that `grid[0][0] = 1` only changes the very first cell.

This code runs. It just does the wrong thing. Read it, find the defect, fix it — the tests below decide when you are right.

javascript
  • Test 1 — expects "[ [ 1, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ]"
Need a hint? (−25% XP)

`Array.fill()` puts the *same* array reference in every slot. Use `Array.from()` with a mapping function to create fresh arrays for each row.

Show solution (0 XP)
const grid = Array.from({length: 3}, () => [0, 0, 0]);
grid[0][0] = 1;
console.log(grid);