Los arrays son objetos similares a una lista, que en JavaScript nos proporcionan métodos para efectuar operaciones de recorrido y mutación, también conocidas como “manipulación de arrays”.
¿Cómo empezar con JavaScript?
Si sos un desarrollador que cuenta con algo de experiencia escribiendo código en otros lenguajes y estás por dar tus primeros pasos en Javascript, hay un par de cosas que deberías saber antes de comenzar.
Antes que nada, daremos una breve definición que nos ayudará a entender qué es y para qué nos sirve este lenguaje. Javascript es un lenguaje de programación dinámico, multiparadigma, débilmente tipado e interpretado. Se usa comúnmente para el desarrollo web front-end y, desde hace algunos años, para desarrollos back-end a través de frameworks como NodeJs y/o NextJs.
Tipos de datos en JavaScript
Que JavaScript sea débilmente tipado no significa que no tenga tipos de datos. De hecho, cuenta (al día de hoy) con 7 tipos primitivos y 2 tipos estructurales. Dentro de los tipos de datos primitivos tenemos los siguientes:
- Boolean
- Null
- Undefined
- Number
- String
- Symbol
- BigInt
Y para completar, los 2 tipos de datos estructurales, son:
- Object
- Function
Manipulación de Arrays (arreglos)
En esta oportunidad, nos vamos a centrar en un tipo de dato estructural perteneciente al tipo Object: array.
Los arrays son objetos similares a una lista, que en JavaScript nos proporcionan métodos para efectuar operaciones de recorrido y mutación, también conocidas como “manipulación de arrays”.
Conocer la variedad de métodos que nos brindan los arrays nos va a resultar muy útil en nuestro trabajo diario, ya que nos ahorrarán muchísimo tiempo cuando queramos manipular datos que se encuentren almacenados en una estructura de datos de este tipo (por ejemplo los tan conocidos archivos en formato JSON utilizados para la transferencia de datos).
Es por ello que, a continuación, vamos a mencionar los más útiles con algunos ejemplos para entender su funcionamiento.
ForEach
Este método, propio de los arrays, nos permite ejecutar una función pasada por parámetro, una vez por cada elemento de nuestro array. Puede recibir hasta 5 parámetros pero nos vamos a enfocar únicamente en los dos obligatorios para poder ejecutar esta función: currentValue (el elemento actual que se encuentra siendo procesado en el array) y una función que es la que se ejecutará en cada iteración. Veamos un ejemplo:
const frutas = ['Manzana', 'Banana', 'Naranja']; function imprimir(item) { console.log(item); } frutas.forEach(function (fruta){ imprimir(fruta); })
Como podemos observar, primero declaramos una variable llamada frutas cuyo valor es un array de 3 elementos de tipo String. Luego, definimos una función llamada imprimir que recibe un elemento y lo muestra por consola. Seguidamente, hacemos un llamado al método forEach de nuestro array, al cual le pasamos por parámetro una función que a su vez recibe por parámetro el currentValue (es decir, el elemento actual que está siendo procesado del array) y luego invoca nuestra función imprimir con ese elemento.
También podemos escribir este procedimiento utilizando una arrow function, de la siguiente manera:
const frutas = ['Manzana', 'Banana', 'Naranja']; frutas.forEach((fruta) => { console.log(fruta); });
En ambos casos, si ejecutamos nuestro código, obtendremos la siguiente salida por consola:
> Manzana > Banana > NaranjaPush, shift, unshift y pop
Antes de avanzar un poco más, creo conveniente mencionar el concepto de mutabilidad. La mutabilidad es la capacidad de un elemento de modificar su estado. Los arrays son objetos que poseen esta capacidad, pero no todos sus métodos hacen uso de ella.
Teniendo en cuenta esta definición, podemos decir que estos métodos pueden ser llamados mutables, ya que tienen la capacidad de modificar el valor del array que los invoca.
Al utilizar el método push, lo que lograremos es agregar un elemento en la última posición de nuestro array. Este método recibe por parámetro el elemento que deseamos agregar. Veamos un ejemplo siguiendo con nuestro caso anterior
const frutas = ['Manzana', 'Banana', 'Naranja']; frutas.push('Mandarina'); console.log(frutas);
Si ejecutamos nuestro código, obtendremos la siguiente salida por consola:
> Manzana > Banana > Naranja > Mandarina
Como podemos observar, el método push agrega nuestro elemento en la última posición del array, modificando el estado del mismo, por eso decimos que es un método mutable.
Shift nos permite eliminar el primer elemento de nuestro array, a la vez que nos lo devuelve para que podamos almacenarlo en otra variable si es necesario. Veamos un ejemplo sencillo, utilizando el mismo array de frutas que en los casos anteriores:
const frutas = ['Manzana', 'Banana', 'Naranja']; let unaFruta = frutas.shift(); console.log(unaFruta); console.log(frutas);
Si ejecutamos nuestro código, obtendremos la siguiente salida por consola:
> [ 'Manzana', 'Banana', 'Naranja' ] > Manzana > [ 'Banana', 'Naranja' ]
Como puede observarse, al invocar al método shift, logramos dos cosas: por un lado almacenamos el valor de nuestro primer elemento en la variable unaFruta, a la vez que eliminamos ese elemento de nuestro array de frutas modificando el estado del mismo. Se puede corroborar al ver el resultado de las impresiones por consola.
Si quisiéramos volver a ingresar el valor ‘Manzana’ (o cualquier otro elemento) en la primera posición de nuestro arreglo, podríamos utilizar el método unshift. Veamos un ejemplo:
const frutas = ['Manzana', 'Banana', 'Naranja']; frutas.shift(); console.log(frutas); frutas.unshift('Manzana'); console.log(frutas);
Al ejecutar este código, obtendremos la siguiente salida por consola:
> [ 'Banana', 'Naranja' ] > [ 'Manzana', 'Banana', 'Naranja' ]
Por último, nos queda ver el comportamiento del método pop. Este método nos permite eliminar el elemento que se encuentra en la última posición de nuestro array, y al igual que el método shift, nos devuelve dicho elemento para que podamos almacenarlo si es necesario. Veamos cómo funciona:
const frutas = ['Manzana', 'Banana', 'Naranja']; let frutaEliminada = frutas.pop(); console.log(frutaEliminada); console.log(frutas);
Al ejecutar este código, obtendremos la siguiente salida por consola:
> Naranja > [ 'Manzana', 'Banana' ]
Map
Map Este es uno de los métodos más útiles de los arrays. A diferencia de los métodos anteriores, map es inmutable, esto quiere decir que no modifica el estado de nuestro arreglo original. Lo que nos permite hacer map, es crear un nuevo arreglo cuyos elementos serán los valores resultantes de aplicar la función que map recibe por parámetro a cada uno de los elementos del array que lo invoca. En este caso dejaremos de lado nuestro ejemplo de frutas y crearemos otro array de números, con el que invocaremos a map para crear uno nuevo con los valores multiplicados por dos.
const numeros = [2, 4, 6, 8] console.log(numeros); const numerosPorDos = numeros.map((numero) => { return numero * 2; }) console.log(numerosPorDos); console.log(numeros);
Luego de ejecutar nuestro código, obtendremos la siguiente salida por consola:
> [ 2, 4, 8, 6 ] > [ 4, 8, 16, 12 ] > [ 2, 4, 8, 6 ]
Como podemos observar, el array original de números no se ha modificado luego del llamado a map, ya que este método es inmutable.
Filter
Otro método muy utilizado es el método filter. También es inmutable. Nos permite filtrar elementos dentro de un array en base a una condición que debe devolver un valor lógico. Veamos un ejemplo a continuación:
const palabras = ['hola', 'manco', 'casa', 'arbol', 'alfajor', 'joystick']; console.log(palabras); const palabrasFiltradas = palabras.filter((palabra) => palabra.length > 5); console.log(palabrasFiltradas); console.log(palabras);
Contamos en primer lugar con un array de palabras. Luego, asignamos a la variable palabrasFiltradas el valor resultante de invocar al método filter con el array palabras y nuestra condición de que incluya cualquier elemento cuyo largo sea mayor a 5 letras.
Si ejecutamos nuestro código, ésta sería la salida por consola resultante:
> [ 'hola', 'manco', 'casa', 'arbol', 'alfajor', 'joystick' ] > [ 'alfajor', 'joystick' ] > [ 'hola', 'manco', 'casa', 'arbol', 'alfajor', 'joystick' ]
Some
Este método nos permite saber si al menos un elemento de nuestro array cumple con una condición que definamos. Su implementación es muy sencilla, como podremos comprobar en el siguiente ejemplo. Definamos un arreglo de números y veamos si alguno de sus elementos es un número par:
const numeros = [1,2,3,4,5]; const esPar = (element) => element % 2 === 0; console.log(numeros.some((numero) => esPar(numero)));
Si ejecutamos nuestro código, tendremos la siguiente salida por consola:
> true
Every
Tal y como lo dice su nombre, el método every corrobora que todos los elementos del array cumplan con una condición. Si en el código anterior reemplazamos el método some por el método every, obtendremos la siguiente salida por pantalla:
> false
Esto se debe a que al recorrer el array y encontrar un elemento que no cumple con la condición, inmediatamente retorna el valor false, ya que sólo devolverá true cuando todos los elementos cumplan con la condición.
Find
Este método retornará el valor del primer elemento del array que cumpla con la condición que definamos.
Supongamos que tenemos un arreglo de personas, donde cada persona tiene un número de ID y su nombre. Al invocar al método find con un ID válido sobre nuestro arreglo de personas, éste nos devolverá el valor del primer elemento que posea ese ID. Veamos un ejemplo:
const personas = [ {id: 1, nombre : 'Nahuel'}, {id: 2, nombre: 'Nicolas'}, {id: 3, nombre: 'Federico'} ]; const persona = personas.find((persona) => persona.id == 2); console.log(persona);
Si ejecutamos este código, obtendremos la siguiente salida por consola:
> { id: 2, nombre: 'Nicolas' }
FindIndex
Este método retornará el índice del primer elemento del array que cumpla con la condición que definamos. Si en el código anterior reemplazamos el método find por el método findIndex, obtendremos la siguiente salida por pantalla:
> 1
Recuerden que los índices comienzan en 0 cuando de posiciones en un array se trata.
Includes
Este método determina si un elemento pertenece o no a un array, devuelve true o false respectivamente.
const numeros = [1,2,3,4,5]; console.log(numeros.includes(3));
Al ejectuarlo, obtendremos la siguiente salida por consola:
> true
Join
Este método une todos los elementos del array en una cadena de texto y la devuelve. Se le puede pasar por parámetro el conector a usar para realizar la concatenación, en caso de omitir este parámetro utilizará una coma por defecto. Veámoslo a continuación:
const elementos = ['Fuego', 'Aire', 'Agua', 'Tierra']; console.log(elementos.join()); console.log(elementos.join('-')); console.log(elementos.join(' ')); console.log(elementos.join(' // '));
Si ejecutamos este código obtendremos la siguiente salida por consola y veremos las diferencias en cada caso:
> Fuego,Aire,Agua,Tierra > Fuego-Aire-Agua-Tierra > Fuego Aire Agua Tierra > Fuego // Aire // Agua // Tierra
Concat
Concat nos permite unir dos o más arrays en un nuevo array que contenga los elementos de ambos. Veamos cómo funciona:
const unArray = ['a','b','c']; const otroArray = ['d','e','f']; const nuevoArray = unArray.concat(otroArray); console.log(nuevoArray);
Al ejecutar el código, nuestra salida por consola será la siguiente:
> [ 'a', 'b', 'c', 'd', 'e', 'f' ]
Slice
Slice es un método inmutable. Nos permite crear una copia de un array, indicando el índice de inicio y fin (sin incluir en la copia). En caso de omitir el inicio y fin, creará una copia de todos los elementos del array. Si los elementos del array son referencias a otros objetos, copiará esa referencia, por lo que modificar ese objeto acarreará la modificación en ambos arrays. Para strings, numbers y boolean (no objetos String y Number), slice copia los valores en el nuevo array. De esta manera, los cambios realizados en un array no afectan a los del otro array. Lo mismo sucede si agregamos un elemento nuevo a alguno de los arrays, este no se agregará al otro. Veamos un ejemplo de todos estos casos:
let numero = {num : 5}; const arreglo = [false, 'Manzana', numero, 10]; console.log('arreglo original: ', arreglo); const arregloCopiado = arreglo.slice(); console.log('arreglo copiado: ', arregloCopiado); arregloCopiado[0] = true; numero.num = 0; arregloCopiado.push('nuevo elemento'); const arregloCortado = arregloCopiado.slice(1,3); console.log('arreglo original: ', arreglo); console.log('arreglo copiado: ', arregloCopiado); console.log('arreglo cortado: ', arregloCortado);
Luego de ejecutar este código, obtendremos la siguiente salida por consola:
> arreglo original: [ false, 'Manzana', { num: 5 }, 10 ] > arreglo copiado: [ false, 'Manzana', { num: 5 }, 10 ] > arreglo original: [ false, 'Manzana', { num: 0 }, 10 ] > arreglo copiado: [ true, 'Manzana', { num: 0 }, 10, 'nuevo elemento' ] > arreglo cortado: [ 'Manzana', { num: 0 } ]
En primer lugar, declaramos la variable numero, la constante arreglo y otra constante arregloCopiado que invoca al metodo slice con el primer array declarado. Luego ejecutamos una serie de operaciones e imprimimos todo por consola para ver los ejemplos antes mencionados.
Como se puede observar, modificar el valor de un elemento de uno de los arrays, no lo modificará en el otro. También podemos notar cómo el haber modificado el valor de la variable numero, hizo que se modifique el elemento correspondiente a esa variable en ambos arrays. Luego agregamos un elemento en la última posición en uno de los arrays y eso no implicó que se agregara en ambos casos. Por último, declaramos una nueva constante e invocamos al método slice pero esta vez con parámetros de inicio y fin para que realice una copia "recortada" del array que lo invoca.
Splice
Este método nos permite modificar el contenido de un array, eliminando elementos existentes y/o agregando nuevos elementos.
Recibe hasta 3 parámetros: start que corresponde al índice de comienzo en el array, deleteCount que indicará la cantidad de elementos a eliminar a partir del índice ingresado (si se omite, se eliminarán todos los elementos del array a partir del índice indicado), y el ítem (puede ser más de uno) a agregar en el array. Como valor de retorno obtendremos una lista con todos los elementos eliminados. Veamos algunos ejemplos:
// Caso 1 eliminar todos let elementos = ['Fuego', 'Agua', 'Aire', 'Tierra']; const eliminados = elementos.splice(0); console.log('Lista elementos: ', elementos); console.log('Elementos eliminados: ', eliminados); // Caso 2 eliminar algunos elementos = ['Fuego', 'Agua', 'Aire', 'Tierra']; const eliminarDos = elementos.splice(0,2); console.log('Lista elementos: ', elementos); console.log('Elementos eliminados: ', eliminarDos); // Caso 3 eliminar y agregar un elemento elementos = ['Fuego', 'Agua', 'Aire', 'Tierra']; const eliminarYAgregarUno = elementos.splice(0, 1, 'Madera'); console.log('Lista elementos: ', elementos); console.log('Elementos eliminados: ', eliminarYAgregarUno);
Si ejecutamos este código, obtendremos la siguiente salida por consola:
> Lista elementos: [] > Elementos eliminados: [ 'Fuego', 'Agua', 'Aire', 'Tierra' ] > Lista elementos: [ 'Aire', 'Tierra' ] > Elementos eliminados: [ 'Fuego', 'Agua' ] > Lista elementos: [ 'Madera', 'Agua', 'Aire', 'Tierra' ] > Elementos eliminados: [ 'Fuego' ]
Y la lista podría seguir, ya que existen muchos más, pero en esta ocasión ya hemos terminado. Esperamos que esta breve y arbitraria selección de métodos para manipulación de arrays les haya sido útil y sirva como material de consulta o repaso.