Iterating a two-dimensional array
Iterating a two-dimensional array (a matrix) is one of the basic but genuinely important operations. Because it is an array of arrays, you walk it with nested loops: the outer one over rows, the inner one over columns. Which form you pick depends on whether you need the indexes and whether you have to be able to stop the loop early.
Theory
TL;DR
- A two-dimensional array is traversed with nested loops: outer over rows, inner over the elements of a row.
- A classic
forgives full control and access to theiandjindexes. - Two nested
for...ofloops are the most readable modern option. forEach()hands you the indexes as a second argument, but it cannot be stopped withbreak.flat()turns the matrix into a one-dimensional array when indexes do not matter.reduce()fits aggregation, for example summing every element.
Quick example
Every example below works on this matrix:
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
for (const row of matrix) {
for (const value of row) {
console.log(value); // 1, 2, 3, 4, ... 9
}
}The classic way with for
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
console.log(`matrix[${i}][${j}] = ${matrix[i][j]}`);
}
}iis the row index,jis the column index,matrix[i][j]is the element in rowiand columnj.
Output:
matrix[0][0] = 1
matrix[0][1] = 2
// ...
matrix[2][2] = 9This form gives full control: you can go backwards, skip elements, and leave with break or continue.
for...of and forEach()
for...of iterates over values, so the code is shorter:
for (const row of matrix) {
for (const value of row) {
console.log(value);
}
}The outer for...of goes over rows, the inner one over the elements inside a row. This is the most readable and most modern way to iterate, and you can still stop it with break.
forEach() does the same thing in a functional style and gives you the indexes for free:
matrix.forEach((row, i) => {
row.forEach((value, j) => {
console.log(`matrix[${i}][${j}] = ${value}`);
});
});It needs no manual counter and reads well in functional code, but you cannot break out of it with break or return: a return only ends the current callback call.
flat() when indexes do not matter
If you only need to visit every element in a row, you can flatten the matrix:
matrix.flat().forEach(value => console.log(value));flat() turns a two-dimensional array into an ordinary one-dimensional one:
matrix.flat(); // [1, 2, 3, 4, 5, 6, 7, 8, 9]The downside is that you lose the row and column information, and you allocate a new array in memory.
reduce() for calculations
If you need, for example, the sum of every element:
const sum = matrix.reduce(
(acc, row) => acc + row.reduce((a, b) => a + b, 0),
0
);
console.log(sum); // 45The inner reduce sums one row, the outer one adds the rows together.
Comparing the options
| Way | What it does | Can the loop be stopped |
|---|---|---|
for | Full control, indexes | Yes |
for...of | Simple and readable traversal | Yes |
forEach() | Functional style | No |
flat() plus forEach() | Visits all values as a flat array | No |
reduce() | Aggregation, a sum for example | Yes, logically |
Bottom line: for walking a two-dimensional array,
javascriptfor (const row of matrix) { for (const value of row) { console.log(value); } }is the modern, readable and safe way to do it.
Common mistakes
breakinsideforEach(). That is a syntax error, andreturnonly exits a single callback call. When you need an early exit, usefororfor...of.- One loop instead of two.
matrix.forEach(row => console.log(row))prints arrays, not values; the values need a second level of iteration. - Bounding by
matrix[0].length. On jagged arrays with rows of different lengths this either skips elements or yieldsundefined; usematrix[i].length. for...ininstead offor...of.for...inwalks keys, that is the string indexes"0","1", and it also picks up any own enumerable properties of the array.flat()where coordinates are needed. After flattening there is no way to tell which row a value came from.- Changing the array length while iterating. A
pushorspliceinside the loop shifts the indexes and leads to skipped or repeated elements.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.