Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds

Funkcje wyższego rzędu: map, filter, reduce

W laboratoriach Parku Jurajskiego naukowcy codziennie przetwarzają ogromne ilości danych o dinozaurach - filtrują próbki DNA, transformują wyniki analiz i agregują statystyki. Funkcje wyższego rzędu (higher-order functions) to narzędzia, które pozwalają robić to samo z danymi w JavaScript - elegancko, czytelnie i bezpiecznie.

Czym jest funkcja wyższego rzędu?

Funkcja wyższego rzędu to funkcja, która przyjmuje inną funkcję jako argument lub zwraca funkcję jako wynik. To jak maszyna w laboratorium, która przyjmuje instrukcję (funkcję) i stosuje ją do każdej próbki DNA.

Array.map() - transformacja danych

map
tworzy nową tablicę, stosując podaną funkcję do każdego elementu. Oryginalna tablica pozostaje nienaruszona.

1const specimens = [
2  { name: 'Rex', weight: 8000, age: 5 },
3  { name: 'Blue', weight: 150, age: 3 },
4  { name: 'Brachio', weight: 56000, age: 12 },
5];
6
7// Transformacja - wydobycie samych nazw
8const names = specimens.map((dino) => dino.name);
9// ['Rex', 'Blue', 'Brachio']
10
11// Transformacja - obliczenie raportu
12const reports = specimens.map((dino) => ({
13  label: dino.name.toUpperCase(),
14  weightInTons: dino.weight / 1000,
15  category: dino.weight > 5000 ? 'large' : 'small',
16}));
17// [{ label: 'REX', weightInTons: 8, category: 'large' }, ...]

Array.filter() - selekcja danych

filter
tworzy nową tablicę z elementami, które spełniają warunek (predykat). To jak filtrowanie próbek DNA - zostawiasz tylko te, które przechodzą kontrolę jakości.

1const allDinosaurs = [
2  { name: 'Rex', diet: 'carnivore', health: 95 },
3  { name: 'Brachio', diet: 'herbivore', health: 88 },
4  { name: 'Raptor', diet: 'carnivore', health: 42 },
5  { name: 'Stego', diet: 'herbivore', health: 100 },
6];
7
8// Filtrowanie - tylko zdrowe dinozaury
9const healthy = allDinosaurs.filter((dino) => dino.health > 80);
10// [Rex, Brachio, Stego]
11
12// Filtrowanie - drapiezniki potrzebujace pomocy
13const sickCarnivores = allDinosaurs.filter(
14  (dino) => dino.diet === 'carnivore' && dino.health < 50
15);
16// [Raptor]

Array.reduce() - agregacja danych

reduce
przetwarza tablicę do pojedynczej wartości, kumulując wynik element po elemencie. To jak raport podsumowujący - zbiera dane ze wszystkich wybiegów i tworzy jedno podsumowanie.

1const parkData = [
2  { zone: 'A', dinosaurs: 5, incidents: 0 },
3  { zone: 'B', dinosaurs: 3, incidents: 2 },
4  { zone: 'C', dinosaurs: 8, incidents: 1 },
5];
6
7// Suma wszystkich dinozaurow
8const totalDinos = parkData.reduce(
9  (sum, zone) => sum + zone.dinosaurs, 0
10);
11// 16
12
13// Grupowanie stref wedlug bezpieczenstwa
14const grouped = parkData.reduce((groups, zone) => {
15  const key = zone.incidents === 0 ? 'safe' : 'risky';
16  return { ...groups, [key]: [...(groups[key] || []), zone.zone] };
17}, {});
18// { safe: ['A'], risky: ['B', 'C'] }

Łączenie map, filter i reduce

Prawdziwa siła FP objawia się, gdy łączymy te funkcje w pipeline przetwarzania:

1const specimens = [
2  { id: 'S001', species: 'T-Rex', viability: 0.95, cost: 50000 },
3  { id: 'S002', species: 'Raptor', viability: 0.3, cost: 20000 },
4  { id: 'S003', species: 'Brachio', viability: 0.88, cost: 80000 },
5  { id: 'S004', species: 'Stego', viability: 0.72, cost: 35000 },
6  { id: 'S005', species: 'Raptor', viability: 0.91, cost: 22000 },
7];
8
9// Pipeline: filtruj viability > 0.7 -> oblicz koszt -> zsumuj
10const totalViableCost = specimens
11  .filter((s) => s.viability > 0.7)
12  .map((s) => s.cost * s.viability)
13  .reduce((total, cost) => total + cost, 0);
14// 47500 + 70400 + 25200 + 20020 = 163120
Przejdź do CodeWorlds