de Alex Permyakov

Cum să vă simplificați baza de coduri cu map (), reduce () și filter () în JavaScript

Cum sa va simplificati baza de coduri cu map
Fotografie de Anders Jildén pe Unsplash

Când citești despre Array.reduce și cât de mișto este, primul și uneori singurul exemplu pe care îl găsiți este suma numerelor. Aceasta nu este definiția noastră de „util”. ?

Mai mult, nu l-am văzut niciodată într-o bază de cod reală. Dar, ceea ce am văzut foarte mult este de 7-8 linii pentru instrucțiuni pentru buclă pentru rezolvarea unei sarcini obișnuite unde Array.reduce ar putea să o facă într-o singură linie.

Recent am rescris câteva module folosind aceste funcții grozave. M-a surprins cât de simplificat a devenit baza de coduri. Deci, mai jos este o listă de bunătăți.

Dacă aveți un bun exemplu de utilizare a unui Hartă sau reduce metodă – postați-o în secțiunea de comentarii. ?

Să începem!

1. Eliminați duplicatele dintr-o serie de numere / șiruri

Ei bine, acesta este singurul despre care nu este vorba Hartă/reduce/filtru, dar este atât de compact încât a fost greu să nu-l introduci în listă. În plus, îl vom folosi și în câteva exemple.

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

// uniqueValues is [3, 1, 5, 2, 4]

2. O căutare simplă (sensibilă la majuscule / minuscule)

filtru() metoda creează o nouă matrice cu toate elementele care trec testul implementat de funcția furnizată.

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. O căutare simplă (fără majuscule)

let res = users.filter(it => new RegExp('oli', "i").test(it.name));

// res is
[
  { id: 97, name: 'Oliver', age: 28, group: 'admin' }
]

4. Verificați dacă vreunul dintre utilizatori are drepturi de administrator

niste() metoda testează dacă cel puțin un element din matrice trece testul implementat de funcția furnizată.

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

// hasAdmin is true

5. Aplatizarea unei matrice de tablouri

Rezultatul primei iterații este egal cu: […[], …[1, 2, 3]]înseamnă că se transformă în [1, 2, 3] – această valoare pe care o oferim ca ‘acc’ la a doua iterație și așa mai departe.

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]

Putem îmbunătăți ușor acest cod omițând o matrice goală[]ca al doilea argument pentru reduce(). Apoi prima valoare a cuibărit va fi folosit ca inițială acc valoare. Mulțumită Vladimir Efanov.

let flat = nested.reduce((acc, it) => [...acc, ...it]);

// flat is [1, 2, 3, 4, 5, 6, 7, 8, 9]

Rețineți că folosind operator de răspândire în interiorul unui reduce nu este excelent pentru performanță. Acest exemplu este un caz când măsurarea performanței are sens pentru cazul dvs. de utilizare. ☝️

Mulțumită Paweł Wolak, aici este o cale mai scurtă fără Array.reduce:

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

De asemenea Array.flat vine, dar este încă o caracteristică experimentală.

6. Creați un obiect care conține frecvența cheii specificate

Să grupăm și să numărăm proprietatea „vârstă” pentru fiecare articol din matrice:

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) => {
  acc[it.age] = acc[it.age] + 1 || 1;
  return acc;
}, {});

// groupByAge is {23: 1, 28: 2, 34: 1}

Mulțumită sai krishna pentru sugerarea acestuia!

7. Indexarea unei matrice de obiecte (tabel de căutare)

În loc să procesăm întreaga matrice pentru găsirea unui utilizator după ID, putem construi un obiect în care ID-ul utilizatorului reprezintă o cheie (cu timp de căutare constant).

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' }
}

Este util atunci când trebuie să vă accesați datele prin id uTable[85].name mult.

8. Extrageți valorile unice pentru cheia dată a fiecărui element din matrice

Să creăm o listă a grupurilor de utilizatori existenți. Hartă() metoda creează o nouă matrice cu rezultatele apelării unei funcții furnizate pe fiecare element din matricea apelantă.

const listOfUserGroups = [...new Set(users.map(it => it.group))];

// listOfUserGroups is ['editor', 'admin'];

9. Inversarea hărții cheie-valoare a obiectului

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"]
}

Acest one-liner pare destul de complicat. Noi folosim operator virgulă aici și înseamnă că returnăm ultima valoare dintre paranteze – acc. Să rescriem acest exemplu într-un mod mai pregătit pentru producție și mai performant:

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

Aici nu folosim operator de răspândire – creează o nouă matrice pe fiecare reduce() apel, ceea ce duce la o penalizare de performanță mare: O (n²). În schimb vechiul bine Apăsați() metodă.

10. Creați o matrice de valori Fahrenheit dintr-o matrice de valori Celsius

Vă gândiți la aceasta ca procesând fiecare element cu o formulă dată?

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ți un obiect într-un șir de interogare

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ți un tabel de utilizatori ca un șir lizibil numai cu cheile specificate

Uneori doriți să imprimați matricea de obiecte cu tastele selectate ca șir, dar vă dați seama de asta JSON.stringify nu-i așa grozav?

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 poate face ieșirea șirului mai lizibilă, dar nu ca tabel:

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. Găsiți și înlocuiți o pereche cheie-valoare într-o serie de obiecte

Să presupunem că vrem să schimbăm vârsta lui John. Dacă cunoașteți indexul, puteți scrie acest rând: users[1].age = 29. Cu toate acestea, să aruncăm o privire la un alt mod de a face acest lucru:

const updatedUsers = users.map(
  p => p.id !== 47 ? p : {...p, age: p.age + 1}
);

// John is turning 29 now

Aici, în loc să schimbăm un singur element din matricea noastră, creăm unul nou, cu un singur element diferit. Acum putem compara matricele noastre doar prin referință ca updatedUsers == users care este super rapid! React.js folosește această abordare pentru a accelera procesul de reconciliere. Iată o explicație.

14. Unirea (A ∪ B) de matrice

Cod mai puțin decât importul și apelarea uniunea metodei lodash.

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. Intersecția (A ∩ B) a matricilor

Ultimul!

const arrA = [1, 4, 3, 2];
const arrB = [5, 2, 6, 7, 1];

arrA.filter(it => arrB.includes(it)); // returns [1, 2]

Ca exercițiu, încercați să implementați diferența (A B) a matricelor. Sugestie: utilizați un semn de exclamare.

Mulțumită Asmor și se incarneaza marele pentru comentariile lor despre # 9.

Asta este!

Dacă aveți întrebări sau feedback, anunțați-mă în comentariile de mai jos sau trimiteți-mi un mesaj Stare de nervozitate.

Dacă acest lucru a fost util, faceți clic pe clap? butonul de mai jos de câteva ori pentru a vă arăta sprijinul! ⬇⬇ ??

Iată mai multe articole pe care le-am scris:

Cum să începeți cu internaționalizarea în JavaScript
Prin adaptarea aplicației noastre pentru diferite limbi și țări, oferim o experiență de utilizare mai bună. Este mai simplu pentru utilizatori …

Gata de producție Configurarea API-urilor REST Node.js folosind TypeScript, PostgreSQL și Redis.
Acum o lună mi s-a dat sarcina de a construi un API de căutare simplu. Tot ce trebuia să facă este să ia câteva date de la terți …

Mulțumesc că ai citit ❤️