Skip to content

Latest commit

 

History

History
532 lines (377 loc) · 16.1 KB

File metadata and controls

532 lines (377 loc) · 16.1 KB

ARRAYS


1. Introducción

// Declaración de array vacío
let numeros = [];          

 // Declaración de array con 4 elementos
let palabras = ['Esto', 'es', 'una', 'prueba'];

1.1. Propiedades y métodos básicos

// Propiedades
numeros.length;             //  0 
palabras.length;            //  4 

// Métodos
palabras.toString();        // "Esto,es,una,prueba"
palabras;                   // ['Esto', 'es', 'una', 'prueba']

palabras.concat([1,2,3]);   // ["Esto", "es", "una", "prueba", 1, 2, 3]
palabras;                   // ['Esto', 'es', 'una', 'prueba']

palabras.forEach ( function (elemento)  {
  console.log (elemento); 
});

NOTA: Los métodos toString y concat no modifican el array original.

1.2. Desestructuración

Se representa con [ ], permite desempacar valores de arrays en distintas variables.

Se utiliza en numerosos ámbitos, para mayor información consultar el siguiente enlace:

https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

Ejemplo 1: Asignación de valores a variables desde un array origen

let a, b;
[a, b] = [10, 20];

console.log(a); // 10
console.log(b); // 20


const x = [1, 2, 3, 4, 5];
const [y, z] = x;

console.log(y); // 1
console.log(z); // 2

Ejemplo 2: Intercambio de variables

let a = 1;
let b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

Ejemplo 3: Devolución de varios valores por una función

function f() {
  return [1, 2];
}

let a, b;
[a, b] = f();
console.log(a); // 1
console.log(b); // 2

1.3. Operador de expansión ...

También llamado spread operator y representado por 3 puntos ..., permite expandir (sacar del array) los elementos.

Se utiliza en numerosos ámbitos, para mayor información consultar el siguiente enlace:

https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Spread_syntax

Ejemplo 1: Paso de parámetros a una función

function suma(x, y, z) { return x+y+z; }

let args = [0, 1, 2];

suma(...args);  // equivale a suma( args[0], args[1], args[2] )

Ejemplo 2: Copia superficial de un array

let numeros  = [1, 2, 3];

let nums = [...numeros]; 

Ejemplo 3: Concatenación de arrays

let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2];

// arr1 = arr1.concat(arr2);

1.4. Añadir elementos

  • Al final del array: push
  • Al principio del array: unshift
  • En cualquier posición: splice

Al final del array

numeros.push (100, 20, 10);           // [ 100, 20, 10 ]

let n = numeros.push (1, 1, 2, 2, 3); // [ 100, 20, 10, 1, 1, 2, 2, 3 ],  n=8 ( es la longitud )

Al principio del array

let n = numeros.unshift (50, 40, 30); // [50, 40, 30, 100, 20, 10, 1, 1, 2, 2, 3] n=11 ( es la longitud)

En cualquier posición

// el método splice tiene la siguiente forma:
// array.splice (pos_inicio, cantidad_elementos, elemento1, elemento2, ...);

numeros.splice(3, 0, 400, 300, 200);   // [50, 40, 30, 400, 300, 200, 100, 20, 10, 1, 1, 2, 2, 3]

// el parámetro cantidad_elementos indica la cantidad de items a eliminar.
// en una insersión dicho parámetro debe ser 0. 

1.5. Eliminar elementos

  • Al final del array: pop
  • Al principio del array: shift
  • En cualquier posición: splice

Al final del array

let z = numeros.pop ();   // [ 50, 40, 30, 400, 300, 200, 100, 20, 10, 1, 1, 2, 2 ],  z=3 ( es el elemento extraido )

Al principio del array

let a = numeros.shift (); // [40, 30, 400, 300, 200, 100, 20, 10, 1, 1, 2, 2 ], a=50 ( es el elemento extraido)

En cualquier posición

let extraido = numeros.splice (2, 3);   // [40, 30, 100, 20, 10, 1, 1, 2, 2 ] , extraido = [ 400, 300, 200 ]

NOTA: los métodos pop y shift sólo pueden extraer un elemento cada vez.

1.6. Hacer copia completa o parcial de un array

// el método slice tiene la siguiente forma:
// array.slice (pos_inicio, pos_final);     

let nuevo = numeros.slice();              // todos los elementos
let trozo = numeros.slice(1, 3);          // desde elemento segundo hasta el cuarto, sin incluir este último

NOTA: el código let nuevo = numeros, no hace una copia.

Simplemente crea una referencia o "alias" llamado nuevo que apunta al mismo sitio que numeros. Cualquier cambio en el array se ve reflejado en ambas variables.

let numeros = [ 1, 2, 3 ];
let nuevo = numeros;

numeros.pop();      // nuevo = [ 1, 2 ] 

ACTIVIDAD PROPUESTA:

  • ¿Qué método se utiliza para convertir un array a texto? Pon un ejemplo.
  • ¿Qué método se utiliza para concatenar 2 arrays? Pon un ejemplo.

1.7. Invertir orden de los elementos

let numeros = [ 2, 20, 2, 1, 10, 1, 100 ];
numeros.reverse();       // [100, 1, 10, 1, 2, 20, 2]

NOTA: El método anterior modifica el array. Si deseamos que el array original no se modifique, usaremos la función toReversed.

let numReversed  = numeros.toReversed(); 

1.8. Ordenar elementos

let numeros = [ 2, 20, 2, 1, 10, 1, 100 ];
numeros.sort();                       // [1, 1, 10, 100, 2, 2, 20]
numeros.reverse();                    // [20, 2, 2, 100, 10, 1, 1]

NOTA: el método sort() realiza una ordenación alfábetica.

// para realizar una ordenación númerica pasamos una función de comparación

numeros.sort( function(a, b){return a-b} );     // [1, 1, 2, 2, 10, 20, 100]  
numeros.sort( function(a, b){return b-a} );     // [100, 20, 10, 2, 2, 2, 1, 1]

// Podemos simplicar haciendo uso de funciones flecha
numeros.sort( (a, b) => a-b );     // [1, 1, 2, 2, 10, 20, 100]  
numeros.sort( (a, b) => b-a );     // [100, 20, 10, 2, 2, 2, 1, 1]

NOTA: El método anterior modifica el array. Si deseamos que el array original no se modifique, usaremos la función toSorted.

let numsOrdenados   = numeros.toSorted( (a,b) => a-b ); // Orden ascendente
let numOrdenadosInv = numeros.toSorted( (a,b) => b-a ); // Orden descendente    

⚠️IMPORTANTE:

Para ordenar un array que contenga strings usa el método localeCompare.

let ciudades = [ "Ávila", "Almeria", "Albacete", "Álava" ]
ciudades.sort()                               // [ 'Albacete', 'Almeria', 'Álava', 'Ávila' ]
ciudades.sort( (a,b) => a.localeCompare(b) )  // [ 'Álava', 'Albacete', 'Almeria', 'Ávila' ]

También válido para array de objetos que contenga strings

ciudades = [
 { nombre: 'Ávila', region: 'Castilla-La Mancha' },
 { nombre: 'Almeria', region: 'Andalucía' },
 { nombre: 'Albacete', region: 'Castilla-La Mancha' },
 { nombre: 'Álava', region: 'Castilla-La Mancha' }
]

ciudades.sort ( (a,b) => a.nombre.localeCompare(b.nombre) )

1.9. Crear elementos

Javascript dispone del método Array.from que puede resultar muy útil en ciertos momentos, sobre todo si necesitamos crear arrays con un gran número de elementos.

A continuación se muestran algunos ejemplos de uso:

// Obtenemos array cuyos elementos son cada una de las letras del string
Array.from("foo");  // [ "f", "o", "o" ]

// Obtenemos array cuyos elementos son el doble del array original
Array.from([1, 2, 3], (x) => x + x); // [2, 4, 6]

// Obtenemos array con 50 números entre 0 y 49
Array.from({ length: 50 }, (value, index) => index);   

// Obtenemos array con 100 números aleatorios entre 0 y 1
Array.from({ length: 100 }, () => Math.random() )

// Obtenemos array con 100 puntos aleatorios con coordenadas {x, y} entre 0 y 1
Array.from({ length: 100 }, () => ({
                x: Math.random(),
                y: Math.random(),
}))

1.10. Encontrar un elemento

Si deseamos buscar un elemento en un array, el siguiente método resulta de gran utilidad:

  • find : Busca el primer elemento que cumple una condición.
let desarrolladores = [
 { id: 1, nombre: 'Juan', tipo: 'móvil', edad: 24 },
 { id: 2, nombre: 'Inma', tipo: 'móvil', edad: 31 },
 { id: 3, nombre: 'Ana',  tipo: 'web',   edad: 25 },
 { id: 4, nombre: 'Eva',  tipo: 'web',   edad: 30 },
 { id: 5, nombre: 'José', tipo: 'móvil', edad: 33 }
];

desarrolladores.find( desarrollador => desarrollador.id == 3 );
// Devuelve { id: 3, nombre: 'Ana',  tipo: 'web',   edad: 25 }
desarrolladores.find( desarrollador => desarrollador.id == 7 );
// Devuelve undefined

NOTA:

También existen los métodos findLast, así como findIndex y findLastIndex. Para mayor información, consultar la documentación oficial.

PROGRAMACIÓN FUNCIONAL:

En el paradigma de programación funcional es posible pasar una función como argumento de otra función. Javascript soporta este paradigma, y un ejemplo de ello es el método anterior, así como los métodos que veremos en el apartado siguiente. El formato seguido es el siguiente:

valorResultado  = array.find   ( /* función que comprueba condición sobre cada elemento hasta encontrarlo */) 
arrayResultado  = array.map    ( /* función que ejecuta operación sobre cada elemento */)
arrayResultado  = array.filter ( /* función que comprueba condición sobre cada elemento */) 
valorResultado  = array.reduce ( /* función que ejecuta operación sobre cada elemento */) 

1.11. Tratar los elementos

Tres métodos muy interesantes para trabajar con arrays, son:

  • map : Realiza una operación para cada uno de los elementos
  • filter : Filtra los elementos deseados
  • reduce : Reduce los elementos a un valor

NOTA: Ninguno de estos métodos modifica el array.

// Ejemplos

let numeros = [ 1, 4, 2, 3, 5, 2, 1 ];
let cuadrados = [];
let filtrados = [];
let suma = [];

// Utilizando map para calcular el cuadrado de cada elemento
cuadrados = numeros.map( item => item * item );        // cuadrados = [ 1, 16, 4, 9, 25, 4, 1 ]  

// Utilizando filter para filtrar los elementos mayores que 2
filtrados = numeros.filter ( item => item > 2 );     // filtrados = [ 4, 3, 5 ]

// Utilizando reduce para sumar los elementos
suma = numeros.reduce ( (acumulador, item) => acumulador + item,  0); 
// suma = 18  (0 + 1 + 4 + 2 + 3 + 5 + 2 + 1 ) 

NOTA:

  • Los métodos map, filter y reduce reciben como primer parámetro una función callback. En este caso la hemos expresado como arrow function para simplificar el código.
  • El método reduce recibe un segundo parámetro que será el primer valor a utilizar.

ACTIVIDAD PROPUESTA:

  • ¿Qué resultado obtenemos si ejecutamos las siguientes sentencias?
   let resultado;
   
   resultado = filtrados.reduce ( (acumulador, item) => acumulador + item,  10);
   resultado = filtrados.reduce ( (acumulador, item) => acumulador * item,  1);

2. Encadenamiento de métodos

El encadenamiento de métodos es una técnica donde aplicamos a un objeto un método. A su vez al objeto resultante se le aplica otro método. Y así sucesivamente. Nos ahorramos así la declaración de objetos intermedios y el código se simplifica.

Como requisito debemos asegurarmos de que el método que aplicamos es adecuado al objeto de trabajo.

// Ejemplo: Calculamos el doble de cada número, luego filtramos los menores de 5 y después los sumamos

resultado = numeros.map ( item => 2 * item ).filter ( item => item < 5 ).reduce ( (acumulador, item) => acumulador + item, 0);

// El resultado es 12
//
// - Doble de cada número: [2, 8, 4, 6, 10, 4, 2]
// - Filtro de menores de 5: [2, 4, 4, 2]
// - Suma de ellos: 12
// Mismo ejemplo anterior. Para mayor legibilidad suele indicarse cada método en una línea separada
// y normalmente el punto (.) suele iniciar la línea.

resultado = numeros.map    ( item => 2 * item )
                   .filter ( item => item < 5 )
                   .reduce ( (acumulador, item) => acumulador + item, 0);

Explicación:

  • La operación numeros.map ( item => 2 * item ) nos devuelve el objeto literal [2, 8, 4, 6, 10, 4, 2].
  • Aplicamos entonces la operación [2, 8, 4, 6, 10, 4, 2].filter ( item => item < 5 ) y obtenemos el objeto literal [2, 4, 4, 2].
  • Aplicamos después la operación [2, 4, 4, 2].reduce ( (acumulador, item) => acumulador + item, 0) y obtenemos 12.
  • Por último el resultado 12 se guarda en la variable resultado.

Si no hubieses empleado encadenamiento de métodos, el código sería el siguiente:

let resultado1 = numeros.map ( item => 2 * item );
let resultado2 = resultado1.filter ( item => item < 5 );
let resultado3 = resultado2.reduce ( (acumulador, item) => acumulador + item, 0);

// resultado final en resultado3

El encadenamiento de métodos es una técnica que podemos utilizar siempre que sea posible y lo deseemos. Suele utilizarse frecuentemente con jQuery.

ACTIVIDAD PROPUESTA:

  • ¿Qué resultado obtenemos si ejecutamos el siguiente código?
let desarrolladores = [
 { nombre: 'Juan', tipo: 'móvil', edad: 24 },
 { nombre: 'Inma', tipo: 'móvil', edad: 31 },
 { nombre: 'Ana',  tipo: 'web',   edad: 25 },
 { nombre: 'Eva',  tipo: 'web',   edad: 30 },
 { nombre: 'José', tipo: 'móvil', edad: 33 }
];


let sumaEdadWeb = desarrolladores
                .filter ( x => x.tipo === 'web')
                .map    ( x => x.edad)
                .reduce ((acumulador, item) => acumulador + item, 0);

ACTIVIDAD PROPUESTA:

  • En lugar de calcular la suma de edades de los desarrolladores web, ¿cómo calcularíamos la media de edad de los desarrolladores web?

2.1. Uso correcto

Tanto el método map como el método filter, éste último en menor medida, se usan de forma bastante frecuente en Javascript. A la hora de usarlos debemos hacerlo de forma correcta. Debemos tener en cuenta que:

  • Se aplican únicamente sobre un array original, que no es modificado
  • Devuelven un nuevo array con los valores resultantes de la operación
  • Para devolver cada valor debemos hacerlo como se muestra a continuación

BIEN

desarrolladores.map( x => x.nombre )            // [ 'Juan', 'Inma', 'Ana', 'Eva', 'José' ]
desarrolladores.map( x => (x.nombre) )          // [ 'Juan', 'Inma', 'Ana', 'Eva', 'José' ] 
desarrolladores.map( x => { return x.nombre } ) // [ 'Juan', 'Inma', 'Ana', 'Eva', 'José' ]

MAL

desarrolladores.map( x => { x.nombre} )        // [ undefined, undefined, undefined, undefined, undefined ]
desarrolladores.map( x => (return x.nombre) )  // Uncaught SyntaxError: Unexpected token 'return'
desarrolladores.map( x => return x.nombre )    // Uncaught SyntaxError: Unexpected token 'return'

Si en lugar de devolver valores simples, devolvemos objetos

BIEN

desarrolladores.map( x => { return { nombre: x.nombre, edad: x.edad } } )
desarrolladores.map( x => ({ nombre: x.nombre, edad: x.edad }))

MAL

desarrolladores.map( x => { nombre: x.nombre, edad: x.edad }) // Uncaught SyntaxError: Unexpected token ':'

3. Referencias