Artículo original escrito por Kingsley Ubah
Artículo original JavaScript Array.map() Tutorial – How to Iterate Through Elements in an Array with map()
Traducido y adaptado por Santiago Yanguas

Cuando salió ES6 (EmcaScript 2015), introdujo un nuevo conjunto de métodos para iterar sobre un arreglo. Uno de los más útiles es el método map().

Array.prototype.map() es un método incorporado en los arreglos, para iterar a través de los elementos dentro de una colección de arreglos en JavaScript. Piensa en él, como un bucle para avanzar de un elemento a otro en una lista, manteniendo el orden y la posición de cada elemento.

Este método toma una función callback, que se llama por cada nuevo elemento sobre el que se itera.

La función callback recibe tres parámetros:

  • El valor actual.
  • Su índice.
  • El arreglo de destino

Si eres un novato que lucha por entender cómo usar el método map() o qué hace exactamente, entonces este artículo es para ti.

Cómo funciona el método map() en JavaScript

Imagínate esto: hay una cola de personas en la puerta de un hospital esperando a ser vacunadas. Esto significa que aún no han sido vacunados.

Uno por uno, un médico administra la vacuna a todos ellos. El médico lo hace repitiendo la fila. En un extremo, hay un grupo de personas que aún no han sido vacunadas. El médico toma a todos y cada uno de ellos, les administra la vacuna y los devuelve a una nueva línea de personas vacunadas.

En un extremo, hay un arreglo (A) sobre el que se quiere operar. map() toma todos los elementos de ese arreglo (A), realiza una acción coherente sobre cada uno de esos elementos y los devuelve en un nuevo arreglo (B).

Cómo utilizar el método map(): Ejemplo de vengadores

Para ilustrar cómo funciona map() en JavaScript, consideremos una lista de nombres de algunos de nuestros Vengadores favoritos. El problema es que los nombres de esta lista no están completos: les falta un sufijo importante.

Con map(), podemos tomar todos los nombres de la matriz y añadir el sufijo "man" a todos y cada uno de ellos:

let prefijos = ["super", "spider", "ant", "iron"]
let sufijo = "man";

let nombresCompletos = prefijos.map(prefijo => prefijo + sufijo);

console.log(nombresCompletos);

// ["superman", "spiderman", "antman", "ironman"]
Añadiendo el sufijo man a cada superheroe
map1-1
VISUAL CODE

¿Qué pasa con las mujeres(women)?

Lo siento, mi error. Me di cuenta de mi error y decidí incluir un personaje femenino en la primera posición del arreglo. Cada elemento dentro de un arreglo se identifica por un valor único, su índice (o posición en el arreglo). El primer elemento tendrá un índice de 0, el segundo un índice de 1, y así sucesivamente.

Dado que ahora hay una superheroína en la lista, tendremos que asegurarnos de añadir el sufijo correcto a la superheroína correspondiente.

Dado que map() también toma el índice del elemento sobre el que estamos iterando, podemos hacer esto comprobando el índice de nuestro héroe y asegurándonos de que utilizamos el sufijo "woman" para el primer elemento de nuestra matriz:

let prefijos = ["wonder", "spider", "ant", "iron"]
let hombre = "man";
let mujer = "woman";

let nombresCompletos = prefijos.map(function(prefijo, indice) {
    return (indice == 0) ? prefijo + mujer : prefijo + hombre;
 });

console.log(nombresCompletos);

["wonderwoman", "spiderman", "antman", "ironman"]
Nombre completos
map--8
Resultado

Cómo utilizar el argumento del índice

Además del valor sobre el que se itera, map toma también su posición de índice. Esto es muy útil si quieres realizar diferentes tipos de operaciones dependiendo de la posición del índice del elemento.

En el ejemplo anterior, añadimos un sufijo diferente comprobando el índice.

Para conocer la posición del índice de cada uno de nuestros elementos dentro del arreglo, podemos hacer lo siguiente:

let nombresCompletos = ["wonderwoman", "spiderman", "antman", "ironman"]

nombresCompletos.map(function(nombre, indice) {
    console.log(${nombre} esta en la posición ${indice});
});

/* Resultado del anterior código
"wonderwoman esta en la posición 0"
"spiderman esta en la posición 0"
"antman esta en la posición 0"
"ironman esta en la posición 0"
*/
map--1
Resultado del código original en inglés

Multiplicar todos los elementos del arreglo por 2

Trabajemos ahora un poco con los números. En este ejemplo, simplemente queremos multiplicar cada número del arreglo de destino por dos y luego devolver sus productos en un nuevo arreglo:

let numeros = [10, 20, 30, 40]
let multiplicador = 2;

let productos = numeros.map(numero => numero * multiplicador);

console.log(productos);

// [20, 40, 60, 80]
arreglo de numeros multiplicados por 2

Redondear al número entero más cercano

¿Qué pasa si tenemos un arreglo de decimales, pero queremos que cada uno de esos números decimales se redondee al entero más cercano?

let numeros = [3.7, 4.9, 6.2]
let redondeados = numeros.map(function(numero) {
    return Math.round(numero);
})

console.log(redondeados);

// [4, 5, 6]
Arreglo de números redondeados
map--2
Resultado

Cambiar cadenas de texto por números

Tenemos una lista de números que son de tipo string (cadena). Sin embargo, queremos convertir cada uno de ellos al tipo Number (número):

let textos = ["10","20","30"]

let numeros = textos.map(function(texto) {
    return Number(texto);
})

console.log(numeros);

// [10, 20, 30]
Cadenas de texto a numeros

Conseguir nombres reales de los Vengadores

En este ejemplo, estamos trabajando con objetos. Tenemos cinco vengadores en el arreglo y cada uno tiene tanto un nombre real como un nombre de héroe. Sin embargo, solo queremos recuperar sus nombres reales en el nuevo arreglo.

let vengadores = [
    {nombre: "steve rogers", nombreHeroe: "captain america"},
    {nombre: "tony stark", nombreHeroe: "iron man"},
    {nombre: "bruce banner", nombreHeroe: "the hulk"},
    {nombre: "peter parker", nombreHeroe: "spiderman"},
    {nombre: "tchalla", nombreHeroe: "black panther"}
]

let nombresReales = vengadores.map(vengador => vengador.nombre);

console.log(nombresReales);

// ["steve rogers", "tony stark", "bruce banner", "peter parker", "tchalla"]
Arreglo de nombres
map--5-1
Resultado del nombre de los vengadores

Conseguir los nombres de los héroes de los Vengadores

Para obtener solo sus nombres de héroe, hacemos casi lo mismo, solo que en este caso accedemos a la propiedad nombreHeroe:

let vengadores = [
    {nombre: "steve rogers", nombreHeroe: "captain america"},
    {nombre: "tony stark", nombreHeroe: "iron man"},
    {nombre: "bruce banner", nombreHeroe: "the hulk"},
    {nombre: "peter parker", nombreHeroe: "spiderman"},
    {nombre: "tchalla", nombreHeroe: "black panther"}
];

let nombresReales = vengadores.map(vengador => vengador.nombreHeroe);

console.log(nombresReales);

// ["captain america", "iron man", "the hulk", "spiderman", "black panther"]
Resultado del nombre de los vengadores
map--10
Resultado

Cómo separar una función para añadir a map

En lugar de definir una función directamente dentro de map(), podemos definir la función fuera y luego llamarla dentro de nuestra función map():

let vengadores = [
    {nombre: "steve rogers", nombreHeroe: "captain america"},
    {nombre: "tony stark", nombreHeroe: "iron man"},
    {nombre: "bruce banner", nombreHeroe: "the hulk"},
    {nombre: "peter parker", nombreHeroe: "spiderman"},
    {nombre: "tchalla", nombreHeroe: "black panther"}
];

let obtenerNombre = vengador => vengador.nombre;
let nombresReales = vengadores.map(obtenerNombre);

console.log(nombresReales);

// ["steve rogers", "tony stark", "bruce banner", "peter parker", "tchalla"]
Quitar complejidad al map mediante separación de funciones

Cómo funciona el argumento del arreglo

Antes dije que en cada iteración, el método map() toma el valor sobre el que se itera y también su posición de indice. Hay otro argumento que añadir a esos dos, los argumentos del arreglo.

El argumento arr representa el arreglo de destino sobre el que se hace un bucle, junto con todo su contenido. Con este argumento, se puede buscar en el arreglo completo para encontrar algo.

En este ejemplo, accederemos al parámetro arr para buscar y comprobar si el elemento actual es el último de la lista. Si no lo es, accedemos al siguiente elemento y lo restamos del elemento actual. Si es el último, simplemente lo devolvemos.

const arregloViejo = [33, 20, 10, 5];
const nuevoArreglo = arregloViejo.map((valorActual, indice, arr) => {
    let siguienteItem = indice + 1 < arr.length ? arr[indice + 1] : 0
    return valorActual - siguienteItem;
});


console.log(nuevoArreglo);

// [13, 10, 5, 5]
Buscar en el arreglo total

Conclusiones

El método map() fue introducido en ES6. Con este método, podemos acceder y realizar una acción consistente en cada elemento dentro de una colección de arreglos.

Toma una función callback que llama por cada nuevo elemento sobre el que itera.

En este tutorial, he introducido el método map(), he ilustrado su funcionamiento con una analogía y he dado algunos ejemplos prácticos de su uso en código JavaScript.

Espero que hayas sacado algo útil de este artículo. Si te gustan los tutoriales relacionados con la programación como este, deberías visitar mi blog. Allí publico regularmente artículos sobre desarrollo de software.

Gracias por leer y hasta pronto.
P/S: Si estás aprendiendo JavaScript, he creado un eBook que enseña 50 temas en JavaScript con notas digitales dibujadas a mano. Compruébalo aquí.