A medida que trabajamos en nuestro código, se hace necesario agrupar valores en una misma variable, para representar conjuntos de datos con cierta relación entre sí. Para ello, tenemos la opción de crear objetos, o unas variables más sencillas llamadas arrays.
¿Qué es un array?
Un
Constructor | Descripción |
---|---|
new Array( size) | Crea un array vacío de tamaño size . Sus valores no están definidos, pero son |
new Array(e1, e2...) | Crea un array con los elementos indicados. |
[e1, e2...] | Simplemente, los elementos dentro de corchetes: [] . Notación preferida. |
Por ejemplo, podríamos tener un array que en su primera posición tenemos el
// Forma tradicional (no se suele usar en Javascript)
const letters = new Array("a", "b", "c"); // Array con 3 elementos
const letters = new Array(3); // Array vacío de tamaño 3
// Mediante literales (notación preferida)
const letters = ["a", "b", "c"]; // Array con 3 elementos
const letters = []; // Array vacío (0 elementos)
const letters = ["a", 5, true]; // Array mixto (String, Number, Boolean)
Al contrario que muchos otros lenguajes de programación, Javascript permite que se puedan realizar arrays de tipo mixto, no siendo obligatorio que todos los elementos sean del mismo tipo de dato.
OJO: Al crear un array con
new Array(size)
hay varios matices que merece la pena mencionar. Lo primero, si sólo se indica un parámetro numéricosize
, Javascript creará un array vacío desize
elementos. Es decir, no es lo mismo queconst a = [3]
, donde creamos un array con un elemento3
. Por otro lado,new Array(size)
realmente crea un array vacío que aún no ha sido rellenado con nada (esto hace que sea más óptimo para arrays grandes) y aunque es equivalente, no es exactamente igualnew Array(3)
que[undefined, undefined, undefined]
.
Acceso a elementos del array
Al igual que los .length
, que nos devolverá el número de elementos existentes en un array:
Forma | Descripción |
---|---|
.length | Propiedad que devuelve el número de elementos del array. |
[pos] | Operador que devuelve (o modifica) el elemento número pos del array. |
.at(pos) | Método que devuelve el elemento en la posición pos . Números negativos en orden inverso. |
.with(pos, el) | Método que crea una copia y modifica el elemento de la posición pos con el . |
Veamos como funcionan.
El operador []
Por otro lado, si lo que queremos es acceder a un elemento específico del array, no hay más que utilizar el operador []
, al igual que lo podríamos hacer con los
const letters = ["a", "b", "c"];
letters.length; // 3
letters[0]; // 'a'
letters[2]; // 'c'
letters[5]; // undefined
Recuerda que las posiciones empiezan a contar desde 0
y que si intentamos acceder a una posición que no existe (mayor del tamaño del array), nos devolverá un
El operador []
no sólo nos permite obtener o acceder a un elemento del array, sino que también nos permite modificar un elemento específico del array, si utilizamos la asignación:
const letters = ["a", "b", "c"];
letters[1] = "Z"; // Devuelve "Z" y modifica letters a ["a", "Z", "c"]
letters[3] = "D"; // Devuelve "D" y modifica letters a ["a", "Z", "c", "D"]
letters[5] = "A"; // Devuelve "A" y modifica letters a ["a", "Z", "c", "D", undefined, "A"]
El método .with()
Ten en cuenta que con el nuevo método .with()
, se puede hacer esto de una forma más cómoda y sin modificar el array original. Permite encadenar múltiples operaciones, pero ten en cuenta que sólo modifica, no se pueden añadir elementos que no existen antes en el array:
const letters = ["a", "b", "c"];
letters.with(1, "Z"); // Devuelve "Z" y modifica letters a ["a", "Z", "c"]
letters.with(1, "Z")
.with(3, "D"); // No se puede hacer porque la posición 3 no existe
letters.with(5, "A"); // No se puede hacer porque la posición 5 no existe
El método .at()
Además del clásico operador []
, también podemos utilizar el método .at()
, añadido en Javascript [pos]
, sólo que además permite valores negativos, mediante los cuales se puede obtener elementos en orden inverso, es decir, empezando a contar desde el último elemento:
const letters = ["a", "b", "c"];
letters.at(0); // "a"
letters.at(1); // "b"
letters.at(3); // undefined
letters.at(-1); // "c"
letters.at(-2); // "b"
Esta característica hace que acceder al último elemento (o cercanos) sea bastante práctico, ya que hacer la misma operación con el operador []
era algo menos directo que en algunos casos se podría volver confuso o poco intuitivo:
const letters = ["a", "b", "c"];
const lastItem = letters.length - 1;
letters[lastItem]; // "c"
El soporte del método .at()
es muy bueno en navegadores actuales:
Añadir o eliminar elementos
Existen varias formas de añadir elementos a un array ya existente. Ten en cuenta que en todos estos casos estamos mutando (variando los elementos del array ya existente). Veamos los métodos que podemos usar para ello:
Método | Descripción |
---|---|
.push(e1, e2, e3...) ⚠️ | Añade uno o varios elementos al final del array. Devuelve el tamaño del array. |
.pop() ⚠️ | Elimina el último elemento del array. Devuelve dicho elemento. |
.unshift(e1, e2, e3...) ⚠️ | Añade uno o varios elementos al inicio del array. Devuelve el tamaño del array. |
.shift() ⚠️ | Elimina el primer elemento del array. Devuelve dicho elemento. |
⚠️ Recuerda que estos métodos sirven para modificar (mutar) el array original.
En los arrays, Javascript proporciona métodos tanto para insertar o eliminar elementos por el final del array, como por el principio:
- Los métodos
.push()
y.pop()
actuan al final del array. - Los métodos
.unshift()
y.shift()
actuan al inicio del array.
Veámoslos en acción:
const elements = ["a", "b", "c"]; // Array inicial
elements.push("d"); // Devuelve 4. Ahora elements = ['a', 'b', 'c', 'd']
elements.pop(); // Devuelve 'd'. Ahora elements = ['a', 'b', 'c']
elements.unshift("Z"); // Devuelve 4. Ahora elements = ['Z', 'a', 'b', 'c']
elements.shift(); // Devuelve 'Z'. Ahora elements = ['a', 'b', 'c']
Salvo por esto, funcionan exactamente igual. Los métodos de inserción .push()
o .unshift()
insertan los elementos pasados por parámetro en el array y devuelve el tamaño actual que tiene el array después de la inserción. Por otro lado, los métodos de extracción, .pop()
o .shift()
, extraen y devuelven el elemento extraído.
Alternativas para crear arrays
Aunque hemos visto las formas principales de crear un
Algunos de estos casos son los siguientes:
Método | Descripción |
---|---|
Array.from(obj) | Intenta convertir el obj en un array. |
Array.from(obj, fmap) | Idem, pero ejecuta la función fmap por cada elemento. Equivalente a .map() |
Array.from({ length: size}) | Crea un array a partir de un size , relleno de |
.concat(e1, e2, e3...) | Devuelve los elementos pasados por parámetro concatenados al final del array. |
.join(sep) | Une los elementos del array mediante separadores sep en un |
Vamos a analizar cada uno de estos métodos y poner algunos ejemplos.
Convertir a array
El método estático Array.from()
, aunque ahora quizás no le encontremos mucha utilidad, nos resultará muy interesante más adelante. Este método se suele utilizar para convertir variables «parecidas» a los arrays (pero que no son arrays) en un
const text = "12345";
text.constructor.name; // "String"
const letters = Array.from(text); // ["1", "2", "3", "4", "5"]
const letters = [...text]; // ["1", "2", "3", "4", "5"]
const divs = document.querySelectorAll("div");
divs.constructor.name; // "NodeList"
const elements = Array.from(divs); // [div, div, div]
const elements = [...divs]; // [div, div, div]
Como se puede ver, es algo muy similar a lo que hacemos con la desestructuración de arrays. Pero no todos los elementos se pueden convertir a arrays. Por ejemplo, si intentamos convertir un undefined
o un null
, nos dará un error similar a Uncaught TypeError: null is not iterable.
De forma opcional, Array.from(obj)
puede recibir un parámetro adicional: una función que actuará de forma idéntica a una función map(). Veamos el funcionamiento:
const text = "12345";
const numbers = Array.from(text, (number) => Number(number)); // [1, 2, 3, 4, 5]
const numbers = Array.from(text, Number); // Equivalente al anterior
// Equivalente a los dos anteriores
const numbers = [...text].map(Number);
Observa que en este caso, la función pasada por segundo parámetro del Array.from()
se ejecutará por cada uno de los elementos de text
, y en este caso concretamente, la función (number) => Number(number)
fuerza a convertir cada elemento en un número. La diferencia respecto al ejemplo anterior, es que en este caso obtienes un array de números, mientras que el anterior obtenías un array de textos.
Si lo que buscas es convertir un objeto
de Javascript en un , probablemente te interese el tema de Iteradores de objetos donde vemos métodos como Object.keys()
,Object.values()
uObject.entries()
.
Concatenar arrays
Al igual que en los concat()
, que nos permite unir los elementos pasados por parámetro en un array a la estructura que estamos manejando. Se podría pensar que los métodos .push()
y concat()
funcionan de la misma forma, pero no es exactamente así. Veamos un ejemplo:
const elements = [1, 2, 3];
elements.push(4, 5, 6); // Devuelve 6. Ahora elements = [1, 2, 3, 4, 5, 6]
elements.push([7, 8, 9]); // Devuelve 7. Ahora elements = [1, 2, 3, 4, 5, 6, [7, 8, 9]]
Ahora veamos el mismo ejemplo realizado con el método .concat()
:
const firstPart = [1, 2, 3];
const secondPart = [4, 5, 6];
firstPart.concat(firstPart); // Devuelve [1, 2, 3, 1, 2, 3]
firstPart.concat(secondPart); // Devuelve [1, 2, 3, 4, 5, 6]
// Se pueden pasar elementos sueltos
firstPart.concat(4, 5, 6); // Devuelve [1, 2, 3, 4, 5, 6]
// Se pueden concatenar múltiples arrays e incluso mezclarlos con elementos sueltos
firstPart.concat(firstPart, secondPart, 7); // Devuelve [1, 2, 3, 1, 2, 3, 4, 5, 6, 7]
Observa un detalle muy importante: El método concat()
, a diferencia de push()
, no modifica el array sobre el cuál trabajamos y al que le añadimos los elementos, sino que simplemente lo devuelve. Al margen de esto, observa que en el caso de pasar un array por parámetro, push()
lo inserta como un array, mientras que concat()
inserta cada uno de sus elementos.
También hay que tener cuidado al utilizar el operador
+
con los arrays. A diferencia de lo que quizás puede parecer intuitivo, utilizando este operador no se añaden los elementos al array, sino que se convierten los arrays en string y luego se concatenan. Veremos más sobre estas conversiones implícitas en temas posteriores.
Separar y unir strings
Además, también tenemos otro método con el que es posible crear un .split()
que vimos en el tema de los .join()
es su contrapartida. Con .join()
podemos crear un
const letters = ["a", "b", "c"];
// Une elementos del array por el separador indicado
letters.join("->"); // Devuelve 'a->b->c'
letters.join("."); // Devuelve 'a.b.c'
// Separa elementos del string por el separador indicado
"a.b.c".split("."); // Devuelve ['a', 'b', 'c']
"5-4-3-2-1".split("-"); // Devuelve ['5', '4', '3', '2', '1']
Ten en cuenta que, como se puede ver en los ejemplos, .join()
siempre devolverá los elementos como .split()
devolverá un
Observa un caso especial, en el que pasamos un cadena de texto .split()
:
"Hola a todos".split(""); // ['H', 'o', 'l', 'a', ' ', 'a', ' ', 't', 'o', 'd', 'o', 's']
En este caso, le hemos pedido dividir el