← Data structures from scratch · Lesson 4/32
Arrays and indexes
Slots in a row, from 0
An array stores its items next to each other, in numbered slots. The slot's number is its index, and counting starts at 0: the first is arr[0] and the last is arr[arr.length - 1].
Since the slots sit next to each other in memory, reaching slot 7 is just arithmetic: "where the array starts + 7 slots". You don't walk past the earlier ones. That's why reading or writing arr[i] costs O(1), whether the array has ten items or ten million.
$ node leccion.js
Press RUN (or Ctrl+Enter).
What to look at
precios[3]is 21: the fourth item, because counting starts at 0.- You get the last one with
length - 1, notlength. - Changing slot 1 didn't move anything else.
The whole lesson on one page
Slots in a row, from 0
An array stores its items next to each other, in numbered slots. The slot's number is its index, and counting starts at 0: the first is arr[0] and the last is arr[arr.length - 1].
Since the slots sit next to each other in memory, reaching slot 7 is just arithmetic: "where the array starts + 7 slots". You don't walk past the earlier ones. That's why reading or writing arr[i] costs O(1), whether the array has ten items or ten million.
const precios = [12, 5, 8, 21, 3];
console.log(precios[0]); // the first
console.log(precios[3]); // the fourth
console.log(precios[precios.length - 1]); // the last
precios[1] = 6; // writing is O(1) too
console.log(precios);
precios[3]is 21: the fourth item, because counting starts at 0.- You get the last one with
length - 1, notlength. - Changing slot 1 didn't move anything else.
Outside the array
What happens if you ask for a slot that doesn't exist? In C or Java that's a serious error (or worse: reading garbage from memory). JavaScript is more relaxed and hands you undefined, silently. Convenient, but it hides bugs: an index that's off by one gives undefined and the program keeps going as if nothing happened.
The most common array bug has a name: off by one. A loop with i <= arr.length takes one turn too many and reads the slot that isn't there.
const dias = ["lun", "mar", "mié"];
console.log(dias[3]); // doesn't exist
console.log(dias[-1]); // neither: no counting from the end
console.log(dias.at(-1)); // at() does count from the end
// The off-by-one bug: <= takes one extra turn
for (let i = 0; i <= dias.length; i++) {
console.log(i, dias[i]);
}
dias[3]anddias[-1]giveundefined, no error.at(-1)is the modern way to ask for the last one.- The loop's last turn prints
3 undefined: that's the extra turn.
Grids: arrays of arrays
A board, a map or a spreadsheet is an array of rows, and each row is another array. You read it with two indexes: first the row (y), then the column (x): grid[y][x].
That's how Daily Challenge's Snake stores its walls: an array of 17 rows with 16 cells each, true where there's a wall. Checking whether a cell is free is one O(1) read.
-
xwall
const mapa = [
"xxxxxx",
"x....x",
"x.xx.x",
"x....x",
"xxxxxx",
];
// From text to a grid of booleans: true = wall
const muros = mapa.map(fila => [...fila].map(c => c === "x"));
console.log(muros.length, "rows,", muros[0].length, "columns");
console.log(muros[2][2]); // row 2, column 2
console.log(muros[1][2]); // row 1, column 2
- 5 rows of 6 columns.
muros[2][2]istrue: row 2 has a wall in the middle.muros[1][2]isfalse: open floor. Order matters: row first, column second.