Los arrays traen su propia caja de herramientas
Los arrays en JavaScript vienen con un montón de métodos integrados. Casi todo lo que resolverías con un bucle for —transformar valores, quedarte con algunos, sumarlos— ya tiene un método que lo hace en una línea, se lee mejor y encaja de forma natural con otros.
El kit básico son tres métodos de array en JavaScript: map, filter y reduce. Domínalos junto con unos pocos primos cercanos, y ese código lleno de bucles se reduce a algo que entiendes de un vistazo.
Cada método recibe un callback y devuelve algo. Ninguno modificó nums: es una idea que conviene interiorizar cuanto antes.
map: transformar cada elemento
map recibe una función y la ejecuta sobre cada elemento, juntando los valores devueltos en un nuevo array del mismo tamaño. Úsalo cuando quieras "una salida por cada entrada".
El callback también recibe el índice como segundo argumento por si lo necesitas: arr.map((item, i) => ...). Si no lo usas, simplemente ignóralo.
Un error muy común: tirar de map cuando en realidad no te hace falta el array de vuelta. Si solo quieres imprimir cada elemento o guardarlo en una base de datos, lo suyo es un forEach o un bucle de toda la vida.
filter: quedarte solo con lo que cumple la condición
filter ejecuta un predicado —una función que devuelve true o false— sobre cada elemento y conserva aquellos en los que el resultado es truthy. El array resultante tiene la misma longitud o menos.
map y filter se encadenan de forma natural. Lee la cadena como si fuera una tubería, de principio a fin:
Primero filter, después map: así map solo se ejecuta sobre los que sobrevivieron al filtro.
reduce: reducir un array a un solo valor
reduce es el más versátil de los tres. Le pasas una función reductora (acumulador, item) => nuevoAcumulador y un valor inicial. Recorre el array elemento por elemento, pasándole cada uno a la función junto con el acumulador actual, y al final te devuelve el acumulador resultante.
El resultado no tiene por qué ser un número. Puede ser un objeto, otro array, una cadena... lo que necesites ir construyendo:
Pasa siempre el valor inicial (el segundo argumento). Si no lo haces, reduce toma el primer elemento como acumulador de partida, lo que falla con arrays vacíos y muchas veces ni siquiera hace lo que tú esperas.
reduce es potente, pero puede volverse difícil de leer cuando la lógica se enreda. Si tu reducer ocupa más de unas pocas líneas, un simple bucle for...of suele ser mucho más claro.
forEach: efectos secundarios, sin valor de retorno
forEach es como map, pero sin el array de salida. Está pensado para cuando quieres hacer algo con cada elemento —imprimirlo por consola, llamar a una API, actualizar el DOM— y no necesitas una colección nueva.
Dos cosas que conviene saber:
forEachdevuelveundefined. No puedes encadenar un.map()después.- No puedes salir antes de tiempo de un
forEachconbreak. Si necesitas cortar la iteración, usafor...ofo biensome/every.
Si te descubres escribiendo arr.forEach(x => results.push(transform(x))), eso es un map disfrazado.
find y findIndex: solo uno, por favor
find devuelve el primer elemento que cumple con el predicado, o undefined si no hay coincidencias. findIndex devuelve el índice correspondiente (o -1 si no encuentra nada).
find se detiene en la primera coincidencia. No uses filter(...)[0]: recorre todo el array para descartar el resto.
some y every: preguntas de sí o no
some devuelve true si al menos un elemento cumple la condición. every solo devuelve true cuando la cumplen todos.
Las dos cortan por lo sano en cuanto encuentran lo que buscan: some se detiene al primer true, y every al primer false. Son justo lo que necesitas cuando quieres responder "¿hay alguno que…?" o "¿todos cumplen…?".
slice vs splice en JavaScript: copiar frente a cortar
Suenan parecido, pero hacen cosas muy distintas.
slice(start, end) devuelve una copia superficial de un trozo del array y no toca el original. Ojo: end no se incluye, y si lo omites, corta hasta el final.
splice(start, deleteCount, ...items) modifica el array original. Elimina deleteCount elementos a partir de la posición start, opcionalmente inserta nuevos elementos en ese hueco y devuelve los elementos eliminados.
Regla mnemotécnica: slice es seguro (copia), mientras que splice edita el array quirúrgicamente y lo modifica in situ.
Métodos que mutan vs. métodos que no mutan en JavaScript
Esta diferencia es importante de verdad. Cuando un trozo de código muta sin querer un array compartido, el bug resultante suele ser de los más molestos de rastrear.
Mutantes (modifican el original y suelen devolver otra cosa):
push,pop,shift,unshiftsplice,sort,reversefill,copyWithin
No mutantes (devuelven un array o valor nuevo y dejan el original intacto):
map,filter,slice,concatflat,flatMapfind,findIndex,some,every,includes,indexOfreduce,reduceRight
Los dos a los que hay que tener vigilados son sort y reverse: parecen inofensivos y mutan el array a escondidas. Si lo que quieres es una copia ordenada, haz primero un slice:
El JavaScript moderno también trae sus gemelos no mutadores: toSorted, toReversed, toSpliced y with. Devuelven un array nuevo y dejan el original intacto. Están disponibles en todos los runtimes actuales, así que úsalos siempre que puedas.
flat y flatMap
flat aplana arrays anidados un nivel (o más, si le pasas un argumento de profundidad). flatMap es un map seguido de un flat de un nivel, ideal cuando cada elemento puede generar cero o varios resultados.
flatMap es la forma más limpia de "expandir" elementos (una entrada, varias salidas) sin tener que recurrir a un flat() extra.
Juntando todas las piezas
Veamos un ejemplo más realista. Dada una lista de pedidos, queremos calcular los ingresos totales de los pedidos completados que superen los 50 $:
Tres métodos, una sola tubería, cero contabilidad de bucles. Cada paso dice lo que hace. Podrías fusionar los dos filter en uno solo, pero dejarlos separados se lee bien y a veces ayuda a la hora de depurar.
Lo que viene: Map y Set
Los arrays se llevan de maravilla con secuencias ordenadas, pero se vuelven torpes cuando necesitas búsquedas rápidas por clave o una colección de valores únicos. JavaScript trae dos estructuras de datos pensadas justo para eso — Map y Set — y son el tema de la siguiente página.
Preguntas frecuentes
¿Cuál es la diferencia entre map, filter y reduce en JavaScript?
map transforma cada elemento y devuelve un array nuevo de la misma longitud. filter se queda solo con los elementos que pasan una condición y devuelve un array nuevo (normalmente más corto). reduce recorre el array y lo reduce a un único valor: una suma, un objeto, otro array… lo que tú quieras construir.
¿En qué se diferencian forEach y map?
forEach ejecuta una función por cada elemento y devuelve undefined: sirve para efectos secundarios. map ejecuta una función por cada elemento y devuelve un array nuevo con los resultados. Si necesitas un array transformado, usa map. Si solo quieres hacer algo por cada elemento y no te importa el resultado, tira de forEach (o de un for...of).
¿Qué métodos de array mutan el array original?
Los que mutan son push, pop, shift, unshift, splice, sort, reverse, fill y copyWithin. El resto —map, filter, slice, concat, flat, flatMap, find, some, every, reduce— deja el array original intacto y te devuelve un valor nuevo.
¿Cuándo conviene usar slice y cuándo splice?
slice(start, end) devuelve una copia superficial de un trozo del array y no toca el original. splice(start, deleteCount, ...items) sí muta el array: elimina y/o inserta elementos in situ y devuelve los que ha eliminado. Regla para acordarte: slice es seguro, splice opera con bisturí.