What a matrix is
| col 0 | col 1 | col 2 | col 3 | |
|---|---|---|---|---|
| row 0 | 1 | 2 | 3 | 4 |
| row 1 | 5 | 6 | 7 | 8 |
| row 2 | 9 | 10 | 11 | 12 |
m[r][c]means rowr, then columnc.m[1]grabs the whole second row[5, 6, 7, 8];m[1][2]then picks index 2 inside it:7. Row before column, always.- Dimensions come from two different lengths.
m.lengthis the number of rows (3);m[0].lengthis the number of columns (4). Grids are not always square. - Indices start at 0, same as arrays — because a row is an array.
Quick check
In the grid above, what is m[1][2]?
Answer it in the interactive lesson to keep your progress.
The core operations
m as the 3×4 grid from above:- Read a cell:
m[1][2]→7. Write the same way:m[1][2] = 99. - Walk a row: fix
r, movec.m[1][0],m[1][1],m[1][2],m[1][3]→5, 6, 7, 8. - Walk a column: fix
c, mover.m[0][2],m[1][2],m[2][2]→3, 7, 11. - Sum a row by walking it with a running total:
5 + 6 + 7 + 8 = 26, one value at a time.
This section has a step-by-step animation in the interactive lesson.
const m = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
];
console.log(m.length); // 3
console.log(m[0].length); // 4
console.log(m[1][2]); // 7
let rowSum = 0;
for (let c = 0; c < m[1].length; c++) {
rowSum += m[1][c];
}
console.log(rowSum); // 26Quick check
You want to print column 0 of the grid (1, 5, 9). Which loop does it?
Answer it in the interactive lesson to keep your progress.
Your first matrix problem: transpose
r becomes column r. It is the gentlest real grid problem — and half of the famous rotate image interview question.m[r][c] and its mirror m[c][r] simply trade places, and the diagonal (m[0][0], m[1][1], …) never moves. On [[1,2,3],[4,5,6],[7,8,9]], pair by pair:| pair | values | after the swap |
|---|---|---|
| m[0][1] ↔ m[1][0] | 2 ↔ 4 | row 0 = [1, 4, _], row 1 = [2, 5, _] |
| m[0][2] ↔ m[2][0] | 3 ↔ 7 | row 0 = [1, 4, 7], row 2 = [3, _, _] |
| m[1][2] ↔ m[2][1] | 6 ↔ 8 | row 1 = [2, 5, 8], row 2 = [3, 6, 9] |
c = r + 1, covering only the pairs above the diagonal. Loop over every cell instead and each pair swaps twice — landing everything right back where it started. Watch the pairs trade places in the animation.This section has a step-by-step animation in the interactive lesson.
function transpose(sq) {
for (let r = 0; r < sq.length; r++) {
for (let c = r + 1; c < sq.length; c++) {
[sq[r][c], sq[c][r]] = [sq[c][r], sq[r][c]];
}
}
return sq;
}
console.log(JSON.stringify(transpose([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))); // [[1,4,7],[2,5,8],[3,6,9]]Where it breaks
- Swapped indices.
m[c][r]instead ofm[r][c]still works on a square grid — it just reads the mirrored cell. On a 3×4 grid it crashes only sometimes, which is worse. Say "row, then column" out loud as you type. - Assuming square. Using
m.lengthfor both dimensions works until the first rectangular input. Rows =m.length, columns =m[0].length— two different numbers. - The shared-row trap.
new Array(3).fill([])puts the same array object in all three slots — write to one row and every row changes. Build rows withArray.from, which runs the row-maker once per row. - Transposing every pair. Looping the full grid swaps each pair twice — the matrix ends up exactly where it started (the checkpoint below makes you prove it).
const bad = new Array(2).fill([0, 0]);
bad[0][0] = 9;
console.log(JSON.stringify(bad)); // [[9,0],[9,0]]
const good = Array.from({ length: 2 }, () => [0, 0]);
good[0][0] = 9;
console.log(JSON.stringify(good)); // [[9,0],[0,0]]Quick check
In transpose, the inner loop runs c from r + 1 upward. What happens if it runs from 0 instead?
Answer it in the interactive lesson to keep your progress.
How fast is it? (complexity)
| Operation | Time | Why |
|---|---|---|
| Read / write one cell | O(1) | Two index jumps |
| Walk one row or column | O(c) or O(r) | One index moves |
| Touch every cell (any order) | O(r · c) | Nested loops, one visit each |
| Transpose in place | O(n²) for n×n | Half the cells swap, still quadratic |
m[r][c]— row first, then column; fix one index and move the other to walk lines.- Rows =
m.length, columns =m[0].length— never assume square. - Build grids with
Array.from, nevernew Array(n).fill([]). - Every-cell work costs
O(rows × cols)— multiply, don't add.