Arrays Methods Javascript
Arrays Methods Javascript
Los arrays (también llamados arreglos o matrices) cuentan con muchos métodos. Para hacer las cosas más
sencillas, en este capítulo se encuentran divididos en dos partes.
Agregar/remover ítems
Ya conocemos algunos métodos que agregan o extraen elementos del inicio o final de un array:
splice
Los arrays son objetos, por lo que podemos intentar con delete :
✍
1 let arr = ["voy", "a", "casa"];
2
3 delete arr[1]; // remueve "a"
4 alert( arr[1] ); //
5 undefined
6
7 // ahora arr = ["voy", , "casa"];
8 alert( arr.length ); // 3
El elemento fue borrado, pero el array todavía tiene 3 elementos; podemos ver que arr.length == 3 .
Es natural, porque delete obj.key borra el valor de key , pero es todo lo que hace. Esto está bien en los
objetos, pero en general lo que buscamos en los arrays es que el resto de los elementos se desplace y se ocupe
el lugar libre. Lo que esperamos es un array más corto.
El método arr.splice funciona como una navaja suiza para arrays. Puede hacer todo: insertar, remover y
remplazar elementos.
La sintaxis es:
Esto modifica arr comenzando en el índice start : remueve la cantidad deleteCount de elementos y luego
inserta elem1, ..., elemN en su lugar. Lo que devuelve es un array de los elementos removidos.
"Yo", "estudio", ✍
1 let arr = ["
a
h
o
r
"
,m
i
s
o
"
]
;"JavaScript",
2
3 // remueve los primeros 3 elementos y
4 los reemplaza con otros arr.splice(0, 3, "a", "bailar");
5 alert( arr ) // ahora ["a", "bailar", "ahora",
6 "mismo"]
Aquí podemos ver que splice devuelve un array con los elementos removidos:
✍
1 let arr = ["Yo", "estudio", "JavaScript"];
2
3 // desde el index 2
4 // remover 0
5 // después insertar "el", "complejo" y "language"
2/22
Los índices negativos están permitidos
En este y en otros métodos de arrays, los índices negativos están permitidos. Estos índices indican la
posición comenzando desde el final del array, de la siguiente manera:
slice
El método arr.slice es mucho más simple que arr.splice .
La sintaxis es:
1 arr.slice([principio], [final])
Devuelve un nuevo array copiando en el mismo todos los elementos desde principio hasta final (sin incluir
final ). principio y final pueden ser negativos, en cuyo caso se asume la posición desde el final del array.
Es similar al método para strings str.slice , pero en lugar de substrings genera subarrays.
Por ejemplo:
✍
1 let arr = ["t", "e", "s", "t"];
2
3 alert( arr.slice(1, 3) ); // e,s (copia desde 1 hasta 3)
4 alert( arr.slice(-2) ); // s,t (copia desde -2 hasta el
5 final)
También podemos invocarlo sin argumentos: arr.slice() crea una copia de arr . Se utiliza a menudo para
obtener una copia que se puede transformar sin afectar el array original.
concat
El método arr.concat crea un nuevo array que incluye los valores de otros arrays y elementos adicionales.
La sintaxis es:
1 arr.concat(arg1, arg2...)
El resultado es un nuevo array conteniendo los elementos de arr , después arg1 , arg2 etc.
3/22
Si un argumento argN es un array, entonces todos sus elementos son copiados. De otro modo el argumento en
sí es copiado.
Por ejemplo:
✍
1
let arr = [1, 2];
2
3
// crea un array a partir de: arr y [3,4]
4
alert( arr.concat([3, 4]) ); // 1,2,3,4
5
6
// crea un array a partir de: arr y [3,4] y [5,6]
7
alert( arr.concat([3, 4], [5, 6]) ); // 1,2,3,4,5,6
8
// crea un array a partir de: arr y [3,4], luego agrega los valores 5
9
y 6 alert( arr.concat([3, 4], 5, 6) ); // 1,2,3,4,5,6
10
Normalmente, solo copia elementos desde arrays. Otros objetos, incluso si parecen arrays, son agregados como
un todo:
✍
1
let arr = [1, 2];
2
3
let arrayLike = {
4
0: "something",
5
length: 1
6
}; alert( arr.concat(arrayLike) ); // 1,2,[object
7
Object]
8
7 length: 2
8 }; alert( arr.concat(arrayLike) ); //
9 1,2,something,else
10
Iteración: forEach
El método arr.forEach permite ejecutar una función a cada elemento del array.
La sintaxis:
4/22
1 arr.forEach(function(item, index, array) {
2 // ... hacer algo con el elemento
3 });
✍
1 // para cada elemento ejecuta alert
2 ["Bilbo", "Gandalf", "Nazgul"].forEach(alert);
✍
1
["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) =>
2
{ alert(`${item} is at index ${index} in ${array}`); });
3
indexOf/lastIndexOf e includes
Los métodos arr.indexOf, arr.lastIndexOf y arr.includes tienen la misma sintaxis y hacen básicamente lo mismo
que sus contrapartes de strings, pero operan sobre elementos en lugar de caracteres:
● arr.indexOf(item, from) – busca item comenzando desde el index from , y devuelve el index donde
fue encontrado, de otro modo devuelve -1 .
● arr.lastIndexOf(item, from) – igual que el anterior, pero busca de derecha a izquierda.
● arr.includes(item, from) – busca item comenzando desde el índice from , devuelve true en caso de
ser encontrado.
Por ejemplo:
✍
1 let arr = [1, 0, false];
2
3 alert( arr.indexOf(0) ); // 1
4 alert( arr.indexOf(false) ); // 2
5 alert( arr.indexOf(null) ); // -1
6 alert( arr.includes(1) ); //
7 true
Tener en cuenta que el método usa comparación estricta ( === ). Por lo tanto, si buscamos false , encontrará
exactamente false y no cero.
Si queremos comprobar si un elemento está incluido y no necesitamos saber su ubicación exacta, es preferible
usar arr.includes
5/22
Además, una pequeña diferencia de includes es que puede manejar correctamente NaN a diferencia de
indexOf/lastIndexOf :
find y findIndex
Imaginemos que tenemos un array de objetos. ¿Cómo podríamos encontrar un objeto con una condición
específica?
La función es llamada para cada elemento del array, uno después del otro:
● item es el elemento.
● index es su índice.
● array es el array mismo.
Si devuelve true , la búsqueda se detiene y el item es devuelto. Si no encuentra nada, entonces devuelve
undefined .
Por ejemplo, si tenemos un array de usuarios, cada uno con los campos id y name . Encontremos el elemento
con id == 1 :
✍
1
let users = [
2
{id: 1, name: "Celina"},
3
{id: 2, name: "David"},
4
{id: 3, name: "Federico"}
5
];
6
let user = users.find(item => item.id == 1);
7
alert(user.name); //
8
Celina
9
En la vida real los arrays de objetos son bastante comunes por lo que el método find resulta muy útil.
Ten en cuenta que en el ejemplo anterior le pasamos a find la función item => item.id == 1 con un
argumento. Esto es lo más común, otros argumentos son raramente usados en esta función.
6/22
El método arr.findIndex es esencialmente lo mismo, pero devuelve el índice donde el elemento fue encontrado
El método find busca un único elemento (el primero) que haga a la función devolver true .
La sintaxis es similar a find , pero filter devuelve un array con todos los elementos encontrados:
Por ejemplo:
✍
1 let users = [
2 {id: 1, name: "Celina"},
3 {id: 2, name: "David"},
4 {id: 3, name: "Federico"}
5 ];
6
7 // devuelve un array con los dos primeros usuarios
8 let someUsers = users.filter(item => item.id < 3);
9 alert(someUsers.length); //
10 2
Transformar un array
Pasamos ahora a los métodos que transforman y reordenan un array.
map
El método arr.map es uno de los métodos más comunes y ampliamente usados.
Este método llama a la función para cada elemento del array y devuelve un array con los resultados.
La sintaxis es:
Por ejemplo, acá transformamos cada elemento en el valor de su respectivo largo (length):
✍
1 let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item =>
2 item.length); alert(lengths); // 5,7,6
7/22
sort(fn)
Cuando usamos arr.sort(), este ordena el propio array cambiando el orden de los elementos.
También devuelve un nuevo array ordenado pero éste usualmente se descarta ya que arr en sí mismo es
modificado.
Por ejemplo:
✍
1 let arr = [ 1, 2, 15 ];
2
3 // el método reordena el contenido de arr
4 arr.sort();
5 alert( arr ); // 1, 15,
6 2
Los elementos fueron reordenados a 1, 15, 2 . Pero ¿por qué pasa esto?
Los elementos son ordenados como strings (cadenas de caracteres) por defecto
Todos los elementos son literalmente convertidos a string para ser comparados. En el caso de strings se aplica
el orden lexicográfico, por lo que efectivamente "2" > "15" .
Para usar nuestro propio criterio de reordenamiento, necesitamos proporcionar una función como argumento
de arr.sort() .
1 function compare(a, b) {
2 if (a > b) return 1; // si el primer valor es mayor que el segundo
3 if (a == b) return 0; // si ambos valores son iguales
4 if (a < b) return -1; // si el primer valor es menor que el segundo
5 }
1 ✍
2
3 function compareNumeric(a, b) {
4 if (a > b) return 1; if (a == b)
5 return 0; if (a < b) return -1;
6 }
7 let arr = [ 1, 2, 15 ];
8
9 arr.sort(compareNumeric);
1 alert(arr); // 1, 2, 15
0
11
Ahora sí funciona como esperábamos.
Detengámonos un momento y pensemos qué es lo que está pasando. El array arr puede ser un array de
cualquier cosa, ¿no? Puede contener números, strings, objetos o lo que sea. Podemos decir que tenemos un
8/22
conjunto de ciertos items. Para ordenarlos, necesitamos una función de ordenamiento que sepa cómo comparar
los elementos. El orden por defecto es hacerlo como strings.
Por cierto, si queremos saber qué elementos son comparados, nada nos impide ejecutar alert() en ellos:
✍
1 [1, -2, 15, 2, 0, 8].sort(function(a, b)
2 { alert( a + " <> " + b ); return a -
3 b;
4 });
El algoritmo puede comparar un elemento con muchos otros en el proceso, pero trata de hacer la menor
cantidad de comparaciones posible.
1 let arr = [ 1, 2, 15 ]; ✍
2
3 arr.sort(function(a, b) { return a - b; });
4
5 alert(arr); // 1, 2, 15
9/22
Mejor, con funciones de flecha
¿Recuerdas las arrow functions? Podemos usarlas en este caso para un ordenamiento más prolijo:
Para muchos alfabetos, es mejor usar el método str.localeCompare para ordenar correctamente letras
como por ejemplo Ö .
reverse
El método arr.reverse revierte el orden de los elementos en arr .
Por ejemplo:
y join
Analicemos una situación de la vida real. Estamos programando una app de mensajería y y el usuario ingresa
una lista de receptores delimitada por comas: Celina, David, Federico . Pero para nosotros un array sería
mucho más práctico que una simple string. ¿Cómo podemos hacer para obtener un array?
10/22
El método str.split(delim) hace precisamente eso. Separa la string en elementos según el delimitante delim
dado y los devuelve como un array.
El método split tiene un segundo argumento numérico opcional: un límite en la extensión del array. Si se
provee este argumento, entonces el resto de los elementos son ignorados. Sin embargo en la práctica rara vez
se utiliza:
✍
1 let arr = 'Bilbo, Gandalf, Nazgul, Saruman'.split(', ', 2);
2 alert(arr); // Bilbo,
3 Gandalf
Separar en letras
El llamado a split(s) con un s vacío separará el string en un array de letras:
arr.join(glue) hace lo opuesto a split . Crea una string de arr elementos unidos con glue (pegamento)
entre ellos.
Por ejemplo:
✍
1 let arr = ['Bilbo', 'Gandalf', 'Nazgul'];
2 let str = arr.join(';'); // une el array en una string
3 usando ;
4 alert( str ); //
5 Bilbo;Gandalf;Nazgul
reduce/reduceRight
Cuando necesitamos iterar sobre un array podemos usar forEach , for o for..of .
Cuando necesitamos iterar y devolver un valor por cada elemento podemos usar map .
Los métodos arr.reduce y arr.reduceRight también pertenecen a ese grupo de acciones pero son un poco más
complejos. Se los utiliza para calcular un único valor a partir del array.
11/22
La sintaxis es la siguiente:
La función es aplicada a todos los elementos del array, uno tras de otro, y va arrastrando el resultado parcial al
próximo llamado.
Argumentos:
● accumulator – es el resultado del llamado previo de la función, equivale a initial la primera vez (si
initial es dado como argumento).
● item – es el elemento actual del array.
● index – es la posición.
● array – es el array.
Mientras la función sea llamada, el resultado del llamado anterior se pasa al siguiente como primer argumento.
Entonces, el primer argumento es el acumulador que almacena el resultado combinado de todas las veces
anteriores en que se ejecutó, y al final se convierte en el resultado de reduce .
¿Suena complicado?
5
alert(result); // 15
1. En la primera pasada, sum es el valor initial (el último argumento de reduce ), equivale a 0 , y current
es el primer elemento de array, equivale a 1 . Entonces el resultado de la función es 1 .
2. En la segunda pasada, sum = 1 , agregamos el segundo elemento del array ( 2 ) y devolvemos el valor. 3.
En la tercera pasada, sum = 3 y le agregamos un elemento más, y así sucesivamente… El flujo de cálculos:
1 2 3 4 5
12/22
O en la forma de una tabla, donde cada fila representa un llamado a una función en el próximo elemento del
array:
primer llamado 0 1 1
segundo llamado 1 2 3
tercer llamado 3 3 6
cuarto llamado 6 4 10
quinto llamado 10 5 15
Acá podemos ver claramente como el resultado del llamado anterior se convierte en el primer argumento del
llamado siguiente.
✍
1
let arr = [1, 2, 3, 4, 5];
2
// valor inicial removido (no 0) let result =
3
arr.reduce((sum, current) => sum + current);
4
alert( result ); //
5
15
6
El resultado es el mismo. Esto es porque en el caso de no haber valor inicial, reduce toma el primer elemento
del array como valor inicial y comienza la iteración a partir del segundo elemento.
Pero este tipo de uso requiere tener extremo cuidado. Si el array está vacío, entonces el llamado a reduce sin
valor inicial devuelve error.
✍
1 let arr = [];
2
3 // Error: Reduce en un array vacío sin valor inicial
4 // si el valor inicial existe, reduce lo devuelve en el arr vacío.
5 arr.reduce((sum, current) => sum + current);
Array.isArray
Los arrays no conforman un tipo diferente. Están basados en objetos.
1 ✍
13/22
2 alert(typeof {}); // object
alert(typeof []); // object
…Pero los arrays son utilizados tan a menudo que tienen un método especial para eso: Array.isArray(value). Este
devuelve true si el valor es un array y false si no lo es.
✍
1 alert(Array.isArray({})); // false
2 alert(Array.isArray([])); //
3 true
Ese parámetro no está explicado en la sección anterior porque es raramente usado. Pero para ser exhaustivos
necesitamos verlo.
1 arr.find(func, thisArg);
2 arr.filter(func, thisArg);
3 arr.map(func, thisArg);
4 // ...
5 // thisArg es el último argumento opcional
Por ejemplo, acá usamos un método del objeto army como un filtro y thisArg da el contexto:
1 ✍
2
3
4
let army = { minAge: 18, maxAge: 27, canJoin(user) {
5
return user.age >= this.minAge && user.age < this.maxAge;
6
}
7
}; let users =
8
[ {age: 16},
9
{age: 20},
1
{age: 23},
0
{age: 30}
11
];
12
13
// encuentra usuarios para los cuales army.canJoin devuelve true
14
let soldiers = users.filter(army.canJoin, army);
15
16
alert(soldiers.length); // 2 alert(soldiers[0].age);
17
// 20 alert(soldiers[1].age); // 23
18
19
20
21
14/22
Si en el ejemplo anterior usáramos users.filter(army.canJoin) , entonces army.canJoin sería llamada
como una función independiente con this=undefined , lo que llevaría a un error inmediato.
Resumen
Veamos el ayudamemoria de métodos para arrays:
● map(func) – crea un nuevo array a partir de los resultados de llamar a la func para cada elemento.
● sort(func) – ordena el array y lo devuelve.
● reverse() – ordena el array de forma inversa y lo devuelve.
● split/join – convierte una cadena en un array y viceversa.
● reduce/reduceRight(func, initial) – calcula un solo valor para todo el array, llamando a la func
para cada elemento, obteniendo un resultado parcial en cada llamada y pasándolo a la siguiente.
● Adicional:
Por favor tener en cuenta que sort , reverse y splice modifican el propio array.
Estos métodos son los más utilizados y cubren el 99% de los casos. Pero existen algunos más:
15/22
● arr.some(fn)/arr.every(fn) comprueba el array.
La función fn es llamada para cada elemento del array de manera similar a map . Si alguno/todos los
resultados son true , devuelve true , si no, false .
Estos métodos se comportan con similitud a los operadores || y && : si fn devuelve un valor verdadero,
arr.some() devuelve true y detiene la iteración de inmediato; si fn devuelve un valor falso, arr.every()
devuelve false y detiene la iteración también.
● arr.fill(value, start, end) – llena el array repitiendo value desde el índice start hasta end .
● arr.copyWithin(target, start, end) – copia sus elementos desde la posición start hasta la posición end en
si mismo, a la posición target (reescribe lo existente).
A primera vista puede parecer que hay demasiados métodos para aprender y un tanto difíciles de recordar. Pero
con el tiempo se vuelve más fácil.
Revisa el ayudamemoria para conocerlos. Después realiza las prácticas de este capítulo para ganar experiencia
con los métodos para arrays.
Finalmente si en algún momento necesitas hacer algo con un array y no sabes cómo, vuelve a esta página, mira
el ayudamemoria y encuentra el método correcto. Los ejemplos te ayudarán a escribirlos correctamente y
pronto los recordarás automáticamente y sin esfuerzo.
✔ Tareas
Escribe la función camelize(str) que convierta palabras separadas por guión como “mi-cadena-corta” en
palabras con mayúscula “miCadenaCorta”.
Esto sería: remover todos los guiones y que cada palabra después de un guión comience con mayúscula.
Ejemplos:
16/22
1 camelize("background-color") == 'backgroundColor'; camelize("list-style-
2 image") == 'listStyleImage'; camelize("-webkit-transition") ==
3 'WebkitTransition';
P.D. Pista: usa split para dividir el string en un array, transfórmalo y vuelve a unirlo ( join ).
Filtrar un rango
importancia: 4
Escribe una función filterRange(arr, a, b) que obtenga un array arr , busque los elementos con valor
mayor o igual a a y menor o igual a b y devuelva un array con los resultados.
Por ejemplo:
1
2 let arr = [5, 3, 8, 1];
3 let filtered = filterRange(arr, 1,
4 4);
5 alert( filtered ); // 3,1 (valores dentro del rango)
6 alert( arr ); // 5,3,8,1 (array original no
7 modificado)
Escribe una función filterRangeInPlace(arr, a, b) que obtenga un array arr y remueva del mismo todos
los valores excepto aquellos que se encuentran entre a y b . El test es: a ≤ arr[i] ≤ b .
Por ejemplo:
17/22
1 let arr = [5, 2, 1, -10, 8];
2
3 // ... tu código para ordenar en orden decreciente
4 alert( arr ); // 8, 5, 2, 1, -
5 10
Supongamos que tenemos un array arr . Nos gustaría tener una copia ordenada del mismo, pero mantener
arr sin modificar.
1
let arr = ["HTML", "JavaScript", "CSS"];
2
3
let sorted = copySorted(arr);
4
alert( sorted ); // CSS, HTML, JavaScript alert(
5
arr ); // HTML, JavaScript, CSS (sin cambios)
6
1.
Primero, implementar el método calculate(str) que toma un string como "1 + 2" en el formato
“NUMERO operador NUMERO” (delimitado por espacios) y devuelve el resultado. Debe entender más + y
menos - .
Ejemplo de uso:
2.
Luego agrega el método addMethod(name, func) que enseñe a la calculadora una nueva operación. Toma
el operador name y la función con dos argumentos func(a,b) que lo implementa.
18/22
1 let powerCalc = new Calculator;
2 powerCalc.addMethod("*", (a, b) => a * b);
3 powerCalc.addMethod("/", (a, b) => a / b);
4 powerCalc.addMethod("**", (a, b) => a ** b);
5
6 let result = powerCalc.calculate("2 ** 3");
7 alert( result ); // 8
Mapa a nombres
importancia: 5
Tienes un array de objetos user , cada uno tiene user.name . Escribe el código que lo convierta en un array de
nombres.
Por ejemplo:
Mapa a objetos
importancia: 5
Escribe el código para crear otro array a partir de este, de objetos con id y fullName , donde fullName es
generado a partir de name y surname .
Por ejemplo:
19/22
1 let john = { name: "John", surname: "Smith", id: 1 };
2 let pete = { name: "Pete", surname: "Hunt", id: 2 };
3 let mary = { name: "Mary", surname: "Key", id: 3 };
4
5 let users = [ john, pete, mary ];
6
7 let usersMapped = /* ... tu código ... */
8
9 /*
10 usersMapped = [
11 { fullName: "John Smith", id: 1 },
12 { fullName: "Pete Hunt", id: 2 },
13 { fullName: "Mary Key", id: 3 }
14 ]
15 */ alert( usersMapped[0].id ) // 1 alert(
16 usersMapped[0].fullName ) // John Smith
17
18
Entonces, en realidad lo que necesitas es mapear un array de objetos a otro. Intenta usar => en este caso. Hay
un pequeño truco.
Escribe la función sortByAge(users) que cree un array de objetos con al propiedad age y los ordene según
age .
Por ejemplo:
20/22
Barajar un array
importancia: 3
Escribe la función shuffle(array) que baraje (reordene de forma aleatoria) los elementos del array.
Múltiples ejecuciones de shuffle puede conducir a diferentes órdenes de elementos. Por ejemplo:
Todos los reordenamientos de elementos tienen que tener la misma probabilidad. Por ejemplo, [1,2,3] puede
ser reordenado como [1,2,3] o [1,3,2] o [3,1,2] etc, con igual probabilidad en cada caso.
Obtener edad promedio
importancia: 4
Escribe la función getAverageAge(users) que obtenga un array de objetos con la propiedad age y devuelva el
promedio de age .
Por ejemplo:
Crea una función unique(arr) que devuelva un array con los elementos que se encuentran una sola vez dentro
de arr .
Por ejemplo:
21/22
1
2 function unique(arr) {
3 /* tu código */
4 } let strings = ["Hare", "Krishna", "Hare",
5 "Krishna",
6 "Krishna", "Krishna", "Hare", "Hare", ":-O"
7 ]; alert( unique(strings) ); // Hare,
8 Krishna, :-O
9
Supongamos que recibimos un array de usuarios con la forma {id:..., name:..., age:... } .
Crea una función groupById(arr) que cree un objeto, con id como clave (key) y los elementos del array como
valores.
Por ejemplo:
1
2
let users = [
3
{id: 'john', name: "John Smith", age: 20},
4
{id: 'ann', name: "Ann Smith", age: 24},
5
{id: 'pete', name: "Pete Peterson", age: 31},
6
];
7
let usersById = groupById(users);
8
/*
9
// después de llamar a la función deberíamos tener:
10
usersById =
11
{
12
john: {id: 'john', name: "John Smith", age: 20},
13
ann: {id: 'ann', name: "Ann Smith", age: 24},
14
pete: {id: 'pete', name: "Pete Peterson", age: 31},
15
} */
16
17
Dicha función es realmente útil cuando trabajamos con información del servidor.
Para esta actividad asumimos que cada id es único. No existen dos elementos del array con el mismo id .
22/22