Ya dominas lo basico de .map(), .filter() y .reduce(). Ahora toca subir el nivel: vamos a trabajar con arrays de objetos, transformaciones multi-paso y combinaciones de metodos. Estos ejercicios te preparan para el lab avanzado y para problemas reales que encontraras en cualquier proyecto.
________________________________________
/ Ya sabes map, filter y reduce. \
| Ahora toca combinarlos como un |
\ verdadero ironhacker. /
----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
- Usar
.map()para transformar arrays de objetos (no solo primitivos) - Usar
.filter()con condiciones sobre propiedades de objetos y busquedas parciales - Usar
.reduce()para construir objetos, calcular promedios y encontrar maximos - Encadenar dos o mas metodos de array para resolver problemas complejos
- Practicar TDD: escribir codigo hasta que los tests pasen
- Haber completado el mini-lab basico de Map, Filter & Reduce
- Conocer la sintaxis de objetos en JavaScript
- Entender
.split(),.join(),.toUpperCase(),.toLowerCase(),.includes()
- Haz fork de este repo y clonalo en tu maquina
- Abre
index.htmlen el navegador — veras Jasmine con todos los tests en rojo - Trabaja en
src/functions.jscompletando las funciones - Cada vez que guardes, recarga el navegador para ver si tus tests pasan
💡 Consejo: no intentes resolver todas a la vez. Ve iteracion por iteracion.
⚠️ Importante: no modifiques los tests. Si un test falla, el problema esta en tu funcion, no en el test.
mini-lab-js-map-filter-reduce-intermediate/
├── index.html ← SpecRunner (abre esto en el navegador)
├── src/
│ └── functions.js ← Aqui escribes tu codigo
└── tests/
└── functions.spec.js ← Tests (NO modificar)
Ya sabes que .map() transforma cada elemento de un array. Ahora vamos a transformar objetos y crear nuevas propiedades.
var result = array.map(function (element) {
return // ... transformacion del elemento
});Completa: celsiusToFahrenheit, addFullName, getAcronyms, applyDiscount
Pistas
- celsiusToFahrenheit:
.map()con la formulatemp * 9 / 5 + 32 - addFullName:
.map()creando un nuevo objeto con spread (Object.assigno copia manual) y anadiendofullName: firstName + " " + lastName. Recuerda: no modifiques el objeto original - getAcronyms:
.map()sobre las frases, dentro.split(" ")para obtener las palabras, luego.map()para sacar la primera letra,.join("")y.toUpperCase() - applyDiscount:
.map()creando un nuevo objeto conoriginalPriceigual al precio original ypricecon el descuento aplicado:price * (1 - discount / 100)
.filter() devuelve un nuevo array con los elementos que cumplen una condicion. Ahora vamos a filtrar con condiciones mas interesantes: propiedades de objetos, busquedas parciales y rangos.
var result = array.filter(function (element) {
return // ... condicion booleana
});Completa: getInStock, getUniqueValues, searchByName, getInRange
Pistas
- getInStock:
.filter()conproduct.stock > 0 - getUniqueValues:
.filter()comparandoarray.indexOf(element) === index— si la primera posicion donde aparece el elemento es la posicion actual, es unico - searchByName:
.filter()con.toLowerCase().includes(query.toLowerCase()) - getInRange:
.filter()connum >= min && num <= max
.reduce() acumula todos los valores de un array en uno solo. Pero ese "uno solo" puede ser un numero, un string, un objeto, o incluso otro array. Aqui practicaras los tres primeros.
var result = array.reduce(function (acc, element) {
return // ... nuevo valor del acumulador
}, valorInicial);Completa: getLongestString, buildObject, calculateAverage, mergeObjects
Pistas
- getLongestString: compara
acc.lengthconelement.length, devuelve el mas largo. Puedes usarreducesin valor inicial (empieza con el primer elemento) - buildObject: reduce sobre el array de keys, usando el index para acceder al valor correspondiente en values:
keys.reduce(function (acc, key, index) { ... }, {}) - calculateAverage: primero comprueba si el array esta vacio (devuelve 0). Si no, usa
.reduce()para sumar y divide por.length - mergeObjects: reduce con valor inicial
{}, usaObject.assign(acc, obj)o copia las propiedades manualmente
Ahora viene lo divertido: encadenar .filter(), .map() y .reduce() para resolver problemas en un solo flujo. Piensa siempre en los pasos: primero seleccionar (filter), luego transformar (map), y finalmente acumular (reduce).
var result = array
.filter(function (el) { return /* seleccionar */ })
.map(function (el) { return /* transformar */ })
.reduce(function (acc, el) { return /* acumular */ }, valorInicial);Completa: getTopStudents, getTotalCartPrice, getWordFrequencies
Pistas
- getTopStudents:
.filter()porgrade >= minGrade, luego.map()formateando comolastName.toUpperCase() + ", " + firstName - getTotalCartPrice:
.map()para calcularprice * quantityde cada item, luego.reduce()para sumar. O directamente.reduce()acumulandoacc + item.price * item.quantity - getWordFrequencies:
.split(" ")para separar en palabras →.map()con.toLowerCase()→.reduce()para contar en un objeto{ word: count }→Object.keys()para convertir a array de{ word, count }→.sort()por count descendente. Cuidado con el string vacio:.split(" ")devuelve[""], asi que filtra primero
Cuando todo este completo, Jasmine mostrara: 58 specs, 0 failures
Happy coding! ❤️