Hoy vamos a hablar sobre algunas funciones que JavaScript tiene para trabajar con arrays. Ya vimos cómo recorrer arrays, y ahora iremos un poco más allá.
Por definición, si consultamos la documentación de estas funciones, siempre veremos que se definen como Array.prototype.metodo()
. Esto se debe a que estas funciones son métodos de Array.prototype
. Cuando creamos una variable con []
(también se puede hacer con new Array
), estamos creando una instancia del objeto Array. Esto significa que la instancia heredará los métodos, incluyendo los del prototype, lo que nos permitirá utilizar todos los que estén definidos.
En esta entrada veremos cuáles son muchos de los métodos de JavaScript y a utilizarlos para que podamos sacarle todo el partido a los arrays: añadir elementos, eliminar, dividir, buscar y otras acciones.
Vamos a empezar explorando las opciones que tenemos para agregar y quitar elemento de un array, con diferentes opciones, así como algunas para operaciones algo más especificas.
Si lo que estamos buscando es añadir elementos de uno a uno a un array, la opción es push()
o unshift()
, depende de lo que estemos buscando.
Con push()
añadiremos un elemento al final del array, ejemplo:
let nuestroArray = [1, 2, 3];
nuestroArray.push(4);
console.log(nuestroArray) // [1,2,3,4]
En cambio, al utilizar unshift()
añadiremos el elemento, pero el resultado será diferente, lo añadiremos al principio:
let nuestroArray = [1, 2, 3];
nuestroArray.unshift(4);
console.log(nuestroArray) // [4,1,2,3]
Esta misma operación se puede hacer añadiendo más de un elemento, por ejemplo:
let nuestroArray = [1, 2, 3];
nuestroArray.push(4, 5, 6);
console.log(nuestroArray) // [1,2,3,4,5,6]
Simplemente, habrá que separar los valores por coma. ¡Ojo! Si hacemos esto mismo con un array, el resultado será este:
let nuestroArray = [1, 2, 3];
let elOtroArray = [4, 5, 6];
nuestroArray.push(elOtroArray);
console.log(nuestroArray) // [1,2,3,[4,5,6]]
Parece obvio, pero puede ser un error típico, al añadirlo, añadiremos el array directamente dentro de nuestro array.
Por otro lado, para eliminar elementos usaremos shift()
y pop()
:
let nuestroArray = [1, 2, 3, 4, 5];
nuestroArray.shift();
console.log(nuestroArray) // [2,3,4,5]
nuestroArray.pop();
console.log(nuestroArray) // [2,3,4]
Creo que con el ejemplo queda claro el funcionamiento, con shift()
eliminamos el primer elemento, y con pop()
eliminamos el último. Tanto uno como el otro, solo permiten eliminar elementos de uno en uno. Esto nos limita bastante, pero no solo en cuanto a número, sino que además no podemos eliminar elementos que se encuentren en medio del array.
splice()
para añadir y eliminar elementos en un arrayLas opciones anteriores para eliminar o añadir son muy prácticas, pero muchas veces vamos a querer hacer algo más concreto, que quitar y poner elementos de uno en uno.
Para eliminar elementos usando splice()
vamos a necesitar pasarle al método dos argumentos: el índice del primer elemento a eliminar y el número de elementos que queramos borrar.
let nuestroArray = ["Elemento1", "Elemento2", "Elemento3", "Elemento4"];
nuestroArray.splice(1, 2);
console.log(nuestroArray); // ["Elemento2", "Elemento3"]
concat()
Hemos visto al inicio de la sección otros métodos para añadir elementos a un array, push()
y shift()
. No obstante, he dejado este para el final por ser un algo diferente, ya que este método no genera ninguna mutación en el array original, concat()
devuelve un array nuevo sin mutar ninguno de los arrays que se concatenen. Ejemplo aquí:
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const concatenatedArray = array1.concat(array2);
console.log(concatenatedArray); // [1, 2, 3, 4, 5, 6]
console.log (array1) // [1, 2, 3]
console.log (array2) // [4, 5, 6]
Como vemos, ¡los array iniciales están intactos!
Vamos a ver las diferentes formas que tenemos para comprobar información de un array como tipos o si contiene algún elemento concreto:
Este es muy sencillo de usar y comprender. Devolverá true
si se le pasa un array y false
si el elemento no es un array. Ejemplo:
let nuestroArray = [1, 2, 3];
let nuestroString = 'hey!';
console.log(Array.isArray(nuestroArray)); // true
console.log(Array.isArray(nuestroString));// false
Aquí tenemos dos opciones, o utilizar directamente toString()
y convertirlo a string, o utilizar join()
que, además de unir nuestro array, nos va a dejar utilizar un separador, que por otro lado toString()
utiliza la coma ,
. Veamos un ejemplo de cada:
let colores = ['rojo', 'azul', 'verde'];
console.log(colores.toString()); // rojo,azul,verde
console.log(colores.join()); // rojo,azul,verde
console.log(colores.join("-")); // rojo-azul-verde
console.log(colores.join(" ")); // rojo azul verde
Con every()
vamos a comparar si cada uno de los elementos de este pasa cierta condición. Vamos con un ejemplo:
const nuestroArray = [14, 3, 27, 9, 22, 5];
const todosMayores = nuestroArray.every(numero => numero > 30);
console.log(todosMayores); // true
De la misma forma podríamos usarlo para ver si dos arrays son iguales, atento:
const arr1 = [5, 7, 11]
const arr2 = [5, 7, 11]
let arraysIguales = arr1.length === arr2.length && arr1.every((num, index) => { num === arr2[index] });
Le diríamos que si los dos arrays tienen el mismo número de elementos y además cumplen la condición del método every()
, el array es igual. Dentro de every()
simplemente comparamos que cada valor de arr1
sea igual al del arr2
en la misma posición.
Por otro lado, tendríamos some()
, que va a devolvernos true
solo con que uno de los elementos pase la condición.
const numeros = [14, 3, 27, 9, 22, 5];
const algunNumeroMayorQue10 = numeros.some(numero => numero < 25);
if (algunNumeroMayorQue10) {
console.log("Al menos un número es menor que 25.");
} else {
console.log("Ningún número es menor que 25.");
}
A continuación vamos a profundizar en la comparación y búsqueda de elementos, realización de copias y filtrado de elementos según criterios específicos. ¡Vamos a ello!
include()
Con include()
lo que vamos a hacer es obtener true
si el array contiene este elemento, si no obtendremos false
.
const numeros = [14, 3, 27, 9, 22, 5];
console.log(numeros.includes(3)); // true
Pero vayamos un paso más allá con indexOf()
:
indexOf()
es similar a include()
solo que en vez de true
va a devolver el índice donde se encuentra el elemento y en vez de false
devolverá el valor -1.
const numeros = [14, 3, 27, 9, 22, 5, 7, 27, 1];
console.log(numeros.indexOf(27)) // 2
console.log(numeros.indexOf(27, 3)) // 7
console.log(numeros.indexOf(4)) // -1
find()
En este caso ya no vamos a ver si el elemento existe o no o si existe dónde está, si no que vamos directamente a recuperarlo si lo encontramos. El método devolverá el primer elemento que satisfaga la condición:
const numeros = [14, 3, 27, 9, 22, 5];
const encontrado = numeros.find(num => num > 15);
console.log(encontrado) // 27
En este método, al igual que en indexOf
, podemos pasarle un índice como atributo para que empiece a buscar a partir de este.
slice()
Este método devolverá una copia superficial del array, sin modificar el anterior, y podremos seleccionar qué parte de ese array nos devuelve. Al pedir esta copia con slice
podremos decirle qué porción del array queremos que nos devuelva pasándole dos parámetros, el índice del comienzo de la porción y el índice del final. Se le pueden pasar valores negativos, con esto el índice contará desde el final del array original.
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const algunosNumeros = numeros.slice(1, 4);
console.log(algunosNumeros); // [2, 3, 4]
El hecho de que nos devuelva una copia superficial no va a presentar un problema cuando nuestros valores sean de tipo primitivo (strings, number, bool) pero sí cuando se trate de arrays u objetos, ya que este tipo de copia es solo una referencia del array original. Aquí un ejemplo de lo que puede ocasionar esto:
const arrayDeObjetos = [
{ id: 1, nombre: 'Objeto 1' },
{ id: 2, nombre: 'Objeto 2' },
{ id: 3, nombre: 'Objeto 3' }
];
// Creamos una "copia superficial" del array original usando slice()
const copiaArray = arrayDeObjetos.slice();
// Modificamos un objeto en la copia
copiaArray[0].nombre = 'Objeto 1 Modificado';
// Imprimimos ambos arrays
console.log('Array Original:', arrayDeObjetos);
console.log('Copia del Array:', copiaArray);
Pruébalo en la consola y verás el resultado, te lo pensarás dos veces antes de usarlo.
filter()
Imaginemos que tenemos un array con palabras, y queremos con expresiones regulares, por ejemplo, obtener solo las palabras que contienen las letras «onte» juntas. Para ello, usaremos filter()
. Vamos por un ejemplo para verlo de forma clara:
const palabras = ["monte", "fontes", "Caronte", "puente", "contenedor", "cuento", "rinoceronte"];
const palabrasConOnte = palabras.filter(palabra => /onte/.test(palabra));
console.log(palabrasConOnte);
Este sería el uso básico, el callback irá filtrando palabra por palabra e irá generando el array final habiendo filtrado todos los elementos que cumplan la condición.
Al callback, además del propio elemento que se está procesando en ese instante, podremos pasarle como parámetro opcional el índice y el propio array.
En esta sección, abordaremos varias técnicas para ordenar, invertir y realizar cálculos en arrays:
sort()
Este puede parecer un método sencillo, si nos dejamos llevar por el nombre y un par de pruebas puede parecer que lo hemos comprendido rápido. Vamos a ver un ejemplo muy sencillo:
let numeros = [5, 2, 4, 1];
numeros.sort();
console.log(numeros); // [ 1, 2, 4, 5 ]
Genial, ¿no? Pues atentos:
let numeros = [5, 2, 4, 1, 11];
numeros.sort();
console.log(numeros); // [ 1, 11, 2, 4, 5 ]
sort()
acepta dos parámetros que nos van a ser imprescindibles para arreglar esto: el primero, «a» y el segundo, «b». Si no pasamos ninguno de estos parámetros, automáticamente, nuestro array será convertido en un string. ¡Ese parece ser nuestro problema!
Entonces vamos a reescribir nuestras últimas líneas para que nos lo ordene por orden numérico:
let numeros = [5, 2, 4, 1, 11];
numeros.sort((a,b) => a - b);
console.log(numeros); // [1, 2, 4, 5, 11]
Cambiando el orden (b – a)
, el orden sería inverso.
sort()
es un método que muta el array inicial, por eso lo hemos definido con let
, y no con const
. Si quisiéramos que no mute, tenemos sorted()
.
reverse()
Sin profundizar mucho, este método es sencillo. Lo menciono porque tiene su uso, pero no tiene gran explicación:
let numeros = [5, 2, 4, 1, 11];
numeros.reverse();
console.log(numeros) // [11, 1, 4, 2, 5]
Al igual que sort()
, es mutable, e igualmente tiene su variante para casos en los que no convenga generar mutación: reversed()
.
reduce()
Este es uno de mis métodos favoritos. reduce()
va a devolver un único valor, y será el acumulado de todos los valores del array que se le pase. Vamos con un ejemplo sencillo para comprenderlo:
const numeros = [1, 2, 3, 4, 5];
const resultado = numeros.reduce((acumulador, numeroActual) => {
return acumulador + numeroActual;
}, 0);
Definimos la variable del acumulador
, que será la que irá guardando la última operación que devuelva el return, numeroActual
, como su nombre indica, será el número en la posición en la que el callback va recorriendo el array, y, por otro lado, definimos 0 como valor inicial del acumulador, pero podríamos definir otro número cualquiera.
Este ejemplo es chulo para que lo veamos con un caso que a priori no suele pasarnos por la cabeza:
const productos = [
{ nombre: 'Camiseta', categoria: 'Ropa' },
{ nombre: 'Zapatillas', categoria: 'Calzado' },
{ nombre: 'Pantalones', categoria: 'Ropa' },
{ nombre: 'Reloj', categoria: 'Accesorios' },
{ nombre: 'Botas', categoria: 'Calzado' }
];
const productosPorCategoria = productos.reduce((acumulador, producto) => {
// Verificar si la categoría ya existe en el acumulador
if (!acumulador[producto.categoria]) {
acumulador[producto.categoria] = [];
}
// Agregar el producto a la categoría correspondiente
acumulador[producto.categoria].push(producto);
return acumulador;
}, {});
console.log(productosPorCategoria);
Teniendo el array de objetos, vamos en cada elemento ver si la key categoría ya está en el acumulador, si no está, la creamos y agregamos el nombre del producto a la categoría obteniendo todas las categorías conteniendo sus objetos.
Ahora ya conoces unos cuantos métodos que te servirán para implementar mejorar o nuevas ideas en tus páginas o aplicaciones web, puedes usarlos incluso para hacerte una herramienta para el navegador que te ayude a auditar tu sitio web.
En esta entrada hemos visto diversos métodos con sus respectivos ejemplos que te ayudarán a comprender un poco más el alcance de JavaScript, si bien es el lenguaje que da vida y funcionalidad al front end en el navegador, con los años ha ido creciendo y su alcance ya es enorme.
Gracias a estos métodos vamos a poder manejar datos de forma más cómoda y elegante, si los comprendemos y los ponemos en práctica podremos sacarle mucho partido a JavaScript y conseguiremos además escribir un código mucho más limpio y eficiente.
En este artículo, aprenderás qué es el Lazy Loading y cómo implementarlo fácilmente en tu… Leer más
En esta guía práctica, te explicamos qué es el presupuesto de rastreo, por qué es… Leer más
¿Alguna vez te has encontrado con un mensaje que te invita a actuar, ya sea… Leer más
Una de las preguntas más comunes entre los desarrolladores web que comienzan a usar JavaScript… Leer más
Descubre qué es y para qué sirve la preimpresión digital para conseguir una buena impresión… Leer más
Ampliamos información para las redes sociales. Descubre cómo gestionar correctamente los consentimientos necesarios en las… Leer más