Librerías como lodash o underscore proveen utilidades que nos ayudarían a realizar la operación de “aplanar” un arreglo en JavaScript. Sin embargo con la constante evolución del estándar ECMAScript, ahora tenemos métodos para hacerlo con JavaScript puro y duro, sin dependencias adicionales a nuestro proyecto.

Array.prototype.flat()

flat que en ingles significa “plano” es el nombre del método en el prototipo del objeto Array que regresa una versión “aplanada” del arreglo en cuestión. Si no le pasamos ningún argumento se asume una profundidad de 1. De lo contrario si cualquier numero entero positivo es pasado como argumento este usa como la profundidad máxima a iterar a la hora de “aplanar” el arreglo.

Es decir, si tenemos el siguiente arreglo y una profundidad de 1

var a = [1, [2, 3], [4, 5], 6]

El arreglo “aplanado” sería

[1, 2, 3, 4, 5, 6]

Si tenemos el siguiente arreglo y una profundidad de 2

var b = [1, [2, [3]], [4, [5, 6]]]

El arreglo aplanado sería otra vez:

[1, 2, 3, 4, 5, 6]

Ahora para comprender mejor veamos como se comporta el método:

console.log(a.flat());
> Array(6) [ 1, 2, 3, 4, 5, 6 ]

console.log(b.flat(2));
> Array(6) [ 1, 2, 3, 4, 5, 6 ]

console.log(b.flat())
> Array(5) [1, 2, [3], 4, [5, 6]]

Noten como afecta la profundidad cuando no pasamos el argumento adecuado. Pero ¿qué pasa si quisiéramos aplanar un arreglo cuya profundidad desconocemos? Bien JavaScript introduce la constante Infinity, de modo que podemos hacer esto:

var arreglo = [1, ...., [190736], 190737];

arreglo.flat(Infinity);

Array.prototype.flatMap()

flatMap() es un método disponible en el prototipo del Array que tiene el mismo efecto que usar el método map() seguido inmediatamente del método flat() con una profundidad por defecto de 1. En otras palabras, flatMap(), mapea cada valor a un nuevo valor y el resultado es aplanado a una profundidad máxima de 1.

var transporte = ["avión", "auto", "barco"];
var tipoTransporte = ["aéreo", "terrestre", "marítimo"];

var transportesMapeados = transporte.map(
        (transporte, indice) => [transporte, tipoTransporte[indice]]
    );

var transportesMapeadosYAplanados = transporte.flatMap(
        (transporte, indice) => [transporte, tipoTransporte[indice]]
    );

Al correr estos ejemplos podemos ver claramente la diferencia principal entre uno y otro. El resultado de imprimir la variable transportesMapeados sería el siguiente:

[ 
  [ "avión", "aéreo" ]
  [ "auto", "terrestre" ]
  [ "barco", "marítimo" ]
]

Entonces si la definición de flatMap dice que al resultado de un map se le aplica flat de profundidad 1, al imprimir transportesMapeadosYAplanados tendríamos como resultado el siguiente arreglo:

[ "avión", "aéreo", "auto", "terrestre", "barco", "marítimo" ]

Compatibilidad

El soporte para estos dos métodos ya esta disponible en las ultimas versiones de los navegadores:

  • Chrome 69+
  • Firefox 12+
  • Safari 12+

como es de esperarse internet explorer aun no soporta ninguno de estos métodos,  por lo que seria bueno si quieren soportarlo hacer un polyFill para ese caso. O bien utilizar lodash o underscore se menciona al principio del post.

Categorized in:

Tagged in:

, ,