En JavaScript, con frecuencia te verás en necesidad de iterar a través de una colección de arreglos y ejecutar un método callback por cada una de las iteraciones. Y para realizarlo hay un método muy útil que los desarrolladores de JavaScript típicamente utilizan: el método forEach()
.
El método forEach()
llama a una función callback específica una vez por cada elemento sobre el que itera dentro de un arreglo. Al igual que otros iteradores de arreglos tales como map
y filter
, la función callback puede recibir tres parámetros.
- El elemento actual: Este es el elemento del arreglo por el cual se está haciendo la iteración.
- Su índice: Este es el índice de la posición que tiene el elemento dentro del arreglo.
- El arreglo objetivo: Este es el arreglo por el cual se está haciendo la iteración.
El método forEach
no regresa un nuevo arreglo al igual que lo hacen otros iteradores tal como filter
, map
y sort
. En cambio, el método devuelve el valor undefined
por sí solo. Por lo tanto no se puede encadenar como los otros métodos.
Otra cosa acerca de forEach
es que no puedes terminar el bucle (con la instrucción break) o hacerlo saltarse una iteración (con la sentencia continue). En otras palabras, no lo puedes controlar.
La única manera de finalizar un bucle forEach
es incluyendo una excepción dentro de la función callback. No te preocupes, pronto veremos todo esto en la práctica.
Como usar el método forEach()
en JavaScript
Imagina que un grupo de estudiantes hacen una fila para el pase de lista de rutina. El coordinador de la clase se mueve a través de la fila y dice el nombre de cada uno de los estudiantes mientras marca si están presentes o ausentes.
Es importante hacer mención que el coordinador no cambia el orden de los estudiantes en la fila. También los mantiene en la misma fila después de terminar el pase de lista. Todo lo que realiza es una acción (su inspección) en cada uno de ellos.
En los siguientes ejemplos, teniendo en mente este escenario, veremos como puedes utilizar el método forEach
para resolver problemas de la vida real con JavaScript.
Ejemplos del método forEach()
en JavaScript
Como remover el primer número impar en un arreglo con forEach()
En este ejemplo, tenemos un arreglo que contiene un número impar en la primera posición y varios números pares después. Pero solo queremos números pares en este arreglo. Así que vamos a remover el número impar del arreglo usando el bucle forEach()
:
let numeros = [3, 6, 8, 10, 12]
let impar = 3;
numeros.forEach(function(numero) {
if (numero === impar) {
numeros.shift() // 3 será borrado del arreglo
}
})
console.log(numeros);
[6, 8, 10, 12] // Todos son pares!
Como acceder a la propiedad del índice con forEach()
En este ejemplo, vamos a ejecutar la función pasarLista
por cada uno de los estudiantes por los que se recorrió el bucle dentro del arreglo. La función pasarLista
solamente registra en la consola una cadena perteneciente a cada uno de los estudiantes.
nombres = ["anna", "beth", "chris", "daniel", "ethan"]
function pasarLista(nombre, indice) {
console.log(`Está el numero de estudiante ${indice + 1} -${nombre} - presente? Sí!`)
;}
numeros.forEach((nombre, indice) => pasarLista(nombre, indice));
/*
"Está el número de estudiante 1 - anna presente? Sí!"
"Está el número de estudiante 2 - beth presente? Sí!"
"Está el número de estudiante 3 - chris presente? Sí!"
"Está el número de estudiante 4 - daniel presente? Sí!"
"Está el número de estudiante 5 - ethan presente? Sí!"
*/
En este ejemplo, el nombre era la única información que teníamos sobre cada estudiante. Sin embargo, también queremos saber cuáles pronombres usa cada estudiante. En otras palabras, queremos definir una propiedad pronombre para cada estudiante.
Entonces vamos a definir a cada estudiante como un objeto con dos propiedades, nombre y pronombre:
nombres = [
{nombre:"anna",pronombre: "ella"},
{nombre: "beth",pronombre: "elle"},
{nombre:"chris",pronombre: "él"},
{nombre: "daniel",pronombre: "él"},
{nombre: "ethan",pronombre: "él"}
]
function pasarLista(estudiante, indice) {
console.log(`El número de estudiante ${indice + 1} ${estudiante.nombre}. Está ${estudiante.pronombre} presente? Sí!`);
}
numeros.forEach((nombre, indice) => pasarLista(nombre, indice));
/*
"El número de estudiante 1 es anna. Está ella presente? Sí!"
"El número de estudiante 2 es beth. Está elle presente? Sí!"
"El número de estudiante 3 es chris. Está él presente? Sí!"
"El número de estudiante 4 es daniel. Está él presente? Sí!"
"El número de estudiante 5 es ethan. Está él presente? Sí!"
*/
Estamos registrando en la consola el pase de lista de cada estudiante, luego realizamos una verificación para ver qué pronombre usa cada estudiante, y finalmente pasamos dinámicamente el pronombre correcto como parte de la cadena.
Como copiar un arreglo en un nuevo arreglo con forEach()
en JavaScript
Después de tres años de estudio, es tiempo de que cada estudiante se gradúe. En nuestro JavaScript, vamos a definir dos arreglos: aunEstudiante
y yaGraduado
. Como probablemente adivinaste, aunEstudiante
guarda el dato de los estudiantes antes de su graduación.
Posteriormente, el bucle forEach
toma el dato de cada uno de los estudiantes y llama a la función estudianteGraduado
en el.
En esta función construimos un objeto con dos propiedades: el nombre de estudiante y la posición en la que se graduó. Luego pasamos el nuevo objeto al arreglo yaGraduado
. A este punto, el estudiante ya se ha graduado.
Este ejemplo también demuestra como puede usar el método forEach()
para copiar un arreglo dentro de un nuevo arreglo.
let aunEstudiante = ["anna", "beth", "chris", "daniel", "ethan"]
let yaGraduado = []
function estudianteGraduado(estudiante, indice) {
let objeto = { nombre: estudiante, posicion: indice + 1}
yaGraduado[indice] = objeto
}
aunEstudiante.forEach((nombre, indice) => estudianteGraduado(nombre, indice));
console.log(yaGraduado);
/*
[
{ nombre: "anna", posición: 1},
{ nombre: "beth", posición: 2},
{ nombre: "chris", posición: 3},
{ nombre: "daniel", posición: 4},
{ nombre: "ethan", posicion: 5}]
]
*/
Como revisar el elemento siguiente en un arreglo con el parámetro arreglo
En algún momento, el profesor deberá verificar si la lista tiene a continuación un elemento en particular en la lista. En tal caso, el profesor deberá tener una visión amplia de toda la lista. De esa manera, puede saber si hay un próximo estudiante al cual llamar.
En nuestro JavaScript, podemos replicar esto porque la función callback también puede acceder al parámetro (el tercero) del arreglo
. Este parámetro representa el arreglo objetivo, que es nombre
.
Verificamos si hay un siguiente elemento (estudiante) en el arreglo. Si lo hay, pasamos la cadena positivo
a la variable siguienteElemento
. Si no hay ninguno, pasamos la cadena negativo
a la variable. Luego para cada iteración, revisamos si ese estudiante es realmente el último.
nombres = ["anna", "beth", "chris", "daniel", "ethan"]
function pasarLista(nombre, indice, arreglo) {
let siguienteElemento = indice + 1 < arreglo.length ? "positivo" : "negativo"
console.log(`Está el número de estudiante ${indice + 1} - ${name} presente? Sí!. Hay un próximo estudiante? ${siguienteElemento}!`);
}
nombres.forEach((nombre, indice, arreglo) => pasarLista(nombre, indice, arreglo))
/*
"Está el número de estudiante 1 - anna presente? Sí!. Hay un próximo estudiante? positivo!"
"Está el número de estudiante 2 - beth presente? Sí!. Hay un próximo estudiante? positivo!"
"Está el número de estudiante 3 - chris presente? Sí!. Hay un próximo estudiante? positivo!"
"Está el número de estudiante 4 - daniel presente? Sí!. Hay un próximo estudiante? positivo!"
"Está el número de estudiante 5 - ethan presente? Sí!. Hay un próximo estudiante? negativo!"
*/
No puedes salir del bucle forEach
, en su lugar utiliza every()
¿Recuerdas cuando mencioné que, por su naturaleza, no puedes salir de un bucle forEach
? Una vez iniciado, va a correr hasta que alcanza el último elemento del arreglo. Así que si insertas una declaración de break
, te va a regresar un error de sintaxis, SyntaxError
:
let numeros = [2, 4, 5, 8, 12]
let impar = 5;
numeros.forEach(function(numero) {
if (numero === impar) {
break; // oops, esto no va a funcionar!
}
})
Normalmente preferirías salir del bucle una vez que consigues que tu código realice su objetivo antes de alcanzar el último elemento. En nuestro ejemplo de arriba, ya encontramos el número impar (5), así no que no había necesidad de seguir iterando sobre los siguientes elementos (8 y 12).
Si te deseas salir de un bucle en alguna condición, entonces te recomiendo utilizar cualquiera de los siguientes métodos.
- bucle
for
- bucle
for…of
ofor…in
Array.some()
Array.every()
Array.find()
Así es como puedes salirte de un bucle con Array.every()
:
let numeros = [2, 4, 5, 8, 12]
let impar = 5;
numeros.every(numero => {
if (numero == impar) {
return false;
}
console.log(numero);
return true;
});
// 2 4