El objeto Array existe desde la primer versión de JavaScript, pero a lo largo del tiempo ha ido incorporando nuevas funcionalidades.

Veremos los métodos que ha incorporado el objeto Array con la versión de ES6, recordando que todos los navegadores actuales los implementan en su totalidad.

Método estático 'from'.

El método estático 'from' retorna la referencia de un objeto de tipo Array que se crea a partir del dato que le pasamos:

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    const arreglo1 = [10, 20, 30];
    const arreglo2 = Array.from(arreglo1);
    arreglo1.fill(5);
    console.log(arreglo1); // [5,5,5]
    console.log(arreglo2); // [10,20,30]
  </script>
</body>

</html>

Creamos un arreglo con 3 elementos:

    const arreglo1 = [10, 20, 30];

Luego llamamos al método 'from' del objeto 'Array', el cual nos retorna un nuevo arreglo con el mismo contenido de 'arreglo1'.

Es importante recordar que los objetos en JavaScript (y los arreglos son objetos) almacenan la referencia del objeto y no los datos propiamente dichos como los hacen las variables de tipo primitiva. No es lo mismo hacer la asignación:

  const arreglo2=arreglo1;

Con la asignación previa sigue existiendo un solo objeto y luego dos referencias (arreglo1 y arreglo2) a dicho objeto.

Si utilizamos la asignación tenemos como resultado:

  <script>
    const arreglo1 = [10, 20, 30];
    const arreglo2 = arreglo1;
    arreglo1.fill(5);
    console.log(arreglo1); // [5,5,5]
    console.log(arreglo2); // [5,5,5]
  </script>

Como podemos comprobar si imprimimos el único arreglo ya sea con la referencia arreglo1 o arreglo2 luego se acceden al mismo contenido.

Luego veremos que el método 'fill' cambia el contenido de un arreglo con el dato que le pasamos como parámetro.

Al método 'from' podemos pasar cualquier objeto que tenga la capacidad de iterar (más adelande veremos como crear objetos iterables). Por ejemplo un string es iterable:

  <script>
    const titulo = "administración";
    const arreglo1 = Array.from(titulo);
    console.log(arreglo1);        // ["a", "d", "m", "i", "n", "i", "s", "t", "r", "a", "c", "i", "ó", "n"]
    console.log(arreglo1.length); // 14
  </script>

Un objeto de tipo Map es iterable:

  <script>
    const mapa1 = new Map();
    mapa1.set("casa", "house");
    mapa1.set("rojo", "red");
    mapa1.set("auto", "car");
    const arreglo1 = Array.from(mapa1);
    console.log(arreglo1);        // [["casa", "house"], ["rojo", "red"], ["auto", "car"]]
    console.log(arreglo1.length); // 3
  </script>

Un objeto de tipo Set es iterable:

  <script>
    const conjunto1 = new Set();
    conjunto1.add("C");
    conjunto1.add("Pascal");
    conjunto1.add("PHP");
    conjunto1.add("Python");
    const arreglo1 = Array.from(conjunto1);
    console.log(arreglo1);        // ["C", "Pascal", "PHP", "Python"]
    console.log(arreglo1.length); // 4
  </script>

Por ejemplo no son iterables los objetos WeakMap, WeapSet, Object etc.

El método 'from' tiene opcionalmente un segundo parámetro al cual podemos pasar una función que reciba cada elemento del arreglo y retorne el dato a almacenar:

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    const arreglo1 = [10, 20, 30];
    const arreglo2 = Array.from(arreglo1, (elemento) => elemento * 2);
    console.log(arreglo2); // [20, 40, 60]
  </script>
</body>

</html>

La función anonima retorna que valor debe almacenar en el arreglo que se crea, en éste caso almacenamos los valores originarios del arreglo1 pero multiplicados por 2.

Recordemos que las funciones flecha son ámpliamente utilizadas a partir de ES6 ya que nos permiten generar un código muy conciso, utilizando la sintaxis anterior tenemos:

  <script>
    const arreglo1 = [10, 20, 30];
    const arreglo2 = Array.from(arreglo1, function (elemento) { return elemento * 2 });
    console.log(arreglo2); // [20, 40, 60]
  </script>

Método estático 'of'.

El método estático 'of' retorna la referencia de un objeto de tipo Array a partir de una lista de valores que le pasamos a dicho método:

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    const arreglo1 = Array.of(10, 20, 30, 40);
    console.log(arreglo1); // [10, 20, 30, 40]
  </script>
</body>

</html>

Métodos 'keys', 'values' y 'entries'.

El objeto Array implementan los métodos que permiten iterar sobre sus claves y valores:

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    const lenguajes = ["domingo", "lunes", "martes", "miércoles",
                       "jueves", "viernes", "sábado"];
    for (let indice of lenguajes.keys())
      console.log(indice); // 0 1 2 3 4 5 6
    for (let valor of lenguajes.values())
      console.log(valor); // "domingo" "lunes" "martes" "miércoles" 
                          // "jueves" "viernes" "sábado"
    for (let componente of lenguajes.entries())
      console.log(componente);  // [0, "domingo"] [1, "lunes"] [2, "martes"] 
                                // [3, "miércoles"] [4, "jueves"] 
                                // [5, "viernes"] [6, "sábado"] [7, "domingo"]

  </script>
</body>

</html>

Los datos que se recuperan en cada ciclo son:

Array keys values entries javascript

En un solo 'for of' podemos recuperar cada componente y guardarlo en un Array el índice por un lado y el valor por otro:

    for (let [indice,valor] of lenguajes.entries())
      console.log(indice,valor);

Método 'fill'.

El método 'fill' permite cambiar el contenido de todas o algunas componentes de un arreglo existente. En ningún caso permite redimensionarlo.

Veamos un ejemplo y los efectos del método 'fill':

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    const arreglo1 = [9, 9, 9, 9, 9, 9, 9];
    // fijamos el valor 3 a todas las componentes del arreglo
    arreglo1.fill(3);
    console.log(arreglo1); // [3, 3, 3, 3, 3, 3, 3]
    // fijamos el valor 0 desde la componente 3 del arreglo
    // hasta el final
    arreglo1.fill(0, 3);
    console.log(arreglo1); // [3, 3, 3, 0, 0, 0, 0]
    // fijamos el valor 5 a todas las componentes
    arreglo1.fill(5);
    console.log(arreglo1); // [5, 5, 5, 5, 5, 5, 5]
    // fijamos el valor 5 desde la componente 3 hasta
    // la componente 5 sin incluirla
    arreglo1.fill(100, 3, 5);
    console.log(arreglo1); // [5, 5, 5, 100, 100, 5, 5]
    // fijamos el valor 5 a todas las componentes
    arreglo1.fill(5);
    console.log(arreglo1); // [5, 5, 5, 5, 5, 5, 5]
    // fijamos el valor 100 en las dos últimas componentes
    arreglo1.fill(100, -2);
    console.log(arreglo1); // [5, 5, 5, 5, 5, 100, 100]
    // fijamos el valor 5 a todas las componentes
    arreglo1.fill(5);
    console.log(arreglo1); // [5, 5, 5, 5, 5, 5, 5]
    // fijamos el valor 100 en la antepenúltima y penúltima
    // posición
    arreglo1.fill(100, -3, -1);
    console.log(arreglo1); // [5, 5, 5, 5, 100, 100, 5]
  </script>
</body>

</html>

Si indicamos un solo valor se modifican todas las componentes del arreglo:

    arreglo1.fill(3);

Podemos indicar desde que posición se comienza a modificar:

    // fijamos el valor 0 desde la componente 3 del arreglo
    // hasta el final
    arreglo1.fill(0, 3);

También podemos indicar desde y hasta que componente se deben modificar:

    // fijamos el valor 5 desde la componente 3 hasta
    // la componente 5 sin incluirla
    arreglo1.fill(100, 3, 5);

Finalmente podemos indicar con valores negativos comenzar desde el final del arreglo:

    // fijamos el valor 100 en las dos últimas componentes
    arreglo1.fill(100, -2);
    console.log(arreglo1); // [5, 5, 5, 5, 5, 100, 100]
    // fijamos el valor 100 en la antepenúltima y penúltima
    // posición
    arreglo1.fill(100, -3, -1);
    console.log(arreglo1); // [5, 5, 5, 5, 100, 100, 5]

Método 'copyWithin'.

El método 'copyWithin' permite copiar algunas componentes de un arreglo en otra parte del mismo arreglo. En ningún caso permite redimensionarlo.

Veamos un ejemplo y los efectos del método 'copyWithin':

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    let arreglo1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    // Copiar a partir de la posición cero del arreglo
    // los elementos comprendidos entre las posiciones
    // 5 y 8
    arreglo1.copyWithin(0, 5, 8);
    console.log(arreglo1); // [6, 7, 8, 4, 5, 6, 7, 8, 9]
    arreglo1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    // Copiar a partir de la posición cero del arreglo
    // los elementos comprendidos desde la posición 5
    // hasta el final
    arreglo1.copyWithin(0, 5);
    console.log(arreglo1); // [6, 7, 8, 9, 5, 6, 7, 8, 9]    
    arreglo1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    // Copiar a partir de la posición cero los dos últimos
    // elementos del arreglo
    arreglo1.copyWithin(0, -2);
    console.log(arreglo1); // [8, 9, 3, 4, 5, 6, 7, 8, 9]
  </script>
</body>

</html>

El método 'copyWithin' es muy eficiente cuando debemos copiar un bloque de un arreglo a otra parte dentro del mismo arreglo.

Búsquedas de valores e índices en un arreglo: indexOf, lastIndexOf e include.

Disponemos de una serie de métodos para recuperar el índice donde se encuentra un elemento en un arreglo. También mediante el método 'include' podemos identificar si un determinado valor está contenido en el Array.

El siguiente ejemplo muestra distintas variantes de los métodos:

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    let arreglo1 = [10, 20, 30, 40, 50, 60, 10, 20, 30];
    // Indice donde se almacena el valor 30
    console.log(arreglo1.indexOf(30)); // 2
    // Indice donde se almacena un valor inexistente
    console.log(arreglo1.indexOf(100)); // -1
    // Indice donde se almacena el valor 20
    // buscándo desde el final
    console.log(arreglo1.lastIndexOf(20)); // 7
    // Indice donde se almacena el valor 10
    // comenzando la búsqueda en la posición 5
    console.log(arreglo1.indexOf(10, 5)); // 6
    // Existe el valor 50 en el arreglo?
    console.log(arreglo1.includes(50)); // true
    // Existe el valor 100 en el arreglo?
    console.log(arreglo1.includes(100)); // false

  </script>
</body>

</html>

Al método includes también podemos pasar un segundo parámetro que indica a partir de que posición dentro del arreglo comenzar a buscar:

    // Existe el valor 100 en el arreglo a partir de
    // la posición 2?
    console.log(arreglo1.includes(100, 2)); 

Métodos 'find' y 'findIndex'.

Estos dos métodos nos permiten enviar una función anónima donde definimos el algoritmo de la búsqueda:

`<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    const personas = [
      {
        nombre: "pedro",
        edad: 34
      },
      {
        nombre: "ana",
        edad: 54
      },
      {
        nombre: "carlos",
        edad: 12
      },
      {
        nombre: "maría",
        edad: 22
      },
      {
        nombre: "oscar",
        edad: 72
      }
    ];

    let per = personas.find((persona, indice) => persona.nombre == "maría");
    if (per != undefined)
      console.log(per);
    else
      console.log("No se encuentra maría en el vector de objetos");
    let indice = personas.findIndex((persona, indice) => persona.nombre == "maría");
    if (indice != -1)
      console.log("Se encuentra en la posción "+indice+" del arreglo.");
    else
      console.log("No se encuentra maría en el vector de objetos");

  </script>
</body>

</html>

El método find retorna el valor 'undefined' si no retorna true el algoritmo dispuesto en la función anónima. En el caso que se encuentra el valor buscado luego retorna el valor de la posición donde se lo ubicó.

Finalmente el método findIndex si la función anónima retorna true luego el método retorna la posición donde se encontró el valor a buscar.

Estamos utilizando funciones flecha, pero nada nos impide de utilizar la sintaxis de funciones anónimas tradicionales:

    let per = personas.find(function (persona, indice) { return persona.nombre == "maría" });
    if (per != undefined)
      console.log(per);
    else
      console.log("No se encuentra maría en el vector de objetos");
    let indice = personas.findIndex(function (persona, indice) { return persona.nombre == "maría" });
    if (indice != -1)
      console.log("Se encuentra en la posción " + indice + " del arreglo.");
    else
      console.log("No se encuentra maría en el vector de objetos");

Métodos every y some.

Al método 'every' debemos pasar una función anónima que procesa cada elemento del arreglo. Si todos los elementos cumplen la condición impuesta dentro de la función, luego el método 'every' retorna true.
En cambio con el método 'some' con que un elemento cumpla la condición impuesta luego el método retorna true.

every (todos) some (alguno)

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    const personas = [
      {
        nombre: "pedro",
        edad: 34
      },
      {
        nombre: "ana",
        edad: 54
      },
      {
        nombre: "carlos",
        edad: 12
      },
      {
        nombre: "maría",
        edad: 22
      },
      {
        nombre: "oscar",
        edad: 72
      }
    ];
    // Todas las personas tienen una edad menor a 100?
    console.log(personas.every((elemento, indice, arreglo) => elemento.edad < 100)); // true
    // Todas las personas son mayor de edad?
    console.log(personas.every((elemento, indice, arreglo) => elemento.edad >= 18)); // false
    // Todas las personas tienen un nombre con 6 o menos caracteres?
    console.log(personas.every((elemento, indice, arreglo) => elemento.nombre.length <= 6)); // true
    // Alguna persona tiene 100 años de edad?
    console.log(personas.some((elemento, indice, arreglo) => elemento.edad == 100)); // false
    // Alguna persona es menor de edad?
    console.log(personas.some((elemento, indice, arreglo) => elemento.edad <= 18)); // true
  </script>
</body>

</html>

Método filter.

El método 'filter' retorna un arreglo con todos los elementos del arreglo original que cumplen una condición que definimos en la función anónima que le pasamos:

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    const personas = [
      {
        nombre: "pedro",
        edad: 34
      },
      {
        nombre: "ana",
        edad: 54
      },
      {
        nombre: "carlos",
        edad: 12
      },
      {
        nombre: "maría",
        edad: 22
      },
      {
        nombre: "oscar",
        edad: 72
      }
    ];
    // Recuperar todas las personas mayores de edad
    const personasmayores = personas.filter((elemento, indice, arreglo) => elemento.edad >= 18);
    console.log(personasmayores); // [{nombre: "pedro",edad: 34},{nombre: "ana",edad: 54},
                                  //  {nombre: "maría",edad: 22},{nombre: "oscar",edad: 72}]
  </script>
</body>

</html>

Tener en cuenta que la función anónima debe retornar true si queremos que el elemento se almacene en el arreglo generado. Si bien no tiene sentido, si queremos que se guarden todos los elementos luego podemos codificar:

    const personasmayores = personas.filter((elemento, indice, arreglo) => true);

Recordar que si no utilizamos funciones flecha el algoritmo será:

    const personasmayores = personas.filter(function (elemento, indice, arreglo) { return true });

Método map.

El método 'map' similar al método 'filter' retorna un arreglo cuyos elementos resultan de las operaciones que se efectúan dentro de la función anónima que le pasamos como parámetro:

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    const arreglo1 = [1, 2, 3, 4, 5];
    // Generar un nuevo arreglo con los elementos del arreglo1 elevalos al cuadrado
    const arreglo2 = arreglo1.map((elemento, indice, arreglo) => elemento ** 2);
    console.log(arreglo2); //[1, 4, 9, 16, 25]
  </script>
</body>

</html>

El arreglo generado siempre es del mismo tamaño que el arreglo original.

Métodos reduce y reduceRight.

El método 'reduce' recibe como primer parámetro una función cuyo primer parámetro es un valor que se arrastra entre cada proceso de un elemento del arreglo, el segundo parámetro de reduce es el valor inicial con el que inicia el acumulador (si no pasamos el segundo parámetro se inicia con el primer elemento del arreglo):

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    const arreglo1 = [1, 2, 73, 3, 4, 120, 5, 18];
    // Acumular todos los elementos que tienen un solo dígito
    const cantidad = arreglo1.reduce((acumulador, elemento, indice, arreglo) => {
      if (elemento < 10)
        acumulador += elemento;
      return acumulador;
    }, 0);
    console.log(cantidad); // 15
  </script>
</body>

</html>

El método 'reduceRight' es simila a 'reduce' con la diferencia que visita cada elemento del arreglo partiendo del final.

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de JavaScript</title>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    const arreglo1 = [1, 2, 73, 3, 4, 120, 5, 18];
    // Generar un nuevo arreglo con los elementos invertidos
    const arreglo2 = arreglo1.reduceRight((acumulador, elemento, indice, arreglo) => {
      acumulador.push(elemento);
      return acumulador;
    }, []);
    console.log(arreglo2); // [18, 5, 120, 4, 3, 73, 2, 1]
  </script>
</body>

</html>

El valor inicial es un arreglo vacío que le pasamos al método reduceRight:

[]

Y dentro de la función anónima agregamos cada elemento del vector visitando sus componentes a partir del final:

      acumulador.push(elemento);

Retornar