← Data structures from scratch · Lesson 5/32
Walking, adding and removing
Walking through
Walking an array means visiting each slot once: O(n). In JavaScript there are two forms you'll use all the time:
for (let i = 0; i < arr.length; i++)when you need the index.for (const x of arr)when you only care about the value.
Looking for a value without knowing where it is is also a walk: indexOf and includes check slot by slot until they find it. That's linear search, O(n) in the worst case.
$ node leccion.js
Press RUN (or Ctrl+Enter).
What to look at
- The first loop gives index and value; the second, just the value.
indexOfreturns-1when it doesn't find it: to know that, it had to check all four slots.
The whole lesson on one page
Walking through
Walking an array means visiting each slot once: O(n). In JavaScript there are two forms you'll use all the time:
for (let i = 0; i < arr.length; i++)when you need the index.for (const x of arr)when you only care about the value.
Looking for a value without knowing where it is is also a walk: indexOf and includes check slot by slot until they find it. That's linear search, O(n) in the worst case.
const tianguis = ["jitomate", "cebolla", "chile", "aguacate"];
for (let i = 0; i < tianguis.length; i++) {
console.log(i, tianguis[i]);
}
for (const cosa of tianguis) {
console.log(cosa.toUpperCase());
}
console.log(tianguis.indexOf("chile")); // where it is
console.log(tianguis.indexOf("mango")); // -1: not there
console.log(tianguis.includes("mango"));
- The first loop gives index and value; the second, just the value.
indexOfreturns-1when it doesn't find it: to know that, it had to check all four slots.
The end is cheap; the front is expensive
push adds at the end and pop removes from the end: nobody has to move, so they cost O(1).
unshift adds at the front and shift removes from the front. Since the slots are contiguous and numbered, everyone else has to shift one place to open or close the gap: O(n). splice, which adds or removes in the middle, also shifts everything behind it.
The program times each one with 20,000 items.
function medir(nombre, hacer) {
const arr = [];
const t0 = Date.now();
for (let i = 0; i < 20000; i++) hacer(arr, i);
console.log(nombre, Date.now() - t0, "ms");
}
medir("push ", (a, i) => a.push(i));
medir("unshift", (a, i) => a.unshift(i));
const letras = ["a", "b", "c", "d"];
letras.splice(1, 2); // from 1, remove 2
console.log(letras);
letras.splice(1, 0, "x"); // from 1, remove 0 and insert "x"
console.log(letras);
unshifttakes many times longer thanpushfor the same count: each one shifts everyone already there. (The milliseconds change from run to run; the gap doesn't.)splice(start, howMany, ...newItems)removes and inserts in the middle.
map, filter and reduce
Three walks so common they have their own names. All three return something new and leave the original alone:
map(f): an array of the same size, withfapplied to each item.filter(f): only the items for whichfreturnstrue.reduce(f, initial): folds everything into a single value, like a sum.
They're still O(n): loops written another way.
const precios = [20, 45, 12, 80];
const conIva = precios.map(p => p * 1.16);
console.log(conIva);
const baratos = precios.filter(p => p < 30);
console.log(baratos);
const total = precios.reduce((suma, p) => suma + p, 0);
console.log(total);
console.log(precios); // the original didn't change
mapgives four prices with 16 % tax (with ugly decimals: that's floating point for you).filterkeeps 20 and 12.reducestarts at 0 and keeps adding: 157.