Jeżeli nie używasz funkcji .map(), .filter() i .reduce() – najwyższa pora zacząć. Funkcje te sprawiają, że kod jest czytelniejszy, prostszy, a przede wszystkim szybciej się go pisze.

Map

Funkcja Map tworzy nową tablicę z wynikami wykonania podanej funkcji na każdym elemencie tablicy. Wynika z tego, że tworzy tablicę o takiej samej długości jak tablica oryginalna. Przykład – chcemy podwoić każdy element tablicy z liczbami. Robiąc to z użyciem .forEach() mamy:

var liczby = [1, 2, 3, 4];

var podwojone = [];
liczby.forEach(function(x){
  podwojone.push(x*2);
});

Jak na coś tak prostego to trochę sporo kodu, no i wygląda to tak średnio. Z użyciem .map() wygląda to tak:

var liczby = [1, 2, 3, 4];

var podwojone = liczby.map(function(x){
  return x*2;
});

Już nieco prościej, prawda? Nie musimy tworzyć tablicy przed jej wykorzystaniem, tylko możemy to zrobić od razu w tej samej linii. Sposób użycia .map() jest podobny jak .forEach(), tylko zamiast pushować elementy do tablicy od razu je zwracamy. Cała reszta dzieje się automagicznie.

Używając ES6, przykład może wyglądać jeszcze prościej:

var liczby = [1, 2, 3, 4];

var podwojone = liczby.map(x => x*2);

Proste, przyjemne, ładne i czytelne. Tak trzymaj! Czas na nieco bardziej zaawansowany przykład. Chcemy z listy napojów restauracji stworzyć listę tylko z nazwami:

var napoje = [
  {
    id: 1,
    nazwa: 'kawa',
    cena: 9,
    categoryId: 1
  },
  {
    id: 2,
    nazwa: 'herbata',
    cena: 8,
    categoryId: 1
  },
  {
    id: 3,
    nazwa: 'cola',
    cena: 8,
    categoryId: 2
  },
  {
    id: 4,
    nazwa: 'piwo',
    cena: 12,
    categoryId: 3
  },
  {
    id: 5,
    nazwa: 'whisky',
    cena: 20,
    categoryId: 3
  }
]

var nazwy = napoje.map(x => x.nazwa);

I gotowe. Teraz kiedy chciałbyś np. listę nazw, ale z przedrostkiem „nazwa – ”, wystarczy, że zmienisz wnętrze funkcji:

var nazwy = napoje.map(x => 'nazwa - ' + x.nazwa);

Proste i przyjemne. Jak widzisz, funkcja .map() sporo upraszcza. Nic, tylko używać :)

Filter

Funkcja .filter() tworzy nową tablicę ze wszystkimi elementami, które przeszły test. Robiąc to z .forEach(), jeżeli chcemy wybrać tylko napoje tańsze niż 10 zł, wyglądałoby to tak:

var napoje = [
  {
    id: 1,
    nazwa: 'kawa',
    cena: 9,
    categoryId: 1
  },
  {
    id: 2,
    nazwa: 'herbata',
    cena: 8,
    categoryId: 1
  },
  {
    id: 3,
    nazwa: 'cola',
    cena: 8,
    categoryId: 2
  },
  {
    id: 4,
    nazwa: 'piwo',
    cena: 12,
    categoryId: 3
  },
  {
    id: 5,
    nazwa: 'whisky',
    cena: 20,
    categoryId: 3
  }
]

var tanie = [];
napoje.forEach(function(x){
  if(x.cena < 10) {
    tanie.push(x);
  }
});

Znowu sporo kodu. A teraz – czas na uzycie funkcji .filter():

var tanie = napoje.filter(function(x) {
  return x.cena < 10;
});

Wersja ES6:

var tanie = napoje.filter(x => x.cena < 10);

Prosto i przyjemnie, prawda?

Reduce

Funkcja .reduce(), jak sama nazwa wskazuje, redukuje, czyli sprowadza całą tablicę do jednej wartości. Bardzo często jest to potrzebne, więc warto się z tym zapoznać. Przykład – wracając znowu do przykładu z napojami, powiedzmy, że chcemy znać cenę wszystkich napojów naraz. Używając .forEach(), wygląda to tak:

var napoje = [
  {
    id: 1,
    nazwa: 'kawa',
    cena: 9,
    categoryId: 1
  },
  {
    id: 2,
    nazwa: 'herbata',
    cena: 8,
    categoryId: 1
  },
  {
    id: 3,
    nazwa: 'cola',
    cena: 8,
    categoryId: 2
  },
  {
    id: 4,
    nazwa: 'piwo',
    cena: 12,
    categoryId: 3
  },
  {
    id: 5,
    nazwa: 'whisky',
    cena: 20,
    categoryId: 3
  }
]


var cena = 0;
napoje.forEach(function(x){
  cena = cena + x.cena;
});

Kiedy używamy .reduce(), wygląda to tak:

var cena = napoje.reduce(function (calaCena, x) {
  return calaCena + x.cena;
}, 0);

Zero na końcu oznacza początkową wartość zmiennej calaCena. Wersja ES6:

var cena = napoje.reduce((calaCena, x) => calaCena + x.cena, 0);

Prawda, że proste? A jaka czytelność. Nic, tylko używać! :D

Połączenie Map, Filter i Reduce

Jeżeli zajdzie potrzeba, można połączyć wszystkie trzy funkcje. Pomińmy opcję z .forEach(), skupmy się na funkcjach. Powiedzmy, że chcemy poznać cenę naszego zamówienia – wszystkie rzeczy kosztujące więcej niż 8 zł chcemy zamówić po 8 razy. Jako że zamówienie jest spore, dostaliśmy 10% zniżki na alkohole i 20% na resztę.

var cena = napoje
.filter(function(x) {
  return x.cena > 8;
})
.map(function(x) {
  return x.categoryId === 3 ? x.cena * 0.9 : x.cena * 0.8;
})
.reduce(function (calaCena, x) {
  return calaCena + x * 8;
}, 0);

Użycie .map() jest troszkę wymuszone w celu pokazania użycia wszystkich funkcji, niemniej widzisz, jak to wygląda. Jako że funkcje .filter() i .map() zwracają tablice, można je fajnie łączyć za sobą. Funkcja .reduce() przyjmuje tablice i zwraca nasz wynik. Jak widzisz – wygląda to całkiem fajnie. Wersja ES6 wygląda tak:

var cena = napoje
.filter(x => x.cena > 8)
.map(x => x.categoryId === 3 ? x.cena * 0.9 : x.cena * 0.8)
.reduce((calaCena, x) => calaCena + x * 8, 0);

Prawda, że wygląda to fajne? A jak czytelnie :D

Podsumowanie

Używanie powyższych funkcji sprawia, że kod jest czytelniejszy i szybciej się go pisze. Poprawia również Twoje umiejętności kodowania, a przy okazji można się nauczyć ES6. Same plusy! Zachęcam Cię gorąco do używania tych funkcji i pracy nad swoim kodem.

Jeżeli chciałbyś coś dodać, masz swoje porady odnośnie do powyższych funkcji lub po prostu chcesz zadać pytanie – zapraszam do komentarzy.