STAR Summary
S — I was studying Block 2 (Arrays) from my Notebook 1. I had 32 progressive exercises ready (without solutions). I had recently learned map(), filter(), reduce() from Jonas Schmedtmann, but only theoretically. I needed to practice without "cheating."
T — Do maximum 15-20 exercises in one session, from simple (access, push, pop) to complex (reduce, chaining, spread, destructuring). Goal: understand the PATTERN, not memorize.
A — I worked in thematic blocks:
- Level 1 (1.1–1.6): Access, mutating methods (push, pop, shift, unshift) — quick, no problems
- Level 2 (2.1–2.6): Non-mutating methods (map, filter, find, includes, slice, forEach) — some blockages (2.3, 2.6)
- Level 3 (3.1–3.3): reduce() — the hardest, but I did it
- Level 4 (4.1–4.3): Chaining — data type errors, learned to fix them
- Level 5 (5.1–5.5): Spread and destructuring — new territory, caught on quickly
R — Completed 18 exercises without solutions. Mastered: array access, mutating/non-mutating methods, forEach, reduce (with accumulator), chaining, spread operator, basic destructuring. Still need: automate reduce(), callbacks with objects in arrays, advanced destructuring.
Wins of the day
+
Mastered .map() and .filter() — understood the difference (transform vs select)
+
reduce() stopped being "the dark beast" — now I see accumulator + callback as a pattern
+
Learned to fix errors (NaN, undefined) by analyzing what data I had at each step
+
Method chaining — .filter().map().reduce() in one line
+
Spread operator and destructuring — new syntax, caught it quickly
"The logic wasn't wrong, it was the syntax. That's real learning — see the error, analyze it, fix it."
Skill levels at end of day
Mutating Methods (push, pop, shift, unshift)
95%
Non-mutating (.map, .filter, .find, .includes)
85%
reduce() — accumulation
70%
Spread operator & destructuring
75%
Debug Log
✗
Bug 1 (Exercise 2.1 .map()): I wrote numeros.map(num => numeros.num) — tried to access a property that didn't exist. I thought numeros.num was the element.
→
Fix 1: num IS ALREADY the element. I don't need to go back to the array. Should be num => num * 2. Key pattern: inside the callback, the parameter is the data.
✗
Bug 2 (Exercise 2.3 .find() with objects): I wrote usuarios.find(id => id === 2) — the parameter was an OBJECT, not a number. Blocked for 15 minutes.
→
Fix 2: Should be usuarios.find(obj => obj.id === 2). The callback receives objects from the array. I need to access obj.id to get to the number.
✗
Bug 3 (Exercise 2.6 .forEach()): I tried to save the result of .forEach() in a variable. I wrote const iteracion = numeros.forEach(...) and then console.log(iteracion).
→
Fix 3: .forEach() returns nothing (returns undefined). It only executes. The console.log must be INSIDE the callback, not outside.
✗
Bug 4 (Exercise 3.2 .reduce() count): I wrote palabras.reduce((acc, num) => acc + num.length, 0) — summed word lengths instead of counting how many there were.
→
Fix 4: To count, it's not acc + num.length, it's acc + 1. Each iteration adds 1, not the length. I misinterpreted "count" vs "sum lengths".
✗
Bug 5 (Exercise 4.2 map + reduce with objects): After .map() I had an array of NUMBERS [2, 1, 3], but in .reduce() I wrote (acc, obj) => acc + obj.precio — obj was a number, not an object.
→
Fix 5: After each method, the data type CHANGES. .map() converts objects to numbers. So in .reduce() after .map(), the parameter is a number, not an object. I must think about what each step returns.
✗
Bug 6 (Exercise 5.2 spread - join arrays): I wrote const union = [...arr1] + [...arr2] — used + to "add" arrays.
→
Fix 6: + with arrays concatenates as strings: "1,2,34,5,6". For arrays, I need [...arr1, ...arr2] (spread inside brackets).
✗
Bug 7 (Exercise 5.3 destructuring): I did normal access const c1 = colores[0] instead of destructuring.
→
Fix 7: Destructuring is const [c1, c2, c3] = colores. It's cleaner than individual access. New concept but caught it quickly.
✗
Bug 8 (Exercise 5.5 destructuring in parameters): I wrote ({nombre, edad}) => console.log(`${nombre.nombre} tiene ${edad.edad}`) — accessed the object again when it was already destructured.
→
Fix 8: When using destructuring in parameters, I already have the values extracted. It's not nombre.nombre, just nombre. The parameter IS ALREADY the value.
✓
Final result: 18 exercises completed. Mastered methods, reduce(), chaining, spread, destructuring. Still need: automate reduce() and callbacks with objects.
Code of the day
// The pattern that was hardest to understand:
// Callbacks receive the ELEMENT, not the array
// ❌ WRONG (what I did many times):
usuarios.map(usuario => usuario.usuarios.nombre)
productos.reduce((acc, prod) => acc + prod.productos.precio, 0)
// ✅ RIGHT (what I learned):
usuarios.map(usuario => usuario.nombre)
productos.reduce((acc, prod) => acc + prod.precio, 0)
// The parameter (usuario, prod) IS ALREADY the object.
// I don't need to go back to the original array.
// Chaining — the flow:
const resultado = estudiantes
.filter(est => est.calificacion >= 8) // objects
.map(est => est.nombre) // strings
.length // number
// Each step transforms the data type.
// Spread vs +
const arr1 = [1, 2];
const arr2 = [3, 4];
arr1 + arr2 // "1,23,4" (string, WRONG)
[...arr1, ...arr2] // [1, 2, 3, 4] (array, RIGHT)
// Destructuring — the new thing
const [a, b, ...resto] = [1, 2, 3, 4, 5]
// a = 1, b = 2, resto = [3, 4, 5]
"The most common error: confusing the callback parameter (the element) with the original array. Inside a callback, the parameter IS ALREADY what you need."