Los arrays son objetos destinados a almacenar grupos de datos relacionados entre sí. Como todos los data types de JavaScript (JS), tienen sus propiedades y métodos específicos.
Lista no exhaustiva de métodos de los arrays
Aquí vamos a hacer un repaso de los métodos más comunes de los arrays. ¡Vamos allá! ?
método | uso (puedes hacer los ejemplos en la consola de chrome) |
---|---|
.join('x') | Devuelve un string separada por el parámetro que le pasemos. let friends = ['Joey', 'Monica', 'Chadler', 'Ross', 'Rachel', 'Phoebe']; friends.join('&'); // "Joey&Monica&Chadler&Ross&Rachel&Phoebe" |
.indexOf(‘x’) | Devuelve la posición (el index, un número) en el array del valor del array que le pasamos por parámetro. let friends = ['Joey', 'Monica', 'Chadler', 'Ross', 'Rachel', 'Phoebe']; friends.indexOf('Monica'); // 1 |
.concat([‘x’]) | Devuelve el mismo array añadiéndole el otro array que le hayamos pasado por parámetro. let friends = ['Joey', 'Monica', 'Chadler', 'Ross', 'Rachel', 'Phoebe']; friends.concat(['Janice', 'Mark']); // ["Joey", "Monica", "Chadler", "Ross", "Rachel", "Phoebe", "Janice", "Mark"] |
.push(‘x’) | Añade un nuevo valor al final del array y devuelve el length del nuevo array generado.
No todos los métodos alterar el valor original de un array. Este sí lo hace. Por eso también se les llama destructive methods. let friends = ['Joey', 'Monica', 'Chadler', 'Ross', 'Rachel', 'Phoebe']; friends.push('Janice'); // 7 |
.pop() | Es un destructive method que borra el último valor del array. Devuelve un string con el elemento del array recién borrado. let friends = ['Joey', 'Monica', 'Chadler', 'Ross', 'Rachel', 'Phoebe']; friends.pop(); // "Phoebe" |
.length() | Para averiguar el número elementos de un array. let friends = ['Joey', 'Monica', 'Chadler', 'Ross', 'Rachel', 'Phoebe']; console.log(friends.length()); // 6 |
.from() | Convierte un data type en un array. No todos los data types son convertibles, ya que deben tener ciertas características para ello. Por ejemplo, una HTMLCollection puede convertirse en un array usando este método. This is a titlethis is a text this is a text this is a text Article written by Ro
Resultado en consola: ▷ (5) [h3, p, p, p, div] El resultado es en realidad un nuevo array, siendo este método un método no-destructivo. Es decir, si ahora volvemos a hacer un console.log de article.children, el resultado sería nuevamente una HTMLCollection, porque este método no altera el valor inicial del data type. |
.filter()Foto: festack. | Este método tiene un nombre bastante intuitivo, ya que sirve para filtrar los elementos de un array y extraer los que le indiquemos. Por ejemplo, tenemos un array que contiene diferentes puntuaciones que ha conseguido un usuario en un juego. const scores = [14, 40, 34, 28, 37, 2, 8, 92]; Este método acepta un parámetro en forma de callback function. Lo que hace el método es barrer todo el array y aplicar un filtro a cada elemento dentro de su callback function. Si el elemento pasa el filtro, se mantiene en el array. Si no, es expulsado del array. Esto lo hace categorizando cada elemento como true si pasa el filtro o como false si no lo pasa. Por ejemplo, si hiciésemos esto: scores.filter(() => { return true; }); técnicamente no estaríamos filtrando nada, porque JS entiende que le estamos diciendo que devuelva true por cada elemento del array, y eso hace. La forma de utilizar este método es pasándole una condición al return que JS pueda evaluar como true o false. Para crear esa condición, creamos una variable local como parámetro de la callback function y la utilizamos para hacer nuestra comprobación. Por ejemplo, queremos filtrar y quedarnos con todos los números mayores que 30. scores.filter(score => { return score > 30; }); Eso sí, filter es un método no-destructivo, lo que significa que no modifica el valor original del array. Para poder ver el resultado que nos da este método, primero debemos guardarlo en un variable. const scores = [14, 40, 34, 28, 37, 2, 8, 92]; scores.filter(score => { return score > 30; }); const filteredScores = scores.filter(score => { return score > 30; }); console.log(scores); // (8) [14, 40, 34, 28, 37, 2, 8, 92] console.log(filteredScores); // (4) [40, 34, 37, 92] Probemos ahora algo un pelín más complejo. Supongamos que tenemos un array con diferentes objetos, usuarios en este caso. const users = [ { name: "pepe", netflix: true }, { name: "ana", netflix: false }, { name: "chicho", netflix: false }, { name: "katrina", netflix: true } ]; Queremos filtrar y obtener sólo los usuarios que tengan netflix. Podemos hacer un return de la propiedad netflix. JS se encargará de comprobar si esa propiedad es true o false. const netflixUsers = users.filter(user => { return user.netflix; }); console.log(netflixUsers); Verás que ahora la consola nos devuelve los objetos de "pepe" y "katrina". ?Ya que estamos usando un único return statement, podemos simplificar la función librándonos:
const netflixUsers = users.filter(user => user.netflix); |
.map()Foto: festack. | Utilizamos este método cuando queremos crear un nuevo array basado en los elementos de un array existente. Un ejemplo sencillo sería si tenemos un array de precios de productos y queremos aplicarle un descuento a todos ellos. const prices = [30, 22, 38, 12, 4, 50, 95]; Esto lo podríamos hacer con el método map(), creando así un array nuevo de precios con el descuento aplicado sobre ellos. const salePrices = prices.map(price => { return price / 2; }); console.log(salePrices); // (7) [15, 11, 19, 6, 2, 25, 47.5] Lo que hace este método es barrer cada elemento del array, actualizarlo con la condición que le digamos y colocarlo en un nuevo array. Es un método no-destructivo. ?️ Hagamos algo un poco más complicadillo. Tenemos un array de objetos. Son productos con su nombre y su precio. const products = [ { name: "stereo", price: 500 }, { name: "earpods", price: 40 }, { name: "charger", price: 20 }, { name: "monitor", price: 120 }, { name: "keyboard", price: 35 } ]; Vamos a aplicar un descuento del 50% sólo a los productos que valgan más de 100 €. Pero ojo, porque debemos hacer un return de un nuevo objeto. ? Añadimos una cláusula else en caso de que el precio sea menos que 100, porque también queremos mostrar esos productos, solo que no van a sufrir ninguna modificación. const saleProducts = products.map(product => { if (product.price > 100) { return { name: product.name, price: product.price / 2 }; } else { return product; } }); console.log(saleProducts); const saleProducts = products.map(product => { if (product.price > 100) { product.price = product.price / 2; return product; // return { name: product.name, price: product.price / 2 }; } else { return product; } }); Pero el problema con esto es que estamos cambiando directamente el array products, de forma que, si ahora hacemos un console.log de éste, verás que es igual que el array saleProducts. ⚠️ Y esta es la razón por la que debemos crear un nuevo objeto y hacer un return de éste. ? Haz la prueba y comprueba tu consola. console.log(saleProducts); console.log(products) |
.reduce()Foto: festack. | Este método no devuelve necesariamente un nuevo array, sino cualquier valor que le pidamos (un string, un número, etc), basado en los elementos del array que le proporcionemos. Por ejemplo, de este array: const scores = [30, 20, 45, 12, 4, 50, 95]; usando el método reduce podríamos pedirle que nos devolviera cuántos números son mayores que 40. Hay tres números mayores que 40, así que el resultado de aplicar este método sería la obtención de un número, el 3. ? También debemos guardar el nuevo valor en una variable. Este método acepta dos argumentos: una callback function y el valor inicial del accumulator. A su vez, la callback function acepta dos parámetros: el accumulator y el current. Es un método no-destructivo. ?️ El accumulator es el parámetro que lleva la cuenta total. Barre cada elemento del array una vez. No tiene por qué ser un número, también podría ser un objeto, y por cada iteración podríamos añadir una nueva propiedad a ese objeto, que se almacenaría en el accumulator. ? El current es el valor de cada elemento del array. Vamos a hacer un ejemplo en el que vamos a añadir +1 al accumulator si el current es mayor que 40. Como queremos recibir el valor del accumulator al final, hacemos un return de éste cuando JS haya terminado de comprobar si el current es mayor que 40. Nos falta un pequeño detalle, y es el valor inicial del accumulator. Le pasamos éste como segundo parámetro del método map. Le damos el valor de 0. const result = scores.reduce((acc, curr) => { if(curr > 40) { acc++; } return acc; }, 0); console.log(result); // 3 Hagamos otro ejemplo más complicadillo, esta vez con objetos. Tenemos varios objetos con el nombre de un jugador y su puntuación. Un jugador puede haber jugado más de una vez, con lo cual, éso constituye un nuevo objeto. const scores = [ { player: "Susi", score: 30 }, { player: "Max", score: 40 }, { player: "Jim", score: 10 }, { player: "Max", score: 60 } ]; Queremos extraer la suma de la puntuación que ha conseguido Max. El accumulator tiene un valor inicial de 0. Para sacar la puntuación total de Max simplemente sumamos todas sus puntuaciones y hacemos que ése sea el resultado del accumulator, ya que el accumulator es lo que debemos obtener al final (return). const maxTotal = scores.reduce((acc, curr) => { if(curr.player === 'Max') { acc += curr.score; } return acc; }, 0) console.log(maxTotal); // 100 Aquí una (musical) guía de CSS tricks que recoge los métodos filter, map y reduce. ¡Es genial! |
.find() | Este método no-destructivo devuelve el primer valor de un array que cumpla la condición que le indiquemos. Esa condición o filtro se lo indicamos en una callback function. La callback function se disparará una vez por cada elemento del array hasta que encuentre el valor que cumpla con nuestra condición, y nos lo devolverá. Esa condición debe tener forma de un valor true o false. Sintaxis: const myVar = myArray.find((var local) => { return condición true o false de var local; }); Por ejemplo, podemos pedirle que nos extraiga el primer valor más alto que 30. const scores = [10, 20, 45, 12, 4, 50, 95]; const firstHighScore = scores.find((score) => { return score > 30; }); console.log(firstHighScore); // 45 Como solo tenemos un return y una variable local, podemos simplificar el código. const firstHighScore = scores.find(score => score > 30); |
.sort() | Este método también tiene un nombre que evidencia lo que hace. Efectivamente, sirve para ordenar información, ya sea alfabéticamente como de mayor a menor (o a la inversa). Cuando se trata de strings, podemos usar sort() para ordenarlos alfabéticamente. Este método está construido en base a un algoritmo que ordena automáticamente nuestro array de strings sin tener que hacer nada más por nuestra parte. Eso sí, el método no devuelve un nuevo valor, sino que modifica el array original, lo cual lo convierte en un método destructivo. ? const names = ["Susi", "Max", "Jim", "Joyce", "Mike"]; names.sort(); console.log(names); // (5) ["Jim", "Joyce", "Max", "Mike", "Susi"] Sin embargo, este método tiene un comportamiento no tan previsible cuando lo aplicamos a números. ? const scores = [10, 20, 45, 12, 4, 50, 95]; scores.sort() console.log(scores); // (7) [10, 12, 20, 4, 45, 50, 95] Como ves, parece que estén ordenados, pero se salta el 4 y lo coloca por en medio. Esto sucede porque JS no reconoce una combinación de números (como 50), si no que sólo examina el primer número de dicha combinación (5) y lo coloca en la posición correspondiente en base al número 5, no al 50. ? Para arreglar esto, debemos aprender a utilizar el método sort() con una función comparativa (compare function) pasada como argumento del método. Vamos a explicar esto usando un array de objetos. const players = [ { name: "Susi", score: 30 }, { name: "Max", score: 20 }, { name: "Jim", score: 60 }, { name: "Mike", score: 50 }, { name: "Dustin", score: 80 } ]; La compare function admite dos parámetros. Es un standard llamarlos a y b. Estos parámetros representan dos elementos consecutivos del array. Por ejemplo, podrían ser estos dos: { name: "Max", score: 20 } { name: "Jim", score: 60 } donde a representa al primer elemento y b al segundo. Lo que haremos será comparar a y b, que representan a estos dos elementos, y decidir cuál va primero. Queremos ordenarlos de mayor a menor puntuación, así que como 60 es mayor que 20, debemos indicarle que b debe ir primero. Para indicar qué número va primero y cuál después, lo hacemos devolviendo un valor en forma de número:
Para completar nuestro código, debemos hacer una comprobación con un if else statement para indicarle a JS que, cuando compare a y b, debe colocar en primer lugar al valor numérico más alto de los dos. players.sort((a, b) => { if (a.score > b.score) { return -1; } else if (b.score > a.score) { return 1; } else { return 0; } }); console.log(players); // Array(5) // 0: {name: "Dustin", score: 80} // 1: {name: "Jim", score: 60} // 2: {name: "Mike", score: 50} // 3: {name: "Susi", score: 30} // 4: {name: "Max", score: 20} ? Existe una forma más corta de escribir este bloque de código: players.sort((a, b) => b.score - a.score); Para entender esto, debemos recordar que aquí se está haciendo una comprobación, que es una sencilla operación matemática (una resta). El resultado de esa resta nos puede dar un número negativo, uno positivo o un 0. Si es positivo, significa que b es mayor y por tanto debe ir antes que a. Y a la inversa. Aquí una tabla con ejemplos: b 5 2 3 6 1 a 3 4 3 2 9 resultado 2 --> positivo --> b va primero -2 --> negativo --> a va primero 0 --> neutro --> a y b son iguales 4 --> positivo --> b va primero -8 --> negativo --> a va primero Sabiendo esto, ya podemos volver a nuestro array de números y ordenarlos de mayor a menor o a la inversa. const scores = [10, 20, 45, 12, 4, 50, 95]; scores.sort((a, b) => b - a); console.log(scores); // (7) [95, 50, 45, 20, 12, 10, 4] |
.reverse() | Este método le da la vuelta al array al que se lo apliquemos. También es un método destructivo. ? Podemos usarlo tanto con strings como con números. const names = ["Susi", "Max", "Jim", "Joyce", "Mike"]; names.reverse(); console.log(names); // (5) ["Mike", "Joyce", "Jim", "Max", "Susi"] const scores = [10, 20, 45, 12, 4, 50, 95]; scores.reverse(); console.log(scores); // (7) [95, 50, 4, 12, 45, 20, 10] |
Encadenando métodos ⛓️
Cuando utilizamos varios métodos sobre el mismo array, existe la posibilidad de que los encadenemos entre sí para así producir menos líneas de código y aplicar el principio DRY (Do not Repeat Yourself).
Hagamos un ejemplo.
Tenemos un array de objetos, cada uno con las mismas dos propiedades, "nombre" y "precio".
const products = [ { name: "stereo", price: 500 }, { name: "earpods", price: 40 }, { name: "charger", price: 20 }, { name: "monitor", price: 120 }, { name: "keyboard", price: 35 } ];
Queremos hacer dos cosas con este array: quedarnos solo con los productos que tengan un precio superior a 100 y aplicarles un descuento del 50% a esos productos.
Para eso podemos usar dos métodos: filter y map. Esta sería la manera larga de hacerlo:
const filtered = products.filter(product => product.price > 100); const specialDiscount = filtered.map(product => `Product with 50% discount applied, new price: ${product.price / 2}`); console.log(specialDiscount); // (2) ["Product with 50% discount applied, new price: 250", "Product with 50% discount applied, new price: 60"]
Hemos creado dos variables, pero podríamos encadenar los métodos, de manera que solo tuviésemos que crear una variable:
const specialDiscount = products .filter(product => product.price > 100) .map(product => `Product with 50% discount applied, new price: ${product.price / 2}`);
Este sería el formato más habitual, escribiendo una línea por cada método, para que sea más fácil su lectura. ?
THE END!
¡Y con esto terminamos nuestro repaso a los métodos más comunes de los arrays! Espero que hayas aprendido algo nuevo ?. Si te queda alguna duda, ¡nos vemos en los comentarios!
Y si crees que este post puede serle útil a alguien, ¡compártelo!
Otros artículos que pueden interesarte