Manipulación de matrices en JavaScript

Las matrices pueden manipularse gracias a distintos métodos que el día de hoy voy a explicarte algunos de ellos, ya que este tema es muy fácil. ¡Vamos a comenzar!

Añadir / eliminar elementos

Ya conocemos métodos que agregan y eliminan elementos desde el principio o el final:

  • arr.push(…items) – agrega elementos al final,
  • arr.pop() – Extrae un artículo del final,
  • arr.shift() – Extrae un artículo desde el principio,
  • arr.unshift(…items) – Agrega elementos al principio.

Sin embargo, aquí hay algunos otros.

Splice

¿Cómo eliminar un elemento de la matriz?

Las matrices son objetos, por lo que podemos tratar de usar delete:

let arr = ["Quiero", "comer", "ahora"];
delete arr[2]; // remove "ahora"
alert( arr[2] ); // indefinido
// ahora arr = ["Quiero", "comer", ];
alert( arr.length ); // 3

Se eliminó el elemento, pero la matriz todavía tiene 3 elementos, podemos ver eso arr.length == 3.

Eso es natural, porque delete obj.key elimina un valor por el key. Es todo lo que hace. Bien para objetos. Pero para los arreglos generalmente queremos que el resto de elementos se desplacen y ocupen el lugar liberado. Esperamos tener una matriz más corta ahora.

Por lo tanto, se deben utilizar métodos especiales.

El método arr.splice (str) es como una navaja suiza para arreglos. Puede hacer de todo: añadir, eliminar e insertar elementos.

La sintaxis es:

arr.splice(index[, deleteCount, elem1, ..., elemN])

Comienza desde la posición index: deleteCount elementos y luego los inserta elem1, …, elemN en su lugar. Devuelve la matriz de elementos eliminados.

Este método es fácil de comprender mediante ejemplos.

Vamos a empezar con la eliminación:

let arr = ["Yo", "estudio", "JavaScript"];
arr.splice(1, 1); // del índice 1 eliminar 1 elemento
alert( arr ); // ["Yo", "JavaScript"]

Fácil, ¿verdad? A partir del índice 1 se eliminó el elemento 1.

En el siguiente ejemplo, eliminamos 3 elementos y los reemplazamos con los otros dos:

let arr = ["Yo", "estudio", "JavaScript", "ahora", "mismo"];
// quitar 3 primeros elementos y sustituirlos por otro
arr.splice(0, 3, "Nosotros", "bailamos");
alert( arr ) // ahora["Nosotros", "bailamos", "ahora", "mismo"]

Aquí podemos ver que splice devuelve la matriz de elementos eliminados:

let arr = ["Yo", "estudio", "JavaScript", "ahora", "mismo"];
//elimina los dos primeros elementos
let removed = arr.splice(0, 2);
alert( removed ); // "YoI", "estudio" <-- conjunto de elementos eliminados

El método splice también es capaz de insertar los elementos sin ningún tipo de eliminación. Para eso tenemos que configurar deleteCount a 0:

let arr = ["Yo", "estudio", "JavaScript"];
// del índice 2
// suprimir 0
//a continuación, insértese "complejo" y " lenguaje".
//arr.splice(2, 0, "complejo", "lenguaje");
alert( arr ); // "Yo", "estudio", "lenguaje", "complejo", "JavaScript"

Se permiten índices negativos

Aquí y en otros métodos de matriz, se permiten índices negativos. Especifican la posición desde el final de la matriz, como aquí:

let arr = [1, 2, 5];
//  del índice -1 (un paso desde el final)
// borra 0 elementos,
// a continuación, añádanse los puntos 3 y 4
splice.array(-1, 0, 3, 4);
alert( arr ); // 1,2,3,4,5

Slice

El método arr.slice es mucho más simple que el similar arr.splice.

La sintaxis es:

arr.slice(principio, final);

Devuelve una nueva matriz donde copia todos los elementos comienzan índice «principio»a «final»(no incluida «final»). Ambos principio y final pueden ser negativos, en ese caso se asume la posición desde el final de la matriz.

Por ejemplo:

let str = "test";
let arr = ["t", "e", "s", "t"];
alert( str.slice(1, 3) ); // es
alert( arr.slice(1, 3) ); // e,s
alert( str.slice(-2) ); // st
alert( arr.slice(-2) ); // s,t
concat

El método arr.concat une la matriz con otras matrices y / o elementos.

La sintaxis es:

arr.concat(arg1, arg2...)

Acepta cualquier número de argumentos, ya sea matrices o valores.

El resultado es una nueva matriz que contiene elementos de arr, entonces arg1, arg2etc.

Si un argumento es una matriz o tiene una propiedad Symbol.isConcatSpreadable, entonces todos sus elementos se copian. De lo contrario, el argumento en sí se copia.

Por ejemplo:

let arr = [1, 2];
// fusionar arr con[3,4]
alert( arr.concat([3, 4])); // 1,2,3,4
// fusionar arr con [3,4] y [5,6]
alert( arr.concat([3, 4], [5, 6])); // 1,2,3,4,5,6
// fusionar arr con [3,4], luego sumar los valores 5 y 6
alert( arr.concat([3, 4], 5, 6)); // 1,2,3,4,5,6

Normalmente, solo copia los elementos de los arreglos (los «extiende»). Otros objetos, incluso si parecen matrices, agregados como un todo:

let arr = [1, 2];
let arrayHola = {
0: "algunas",
length: 1
};
alert( arr.concat(arrayHola) ); // 1,2,[object Object]
//[1, 2, arrayLike]

Pero si un objeto similar a una matriz tiene propiedades Symbol.is, Concat ,Spreadable, entonces sus elementos se agregan en su lugar:

let arr = [1, 2];
let arrayHola = {
0: "algunas",
1: "flaso",
[Symbol.isConcatSpreadable]: true,
length: 2
};
alert( arr.concat(arrayHola) ); // 1,2,algunas, falso

Buscando en la matriz

Estos son métodos para buscar algo en una matriz.

indexOf / lastIndexOf e Includes

Los métodos arr.indexOf , arr.lastIndexOf y arr.includes tienen la misma sintaxis y hacen esencialmente lo mismo que sus homólogos de cadena, pero operan en elementos en lugar de caracteres:

  • arr.indexOf(item, desde) busca un item a partir del índice desde, y devuelve el índice donde se encontró, de lo contrario -1.
  • arr.lastIndexOf(item, desde) – Igual, pero mira de derecha a izquierda.
  • arr.includes(item, desde)– Busca a item a partir del índice from, y devuelve true si se encuentra.
    Por ejemplo:

let arr = [1, 0, false];
alert( arr.indexOf(0) ); // 1
alert( arr.indexOf(false) ); // 2
alert( arr.indexOf(null) ); // -1
alert( arr.includes(1) ); // true

Ten en cuenta que los métodos utilizan la comparación ===. Entonces, si buscamos false, encuentra exactamente false y no el cero.

Si queremos verificar la inclusión y no queremos saber el índice exacto, entonces arr.includes es preferible.

Además, una diferencia muy pequeña de includes es que maneja correctamente NaN, a diferencia de indexOf/lastIndexOf:

const arr = [NaN];
alert( arr.indexOf(NaN) ); // -1 (debería ser 0, pero ==== la igualdad no funciona para NaN)
alert( arr.includes(NaN) );// true (correcto)

find y findIndex

Imagina que tenemos una variedad de objetos. ¿Cómo encontramos un objeto con la condición específica?

Aquí el método arr.find es útil.

La sintaxis es:

let resultado = arr.find(function(item, index, array) {
// debería devolver true si el ítem es lo que estamos buscando});

La función se llama repetitivamente para cada elemento de la matriz:

  • item es el elemento
  • index es su índice.
  • array es la propia matriz.

Si vuelve true, la búsqueda se detiene, item se devuelve. Si no se encuentra nada, undefined se devuelve.

Por ejemplo, tenemos una matriz de usuarios, cada uno con los campos id y name. Encontremos el que tiene id == 1:

let usuarios = [
{id: 1, nombre: "Juan"},
{id: 2, nombre: "Pedro"},
{id: 3, nombre: "María"}
];
let usuarios = usuarios.find(item => item.id == 1);
alert(usuarios.nombre); // John

En la vida real, los arreglos de objetos son una cosa común, por lo que el método find es muy útil.

Ten en cuenta que en el ejemplo que proporcionamos  de una función find de argumento único item => item.id == 1. Otros parámetros de find raramente se utilizan.

El método arr.findIndex es esencialmente el mismo, pero devuelve el índice donde se encontró el elemento en lugar del elemento en sí.

Filter

El método find busca un único (primer) elemento que hace que la función regrese true.

Si puede haber muchos, podemos usar arr.filter (fn).

La sintaxis es aproximadamente la misma que find, pero devuelve una matriz de elementos coincidentes:

let resultado = arr.filter(function(item, index, array) {
//debería devolver true si el elemento pasa el filtro});

Por ejemplo:

let usuarios = [
{id: 1, nombre: "Juan"},
{id: 2, nombre: "Pedro"},
{id: 3, nombre: "Maria"}
];

// regresa el array de los primeros usuarios
let algunosUsuarios = users.filter(item => item.id < 3);

alert(algunosUsuarios.length); // 2