Cómo simplificar su base de código con map (), reduce () y filter () en JavaScript

Cuando lees sobre Array.reduce y lo genial que es, el primer y, a veces, el único ejemplo que encuentras es la suma de números. Esta no es nuestra definición de "útil". ?

Además, nunca lo he visto en una base de código real. Pero lo que he visto mucho son sentencias de 7 a 8 líneas para bucle para resolver una tarea regular en la que Array.reduce podría hacerlo en una línea.

Recientemente reescribí algunos módulos usando estas excelentes funciones. Me sorprendió lo simplificado que se volvió el código base. Entonces, a continuación hay una lista de golosinas.

Si tiene un buen ejemplo de cómo utilizar un mapa o un método de reducción , publíquelo en la sección de comentarios. ?

¡Empecemos!

1. Elimina duplicados de una serie de números / cadenas

Bueno, este es el único que no se trata de map / reduce / filter , pero es tan compacto que fue difícil no ponerlo en la lista. Además, también lo usaremos en algunos ejemplos.

const values = [3, 1, 3, 5, 2, 4, 4, 4]; const uniqueValues = [...new Set(values)]; // uniqueValues is [3, 1, 5, 2, 4]

2. Una búsqueda simple (distingue entre mayúsculas y minúsculas)

El método filter () crea una nueva matriz con todos los elementos que pasan la prueba implementada por la función proporcionada.

const users = [ { id: 11, name: 'Adam', age: 23, group: 'editor' }, { id: 47, name: 'John', age: 28, group: 'admin' }, { id: 85, name: 'William', age: 34, group: 'editor' }, { id: 97, name: 'Oliver', age: 28, group: 'admin' } ]; let res = users.filter(it => it.name.includes('oli')); // res is []

3. Una búsqueda simple (no distingue entre mayúsculas y minúsculas)

let res = users.filter(it => new RegExp('oli', "i").test(it.name)); // res is [ { id: 97, name: 'Oliver', age: 28, group: 'admin' } ]

4. Compruebe si alguno de los usuarios tiene derechos de administrador.

El método some () prueba si al menos un elemento de la matriz pasa la prueba implementada por la función proporcionada.

const hasAdmin = users.some(user => user.group === 'admin'); // hasAdmin is true

5. Acoplamiento de una matriz de matrices

El resultado de la primera iteración es igual a: [… [],… [1, 2, 3]] significa que se transforma en [1, 2, 3] - este valor lo proporcionamos como un 'acc' en la segunda iteración y pronto.

const nested = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; let flat = nested.reduce((acc, it) => [...acc, ...it], []); // flat is [1, 2, 3, 4, 5, 6, 7, 8, 9]

Podemos mejorar ligeramente este código omitiendo una matriz vacía []como segundo argumento para reduce (). Entonces, el primer valor del anidado se usará como el valor de acc inicial . Gracias a Vladimir Efanov.

let flat = nested.reduce((acc, it) => [...acc, ...it]); // flat is [1, 2, 3, 4, 5, 6, 7, 8, 9]

Tenga en cuenta que usar el operador de extensión dentro de una reducción no es excelente para el rendimiento. Este ejemplo es un caso en el que medir el rendimiento tiene sentido para su caso de uso. ☝️

Gracias a Paweł Wolak, aquí hay un camino más corto sin Array.reduce:

let flat = [].concat.apply([], nested);

También viene Array.flat , pero sigue siendo una función experimental.

6. Cree un objeto que contenga la frecuencia de la clave especificada

Agrupemos y contemos la propiedad 'edad' para cada elemento de la matriz:

const users = [ { id: 11, name: 'Adam', age: 23, group: 'editor' }, { id: 47, name: 'John', age: 28, group: 'admin' }, { id: 85, name: 'William', age: 34, group: 'editor' }, { id: 97, name: 'Oliver', age: 28, group: 'admin' } ]; const groupByAge = users.reduce((acc, it) => , {}); // groupByAge is {23: 1, 28: 2, 34: 1}

¡Gracias a sai krishna por sugerir este!

7. Indexación de una matriz de objetos (tabla de búsqueda)

En lugar de procesar toda la matriz para encontrar un usuario por identificación, podemos construir un objeto donde la identificación del usuario representa una clave (con un tiempo de búsqueda constante).

const uTable = users.reduce((acc, it) => (acc[it.id] = it, acc), {}) // uTable equals: { 11: { id: 11, name: 'Adam', age: 23, group: 'editor' }, 47: { id: 47, name: 'John', age: 28, group: 'admin' }, 85: { id: 85, name: 'William', age: 34, group: 'editor' }, 97: { id: 97, name: 'Oliver', age: 28, group: 'admin' } }

Es útil cuando tienes que acceder a tus datos por identificación como uTable[85].namemucho.

8. Extraiga los valores únicos para la clave dada de cada elemento de la matriz.

Creemos una lista de los grupos de usuarios existentes. El método map () crea una nueva matriz con los resultados de llamar a una función proporcionada en cada elemento de la matriz de llamada.

const listOfUserGroups = [...new Set(users.map(it => it.group))]; // listOfUserGroups is ['editor', 'admin'];

9. Inversión del mapa de valores-clave de objeto

const cities = { Lyon: 'France', Berlin: 'Germany', Paris: 'France' }; let countries = Object.keys(cities).reduce( (acc, k) => (acc[cities[k]] = [...(acc[cities[k]] || []), k], acc) , {}); // countries is { France: ["Lyon", "Paris"], Germany: ["Berlin"] }

Este resumen parece bastante complicado. Usamos el operador de coma aquí, y significa que devolvemos el último valor entre paréntesis - acc. Reescribamos este ejemplo de una manera más productiva y lista para la producción:

let countries = Object.keys(cities).reduce((acc, k) =>  []; acc[country].push(k); return acc; , {});

Aquí no usamos el operador de propagación, crea una nueva matriz en cada llamada reduce () , lo que conduce a una gran penalización de rendimiento: O (n²). En su lugar, el viejo método push () .

10. Cree una matriz de valores Fahrenheit a partir de una matriz de valores Celsius

¿Piensa en ello como procesar cada elemento con una fórmula determinada?

const celsius = [-15, -5, 0, 10, 16, 20, 24, 32] const fahrenheit = celsius.map(t => t * 1.8 + 32); // fahrenheit is [5, 23, 32, 50, 60.8, 68, 75.2, 89.6]

11. Codifica un objeto en una cadena de consulta.

const params = {lat: 45, lng: 6, alt: 1000}; const queryString = Object.entries(params).map(p => encodeURIComponent(p[0]) + '=' + encodeURIComponent(p[1])).join('&') // queryString is "lat=45&lng=6&alt=1000"

12. Imprima una tabla de usuarios como una cadena legible solo con claves específicas

A veces desea imprimir su matriz de objetos con claves seleccionadas como una cadena, pero se da cuenta de que JSON.stringify no es tan bueno.

const users = [ { id: 11, name: 'Adam', age: 23, group: 'editor' }, { id: 47, name: 'John', age: 28, group: 'admin' }, { id: 85, name: 'William', age: 34, group: 'editor' }, { id: 97, name: 'Oliver', age: 28, group: 'admin' } ]; users.map(({id, age, group}) => `\n${id} ${age} ${group}`).join('') // it returns: " 11 23 editor 47 28 admin 85 34 editor 97 28 admin"

JSON.stringify puede hacer que la salida de la cadena sea más legible, pero no como una tabla:

JSON.stringify(users, ['id', 'name', 'group'], 2); // it returns: "[ { "id": 11, "name": "Adam", "group": "editor" }, { "id": 47, "name": "John", "group": "admin" }, { "id": 85, "name": "William", "group": "editor" }, { "id": 97, "name": "Oliver", "group": "admin" } ]"

13. Busque y reemplace un par clave-valor en una matriz de objetos

Digamos que queremos cambiar la edad de John. Si conoce el índice, se puede escribir la siguiente línea: users[1].age = 29. Sin embargo, echemos un vistazo a otra forma de hacerlo:

const updatedUsers = users.map( p => p.id !== 47 ? p : {...p, age: p.age + 1} ); // John is turning 29 now

Aquí, en lugar de cambiar un solo elemento en nuestra matriz, creamos uno nuevo con solo un elemento diferente. Ahora podemos comparar nuestras matrices solo por referencia, ¡lo updatedUsers == userscual es súper rápido! React.js usa este enfoque para acelerar el proceso de reconciliación. He aquí una explicación.

14. Unión (A ∪ B) de matrices

Less code than importing and calling the lodash method union.

const arrA = [1, 4, 3, 2]; const arrB = [5, 2, 6, 7, 1]; [...new Set([...arrA, ...arrB])]; // returns [1, 4, 3, 2, 5, 6, 7]

15. Intersection (A ∩ B) of arrays

The last one!

const arrA = [1, 4, 3, 2]; const arrB = [5, 2, 6, 7, 1]; arrA.filter(it => arrB.includes(it)); // returns [1, 2]

As an exercise try to implement difference (A \ B) of the arrays. Hint: use an exclamation mark.

Thanks to Asmor and incarnatethegreat for their comments about #9.

That’s it!

If you have any questions or feedback, let me know in the comments down below or ping me on Twitter.

If this was useful, please click the clap ? button down below a few times to show your support! ⬇⬇ ??

Here are more articles I’ve written:

How to get started with internationalization in JavaScript

By adapting our app for different languages and countries, we provide a better user experience. It’s simpler for users…

Production ready Node.js REST APIs Setup using TypeScript, PostgreSQL and Redis.

A month ago I was given a task to build a simple Search API. All It had to do is to grab some data from 3rd party…

Thanks for reading ❤️