Un array, en cualquier lenguaje de programación, es una variable que sirve para almacenar varios datos dentro. En muchos lenguajes estos arrays tienen un tamaño fijo e inamovible durante la ejecución del programa, pero en JavaScript no (de hecho, no son arrays propiamente dichos, sino vectores o listas).
Normalmente los datos que se almacenan en un array son del mismo tipo (por ejemplo, un conjunto de números enteros, o un conjunto de cadenas de texto), aunque en el caso de JavaScript y otros lenguajes (como PHP), cada elemento de la lista o conjunto puede ser de un tipo diferente al resto.
Para crear arrays en JavaScript, creamos la variable que va a almacenar el conjunto con dos corchetes o bien con new Array. En este último caso, podemos indicar el tamaño inicial del array también:
let conjunto = [];
let conjunto2 = new Array();
let conjunto3 = new Array(10);
También podemos definir a la vez el array y los elementos iniciales que va a tener en una misma línea (aunque luego podemos añadir más o cambiar los que hay).
let conjunto = [10, "Hola", 3.5];
let conjunto2 = new Array(10, "Hola", 3.5);
Después, podemos ir añadiendo elementos a esta colección usando los corchetes y poniendo dentro qué posición ocupa el elemento en la colección, empezando por la posición 0. Por ejemplo:
conjunto[0] = 10;
conjunto[1] = "Hola";
conjunto[2] = 3.5;
...
Alternativamente, también podemos emplear la instrucción push para añadir elementos al final de los existentes:
conjunto.push(3);
conjunto.push("Buenas");
Observemos cómo cada posición guarda un dato distinto (un entero, un texto, un número real…). Esto es posible, como decimos, en ciertos lenguajes de programación, especialmente los de tipado dinámico, es decir, aquellos donde no hay que indicar de qué tipo es una variable, sino que toma el tipo del valor que se le asigna. Si volvemos a utilizar una misma posición, borraremos el elemento previo y asignaremos el nuevo, pudiendo también cambiar el tipo de dato de esa posición:
conjunto[1] = "Adiós"; // Ahora este elemento ya no vale "Hola"
Si utilizamos una posición no correlativa con las anteriores, se añadirá un elemento en esa posición, y quedarán huecos vacíos enmedio, a los que se les asigna el valor undefined.
Si asignamos a una variable simple el valor de otra, estamos creando una copia de la variable original, con lo que si modificamos la segunda variable, la primera no ve su valor alterado:
let a = 3;
let b = a;
b = 4;
alert(a); // 3
Esto no es así con los arrays, ya que almacenan un conjunto mayor de datos. Cuando asignamos una variable array a otra, estamos asignando una referencia a la posición de memoria del array original, con lo que cualquier cambio en esa segunda variable va a afectar al array original:
let datos = [1, 2, 3, 4];
let datos2 = datos;
datos2[0] = 10;
console.log(datos); // [10, 2, 3, 4]
En ocasiones es posible que nos toque recorrer una lista o array de elementos de una web, buscando uno en concreto. Para ello, disponemos de las estructuras repetitivas o bucles vistos en documentos anteriores (while, do..while o for). Por ejemplo, supongamos que tenemos una variable lista con un array de elementos (el que sea). Si queremos recorrerlopodemos utilizar una variable que vaya desde el principio del array (posición 0) hasta el final (indicado por la propiedad length del array):
for (let i = 0; i < lista.length; i++)
{
alert (lista[i]); // Muestra el valor de cada elemento
}
Otra alternativa es utilizar una variable que sirva de índice en la lista, tomando el valor de cada posición de la misma, y accediendo con dicho valor a la posición concreta del array:
for (let indice in lista)
{
alert (lista[indice]); // Muestra el valor de cada elemento
}
Una tercera alternativa que podemos emplear desde ES2015 es el bucle for..of, que permite iterar por todos los valores del array (y también por todas las letras de un texto):
for (let valor of lista)
{
alert(valor);
}
Sobre la propiedad length, se cuentan las posiciones hasta la última ocupada, aunque en medio haya posiciones no definidas (undefined). Por ejemplo, este array tiene tamaño 5:
let a = [];
a[4] = 3;
Pasamos a detallar ahora algunas de las operaciones más útiles que podemos realizar con arrays:
push nos sirve para añadir elementos al final de los disponibles en un array. Podemos pasarle tantos como queramos, separados por comas. La instrucción unshift añade elementos al principio del array. También podemos pasarle los que queramos, separados por comas.pop devuelve y elimina el último elemento del array. La función shift devuelve y elimina la primera posición.join se aplica sobre un array. Puede recibir como parámetro un delimitador (texto) y obtiene un texto separando todos los elementos del array con el delimitador.concat enlaza dos arrays, obteniendo otro con la unión de todos los elementos de ambosslice obtiene un subarray desde una posición inicial (incluida) hasta una final (no incluida)splice quita elementos de un array, indicando desde qué posición eliminar y cuántos elementos quitar desde ahí. Adicionalmente, admite más parámetros, que serían los datos a añadir en la posición donde nos hemos quedado.reverse invierte el orden de los elementos de un arrayindexOf recibe como parámetro un dato, y nos devuelve en qué posición del array se encuentra por primera vez, o -1 si no se encuentra.includes recibe como parámetro un dato y devuelve si dicho dato está en el array o no.Veamos aquí un ejemplo de uso de cada una de estas funciones:
let datos = [1, 2, 3, 4];
datos.unshift(5, 6); // [5, 6, 1, 2, 3, 4]
let variable = datos.pop(); // variable = 4, datos = [5, 6, 1, 2, 3]
let texto = datos.join(":"); // "5:6:1:2:3"
let datos2 = datos.concat([10, 9]); // [5, 6, 1, 2, 3, 10, 9]
let datos3 = datos.slice(1, 3); // [6, 1]
datos2.splice(1, 3, 20, 30); // [5, 20, 30, 3, 10, 9]
datos2.reverse(); // [9, 10, 3, 30, 20, 5]
let posicion = datos2.indexOf(3); // 2
let existe = datos2.includes(10); // true
Ejercicio 1:
Realiza los siguientes pasos en un fichero llamado ejercicio1.html. Muestra por consola el resultado después de aplicar cada uno, pero con los elementos separados por “=>” usando join:
- Crea un array con 4 elementos numéricos
- Concatena 2 elementos más al final y 2 al principio (unshift y push)
- Elimina las posiciones de la 3 a la 5 (incluida) (splice)
- Inserta 2 elementos más entre el penúltimo y el último (splice)
- Invierte el array (reverse)
La función sort permite ordenar el array sobre el que se aplica. Es importante destacar que no crea un nuevo array sino que ordena el existente.
let nombres = ["Juan", "Ana", "Laura", "Blas"];
nombres.sort(); // ["Ana", "Blas", "Juan", "Laura"]
La ordenación que se realiza con sort por defecto es alfabética. Por ejemplo, el número 40 se considera menor que 5, ya que se comparan como textos, no como números. Esto quiere decir que JavaScript convierte los elementos del array a cadenas de texto (string) y los compara como texto, lo que puede provocar resultados inesperados cuando queremos ordenar números.
let numeros = [1, 10, 2, 21];
numeros.sort();
console.log(numeros); // [1, 10, 2, 21] => Esto ocurre porque "10" va antes que "2" en una comparación alfabética.
Para realizar una ordenación numérica correcta, es necesario pasar a sort una función de comparación que indique a JavaScript cómo debe ordenar los elementos. Dicha función recibe dos parámetros que actúan como dos datos cualesquiera del array, y devuelve un número que será:
El siguiente ejemplo ordena ascendentemente (en orden numérico) un array de enteros:
let datos = [20, 4, 6, 2, 10];
datos.sort(function(n1, n2) {
if (n1 < n2)
return -1;
else if (n1 > n2)
return 1;
else
return 0;
});
console.log(datos); // [2, 4, 6, 10, 20]
Alternativamente, podemos expresarla de esta otra forma más resumida, con el mismo resultado:
let datos = [20, 4, 6, 2, 10];
datos.sort(function(n1, n2) {
return n1 - n2;
});
Ejercicio 2:
Crea un fichero llamado ejercicio2.html. Crea dentro un array de números y ordénalo de mayor a menor utilizando sort. Muestra el array antes y después de ordenarlo.
Existen otras operaciones que podemos aplicar sobre arrays que tienen un uso un poco más avanzado. Muchas de ellas reciben una función como parámetro, que se aplica a cada elemento del array.
La función every devuelve un valor booleano indicando si la función que recibe como parámetro es cierta para todos los elementos del array. El siguiente ejemplo comprueba si todos los elementos del array son pares:
let resultado = datos.every(function(n) {
return n % 2 == 0;
});
La función some es similar a la anterior, pero devuelve un valor booleano indicando si alguno de los elementos del array cumple la función. Este ejemplo comprueba si alguno de los números del array es mayor que 10:
let resultado = datos.some(function(n) {
return n > 10;
});
La función forEach recorre todos los elementos del array, y aplica la función que recibe como parámetro a cada uno de ellos. A diferencia de otras funciones, forEach no devuelve ningún valor, y se utiliza principalmente para realizar acciones como mostrar datos o modificarlos.
Este ejemplo muestra por consola cada elemento del array:
datos.forEach(function(n) {
console.log(n);
});
La función filter devuelve un nuevo array con los elementos que cumplen la condición indicada por la función que se pasa como parámetro. El siguiente ejemplo obtiene un subconjunto del array inicial con los valores mayores que 10:
let datosMayores10 = datos.filter(function(n){
return n > 10;
});
La función map permite obtener un nuevo array aplicando una transformación a todos los elementos del array original. El siguiente ejemplo multiplica por 2 cada elemento del array:
let dobles = datos.map(function(n) {
return n * 2;
});
En todas estas funciones podemos emplear arrow functions o funciones lambda como parámetro, obteniendo un código más compacto:
let resultado = datos.every(n => n % 2 == 0);
let datosMayores10 = datos.filter(n => n > 10);
let dobles = datos.map(n => n * 2);
RECUERDA:
maptransforma,filterselecciona,forEachejecuta
Ejercicio 3:
Crea un fichero llamado ejercicio3.html. Define una función que reciba un array y un número como parámetros y devuelva si todos los números del array son múltiplos del número recibido como parámetro. Haz que el número tome por defecto el valor de 2, y prueba la función con distintas llamadas.
Ejercicio 4:
Crea un fichero llamado ejercicio4.html. Define un array de datos numéricos, quédate sólo con los números que sean positivos y transforma el array para que almacene los cuadrados de esos números. Usa funciones lambda para resolver este ejercicio.
JavaScript es un lenguaje que permite trabajar con objetos. Aunque su modelo de orientación a objetos es diferente al de otros lenguajes como Java o C++, sí que permite definir clases (veremos algún ejemplo de ello más adelante) y trabajar con objetos que almacenan información heterogénea.
Un objeto en JavaScript es una colección de pares clave–valor, donde cada clave identifica una propiedad y cada valor puede ser de cualquier tipo (números, cadenas, arrays, otros objetos, etc.).
Para definir un objeto JavaScript, encerramos sus datos entre llaves. Cada propiedad se define mediante un nombre y, tras los dos puntos, su valor inicial. Así podríamos definir los datos de una persona:
let persona = {
nombre: "Mario",
edad: 23,
telefono: "611223344"
};
console.log(persona.nombre);
Una vez definido el objeto, podemos acceder a sus propiedades de dos formas distintas:
Por ejemplo, las siguientes expresiones son equivalentes:
console.log(persona.nombre);
console.log(persona["nombre"]);
También es posible añadir nuevas propiedades a un objeto después de haber sido creado, simplemente asignándoles un valor:
let persona = {
nombre: "Mario",
edad: 23,
telefono: "611223344"
};
persona.direccion = "C/Mayor 13";
persona["email"] = "mario@email.com";
Una vez definidos los objetos, en muchas ocasiones necesitamos recorrer sus propiedades para acceder a sus valores o mostrarlos. Para ello, podemos utilizar la estructura for...in, que recorre todas las propiedades de un objeto.
let persona = {
nombre: "Mario",
edad: 23,
telefono: "611223344"
};
for (let propiedad in persona) {
console.log(propiedad + ": " + persona[propiedad]);
}
En cada iteración del bucle, la variable propiedad contiene el nombre de una propiedad del objeto. Para acceder a su valor, utilizamos la notación con corchetes [ ].
Este tipo de recorrido es útil cuando no conocemos de antemano todas las propiedades del objeto o cuando queremos procesarlas de forma genérica.
En aplicaciones reales es muy habitual trabajar no con un único objeto, sino con colecciones de objetos, que suelen almacenarse en arrays. Cada elemento del array es un objeto con la misma estructura.
Por ejemplo, un array de personas podría definirse así:
let personas = [
{ nombre: "Ana", edad: 25 },
{ nombre: "Juan", edad: 32 },
{ nombre: "Laura", edad: 28 }
];
Podemos recorrer este array utilizando forEach para acceder a cada objeto:
personas.forEach(function(p) {
console.log(p.nombre + " tiene " + p.edad + " años");
});
En este caso, en cada iteración p representa un objeto del array, y podemos acceder a sus propiedades mediante el operador punto.
Una vez que trabajamos con arrays de objetos, las funciones vistas en el apartado anterior (map, filter y sort) resultan especialmente útiles.
La función map permite obtener un nuevo array transformando cada objeto del array original. El siguiente ejemplo obtiene un array con los nombres de las personas:
let nombres = personas.map(function(p) {
return p.nombre;
});
También podemos transformar los valores. Por ejemplo, aumentar la edad de todas las personas en un año:
let personasActualizadas = personas.map(function(p) {
return {
nombre: p.nombre,
edad: p.edad + 1
};
});
La función filter permite obtener un subconjunto del array, seleccionando únicamente los objetos que cumplen una condición. El siguiente ejemplo obtiene las personas mayores de 30 años:
let mayores30 = personas.filter(function(p) {
return p.edad > 30;
});
El array original no se modifica, y el resultado es un nuevo array con los objetos que cumplen la condición.
La función sort también puede utilizarse con arrays de objetos, indicando el criterio de ordenación mediante una función de comparación. Por ejemplo, para ordenar el array de personas por edad de menor a mayor:
personas.sort(function(p1, p2) {
return p1.edad - p2.edad;
});
Ejercicio 5:
Crea una página llamada ejercicio5.html. Define un array con datos de personas como los del ejemplo anterior. Ordena después el array ascendentemente por el nombre de las personas (alfabético), recórrelo y muéstralo por pantalla. Puede serte de utilidad la función localeCompare que permite comparar alfabéticamente dos textos y obtener un entero indicando cuál es mayor o menor.
Ejercicio 6:
Crea una página llamada ejercicio6.html. Define el siguiente array: let numeros = [3, -1, 4, 0, -5, 8]; a) Obtén un array con los números positivos b) Obtén otro array con esos números multiplicados por 10 c) Indica qué funciones de arrays has utilizado en cada caso y por qué
Ejercicio 7:
Crea una página llamada ejercicio7.html. Define el siguiente array de personas: let personas = [ { nombre: “Ana”, edad: 17 }, { nombre: “Luis”, edad: 22 }, { nombre: “Marta”, edad: 19 } ]; a) Obtén un array con las personas mayores de edad b) Obtén un array con solo los nombres de esas personas
Ejercicio 8:
Crea una página llamada ejercicio8.html. Crea un array de objetos con productos (nombre y precio): a) Filtra los productos con precio mayor que 20 b) Ordénalos de menor a mayor precio c) Obtén un array con solo los nombres de los productos resultantes