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

Iteracja po tablicach (forEach, map, filter, reduce)

W naszym Parku Jurajskim gromadzimy mnóstwo danych o dinozaurach - ich gatunki, wymiary, nawyki żywieniowe, poziomy agresji i wiele więcej. Gdy mamy tablicę pełną takich informacji, często potrzebujemy wykonać operacje na każdym z tych elementów. JavaScript oferuje szereg metod do iteracji po tablicach, które ułatwiają przetwarzanie danych.

Metoda forEach

Metoda

forEach
pozwala na wykonanie funkcji dla każdego elementu tablicy. Jest to podstawowy sposób iteracji, gdy chcemy wykonać jakąś operację, ale nie potrzebujemy zwracać nowej tablicy.

1// Tablica zawierająca obiekty reprezentujące dinozaury w naszym parku
2const dinosaurs = [
3  { name: "Tyrannosaurus", diet: "carnivore", aggressionLevel: 10 },
4  { name: "Triceratops", diet: "herbivore", aggressionLevel: 4 },
5  { name: "Velociraptor", diet: "carnivore", aggressionLevel: 9 },
6  { name: "Stegosaurus", diet: "herbivore", aggressionLevel: 2 },
7  { name: "Brachiosaurus", diet: "herbivore", aggressionLevel: 1 }
8];
9
10// Używamy forEach do wyświetlenia nazw wszystkich dinozaurów
11console.log("Lista dinozaurów w parku:");
12dinosaurs.forEach(function(dino) {
13  console.log(dino.name);
14});
15
16// Możemy również użyć funkcji strzałkowej (arrow function) dla bardziej zwięzłego zapisu
17console.log("Lista dinozaurów z poziomem agresji:");
18dinosaurs.forEach(dino => {
19  console.log(`${dino.name}: Poziom agresji ${dino.aggressionLevel}/10`);
20});

Metoda

forEach
nie zwraca żadnej wartości (a dokładnie zwraca
undefined
), więc używamy jej, gdy chcemy tylko wykonać jakieś działanie na elementach, bez tworzenia nowej tablicy.

Metoda map

Metoda

map
tworzy nową tablicę zawierającą wyniki wywołania dostarczonej funkcji dla każdego elementu oryginalnej tablicy. Jest to niezwykle przydatne, gdy chcemy przekształcić dane z jednej formy na drugą.

1// Używamy map do stworzenia nowej tablicy zawierającej tylko nazwy dinozaurów
2const dinoNames = dinosaurs.map(dino => dino.name);
3console.log("Nazwy dinozaurów:", dinoNames);
4// Wynik: ["Tyrannosaurus", "Triceratops", "Velociraptor", "Stegosaurus", "Brachiosaurus"]
5
6// Możemy też tworzyć bardziej złożone transformacje
7const dinoSummaries = dinosaurs.map(dino => {
8  return {
9    name: dino.name,
10    dangerLevel: dino.diet === "carnivore" ? "Wysoki" : "Niski",
11    warning: dino.aggressionLevel > 7 ? "Zachować szczególną ostrożność!" : "Standardowe procedury bezpieczeństwa"
12  };
13});
14
15console.log("Podsumowanie bezpieczeństwa dinozaurów:", dinoSummaries);

W przeciwieństwie do

forEach
, metoda
map
zawsze zwraca nową tablicę o tej samej długości co oryginalna, zawierającą przekształcone elementy.

Metoda filter

Metoda

filter
tworzy nową tablicę zawierającą tylko elementy, które spełniają określony warunek. Jest to idealne narzędzie, gdy potrzebujemy wyodrębnić podzbiór elementów z większej kolekcji.

1// Filtrujemy, aby uzyskać tylko dinozaury mięsożerne
2const carnivores = dinosaurs.filter(dino => dino.diet === "carnivore");
3console.log("Mięsożerne dinozaury:", carnivores);
4
5// Możemy łączyć warunki, aby tworzyć bardziej złożone filtry
6const dangerousDinos = dinosaurs.filter(dino => {
7  return dino.diet === "carnivore" && dino.aggressionLevel > 7;
8});
9console.log("Najbardziej niebezpieczne dinozaury:", dangerousDinos);
10
11// Możemy też łączyć filter z map, aby najpierw odfiltrować, a potem przekształcić dane
12const safetyWarnings = dinosaurs
13  .filter(dino => dino.aggressionLevel > 5)
14  .map(dino => `UWAGA: ${dino.name} ma wysoki poziom agresji!`);
15
16console.log("Ostrzeżenia bezpieczeństwa:", safetyWarnings);

Metoda

filter
zwraca nową tablicę, która może być krótsza niż oryginalna, zawierającą tylko elementy, które przeszły przez "filtr" (zwróciły
true
w funkcji testującej).

Metoda reduce

Metoda

reduce
jest najpotężniejszą z metod iteracyjnych, ale też najbardziej złożoną. Pozwala na "zredukowanie" tablicy do pojedynczej wartości, wykonując funkcję na każdym elemencie tablicy, z uwzględnieniem wyniku z poprzedniej iteracji.

1// Obliczamy sumę poziomów agresji wszystkich dinozaurów
2const totalAggressionLevel = dinosaurs.reduce((total, dino) => {
3  return total + dino.aggressionLevel;
4}, 0); // 0 to wartość początkowa
5
6console.log("Całkowity poziom agresji w parku:", totalAggressionLevel);
7
8// Możemy użyć reduce do tworzenia bardziej złożonych struktur, np. obiektu grupującego dinozaury według diety
9const dinosByDiet = dinosaurs.reduce((groups, dino) => {
10  // Jeśli grupa dla tej diety jeszcze nie istnieje, tworzymy ją
11  if (!groups[dino.diet]) {
12    groups[dino.diet] = [];
13  }
14
15  // Dodajemy dinozaura do odpowiedniej grupy
16  groups[dino.diet].push(dino.name);
17
18  return groups;
19}, {}); // {} to wartość początkowa (pusty obiekt)
20
21console.log("Dinozaury pogrupowane według diety:", dinosByDiet);
22// Wynik: { "carnivore": ["Tyrannosaurus", "Velociraptor"], "herbivore": ["Triceratops", "Stegosaurus", "Brachiosaurus"] }

Metoda

reduce
przyjmuje dwa parametry:

  1. Funkcję redukcji, która sama przyjmuje co najmniej dwa parametry:
    • Akumulator: wartość zwrócona z poprzedniej iteracji (lub wartość początkowa)
    • Bieżący element: aktualnie przetwarzany element tablicy
  2. Wartość początkową (opcjonalną, ale zdecydowanie zalecaną)

Metoda find

Metoda

find
zwraca pierwszy element tablicy, który spełnia podany warunek.

1// Szukamy dinozaura o określonej nazwie
2const stegosaurus = dinosaurs.find(dino => dino.name === "Stegosaurus");
3console.log("Informacje o Stegosaurusie:", stegosaurus);
4
5// Szukamy pierwszego dinozaura mięsożernego o agresji większej niż 8
6const dangerousCarnivore = dinosaurs.find(dino => {
7  return dino.diet === "carnivore" && dino.aggressionLevel > 8;
8});
9console.log("Pierwszy niebezpieczny mięsożerca:", dangerousCarnivore); // Tyrannosaurus

W przeciwieństwie do

filter
, który zwraca tablicę wszystkich pasujących elementów,
find
zwraca tylko pierwszy pasujący element, a jeśli nic nie pasuje, zwraca
undefined
.

Metoda some i every

Metody

some
i
every
zwracają wartość boolowską i są przydatne do sprawdzania, czy elementy tablicy spełniają określone kryteria.

some

Metoda

some
sprawdza, czy przynajmniej jeden element tablicy spełnia podany warunek.

1// Sprawdzamy, czy w parku są jakieś niebezpieczne dinozaury
2const hasHighAggressionDinos = dinosaurs.some(dino => dino.aggressionLevel > 8);
3console.log("Czy park ma dinozaury o wysokiej agresji?", hasHighAggressionDinos); // true
4
5// Sprawdzamy, czy w parku są jakieś dinozaury wszystkożerne
6const hasOmnivores = dinosaurs.some(dino => dino.diet === "omnivore");
7console.log("Czy park ma dinozaury wszystkożerne?", hasOmnivores); // false

every

Metoda

every
sprawdza, czy wszystkie elementy tablicy spełniają podany warunek.

1// Sprawdzamy, czy wszystkie dinozaury mają przypisany poziom agresji
2const allHaveAggressionLevel = dinosaurs.every(dino => dino.aggressionLevel !== undefined);
3console.log("Czy wszystkie dinozaury mają przypisany poziom agresji?", allHaveAggressionLevel); // true
4
5// Sprawdzamy, czy wszystkie dinozaury są roślinożerne
6const allHerbivores = dinosaurs.every(dino => dino.diet === "herbivore");
7console.log("Czy wszystkie dinozaury są roślinożerne?", allHerbivores); // false

Metoda sort

Metoda

sort
porządkuje elementy tablicy i zwraca posortowaną tablicę. Domyślnie metoda ta sortuje elementy jako ciągi znaków, co może prowadzić do nieoczekiwanych wyników przy sortowaniu liczb. Dlatego często przekazujemy funkcję porównującą.

1// Sortujemy dinozaury według nazwy (alfabetycznie)
2const dinosSortedByName = [...dinosaurs].sort((a, b) => {
3  return a.name.localeCompare(b.name);
4});
5console.log("Dinozaury posortowane alfabetycznie:", dinosSortedByName);
6
7// Sortujemy dinozaury według poziomu agresji (od najmniej do najbardziej agresywnych)
8const dinosSortedByAggression = [...dinosaurs].sort((a, b) => {
9  return a.aggressionLevel - b.aggressionLevel;
10});
11console.log("Dinozaury posortowane według agresji (rosnąco):", dinosSortedByAggression);
12
13// Sortujemy dinozaury według poziomu agresji (od najbardziej do najmniej agresywnych)
14const mostDangerousFirst = [...dinosaurs].sort((a, b) => {
15  return b.aggressionLevel - a.aggressionLevel;
16});
17console.log("Dinozaury posortowane według agresji (malejąco):", mostDangerousFirst);

Zauważ, że używamy operatora spread (

...
) do stworzenia kopii tablicy przed sortowaniem, ponieważ
sort
modyfikuje oryginalną tablicę, a my chcemy zachować oryginalną kolejność.

Łączenie metod

Jedną z najpotężniejszych cech tych metod jest możliwość ich łączenia w "łańcuchy", aby wykonać złożone operacje na danych:

1// Znajdźmy nazwy wszystkich dinozaurów roślinożernych, posortowane alfabetycznie
2const sortedHerbivoreNames = dinosaurs
3  .filter(dino => dino.diet === "herbivore")  // Najpierw filtrujemy
4  .map(dino => dino.name)                     // Potem transformujemy do tablicy nazw
5  .sort();                                   // Na końcu sortujemy alfabetycznie
6
7console.log("Roślinożercy (alfabetycznie):", sortedHerbivoreNames);
8// Wynik: ["Brachiosaurus", "Stegosaurus", "Triceratops"]
9
10// Obliczmy średni poziom agresji mięsożerców
11const averageCarnivoreAggression = dinosaurs
12  .filter(dino => dino.diet === "carnivore")   // Najpierw filtrujemy tylko mięsożerców
13  .reduce((sum, dino, index, array) => {       // Potem redukujemy do średniej
14    sum += dino.aggressionLevel;               // Dodajemy poziom agresji do sumy
15
16    // Jeśli to ostatni element, dzielimy przez liczbę elementów
17    if (index === array.length - 1) {
18      return sum / array.length;
19    }
20
21    return sum;                               // Zwracamy sumę częściową
22  }, 0);
23
24console.log("Średni poziom agresji mięsożerców:", averageCarnivoreAggression); // 9.5

Podsumowanie

Metody iteracyjne tablic w JavaScript są nieocenionym narzędziem przy pracy z kolekcjami danych. Każda ma swoją specjalizację:

  • forEach: gdy chcemy wykonać jakąś operację na każdym elemencie, bez tworzenia nowej tablicy
  • map: gdy chcemy przekształcić każdy element tablicy w coś innego
  • filter: gdy chcemy wybrać podgrupę elementów spełniających określone kryteria
  • reduce: gdy chcemy "zredukować" tablicę do pojedynczej wartości lub nowej struktury
  • find: gdy szukamy pierwszego elementu spełniającego określone kryterium
  • some/every: gdy chcemy sprawdzić, czy pewne/wszystkie elementy spełniają określone kryterium
  • sort: gdy chcemy uporządkować elementy tablicy

W naszym Parku Jurajskim te metody są niezbędne do efektywnego zarządzania danymi o dinozaurach, monitorowania bezpieczeństwa i podejmowania decyzji opartych na danych.

Przejdź do CodeWorlds