Scala for Backend Engineering & Functional Programming · Lekcja

Operacje funkcyjne na kolekcjach

Opanuj popularne operacje funkcyjne, takie jak map, filter, fold i reduce, służące do transformacji danych.

Lekcja 2 z 311 kroki

Operacje funkcyjne na kolekcjach to bezpłatna lekcja Scala for Backend Engineering & Functional Programming na CoddyKit. To lekcja 2 z 3. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Scala for Backend Engineering & Functional Programming, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Scala for Backend Engineering & Functional Programming zawiera 3 lekcji w sumie.

Operacje funkcyjne: dlaczego ich używać?

Operacje funkcyjne na kolekcjach pomagają przekształcać i łączyć dane bez zmieniania oryginalnej kolekcji. Takie podejście promuje niemutowalność i ułatwia odczytywanie oraz testowanie kodu.

Omówimy kluczowe operacje, takie jak map, filter, reduce i fold.

Przekształcanie za pomocą `map`

Operacja map stosuje funkcję do każdego elementu kolekcji i zwraca nową kolekcję z przekształconymi wynikami. Oryginalna kolekcja pozostaje niezmieniona.

Spróbuj uruchomić ten przykład:

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 2, 3, 4)
    val doubled = numbers.map(n => n * 2)
    println(s"Original: $numbers")
    println(s"Doubled: $doubled")
  }
}

`map` z różnymi typami

map jest bardzo elastyczne! Można przekształcać elementy na zupełnie inny typ. W tym przykładzie konwertujemy liczby na napisy albo pobieramy długości napisów.

Zauważ, że wynikiem jest List[Int], mimo że dane wejściowe miały typ List[String].

object Main {
  def main(args: Array[String]): Unit = {
    val names = List("Alice", "Bob", "Charlie")
    val lengths = names.map(name => name.length)
    println(s"Names: $names")
    println(s"Lengths: $lengths")
  }
}

Wybieranie za pomocą `filter`

Operacja filter tworzy nową kolekcję zawierającą tylko elementy spełniające określony warunek (funkcję predykatową). Odrzuca elementy, które nie są potrzebne.

Znajdźmy liczby parzyste:

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 2, 3, 4, 5, 6)
    val evens = numbers.filter(n => n % 2 == 0)
    println(s"Original: $numbers")
    println(s"Evens: $evens")
  }
}

Więcej przykładów `filter`

Jako warunku filtrowania można użyć dowolnego wyrażenia logicznego. Przefiltrujmy listę słów, aby pozostawić tylko te, które mają więcej niż 4 znaki.

object Main {
  def main(args: Array[String]): Unit = {
    val words = List("apple", "cat", "banana", "dog", "elephant")
    val longWords = words.filter(w => w.length > 4)
    println(s"Words: $words")
    println(s"Long words: $longWords")
  }
}

Łączenie za pomocą `reduce`

Operacja reduce łączy wszystkie elementy kolekcji w pojedynczy wynik. Przyjmuje operację dwuargumentową (funkcję, która przyjmuje dwa argumenty i zwraca jeden) i stosuje ją kumulacyjnie.

W tym przykładzie sumujemy wszystkie elementy:

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 2, 3, 4)
    val sum = numbers.reduce((a, b) => a + b)
    println(s"Numbers: $numbers")
    println(s"Sum: $sum")
  }
}

`reduce` dla iloczynu i maksimum

reduce może wykonywać różne agregacje. Możemy obliczyć iloczyn liczb albo znaleźć największą wartość.

Uwaga: reduce zgłosi błąd dla pustej kolekcji.

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 5, 2, 8)
    val product = numbers.reduce((a, b) => a * b)
    val maxNum = numbers.reduce((a, b) => if (a > b) a else b)
    println(s"Numbers: $numbers")
    println(s"Product: $product")
    println(s"Max: $maxNum")
  }
}

`fold`: potęga wartości początkowej

fold działa podobnie do reduce, ale występuje tu ważna różnica: przyjmuje wartość początkową (nazywaną także „akumulatorem”). Dzięki temu jest bezpieczne dla pustych kolekcji i pozwala uzyskać wyniki różnych typów.

Dodajmy liczby, zaczynając od 10:

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 2, 3)
    // foldLeft(initialValue)(operation)
    val sumWithInitial = numbers.foldLeft(10)((acc, n) => acc + n)
    println(s"Numbers: $numbers")
    println(s"Sum (starting from 10): $sumWithInitial")
  }
}

Kierunek: `foldLeft` a `foldRight`

Scala udostępnia foldLeft i foldRight. Różnią się kolejnością przetwarzania elementów oraz sposobem przekazywania akumulatora.

  • foldLeft(initial)(op): przetwarza elementy od lewej do prawej.
  • foldRight(initial)(op): przetwarza elementy od prawej do lewej.

W przypadku operacji takich jak konkatenacja napisów kierunek ma znaczenie!

object Main {
  def main(args: Array[String]): Unit = {
    val chars = List('a', 'b', 'c')
    val leftFold = chars.foldLeft("")((acc, c) => acc + c)
    val rightFold = chars.foldRight("")((c, acc) => acc + c)
    println(s"Chars: $chars")
    println(s"foldLeft: $leftFold") // Output: abc
    println(s"foldRight: $rightFold") // Output: abc (due to string append order)

    // Example where order matters: (acc, char) => char + acc
    val rightFoldReversed = chars.foldRight("")((c, acc) => c + acc)
    println(s"foldRight (char + acc): $rightFoldReversed") // Output: abc

    // A common example where order matters is for operations like subtraction or division, but string concatenation also shows it.
  }
}

Sprawdzenie operacji funkcyjnych

Rozważ następujący fragment kodu Scala:

val data = List(10, 20, 30, 40)
val result1 = data.map(x => x / 10)
val result2 = data.filter(x => x > 25)
val result3 = data.reduce((a, b) => a + b)

Które z poniższych stwierdzeń dotyczących wyników są PRAWDZIWE?

Podsumowanie: siła operacji funkcyjnych

Opanowano najważniejsze operacje funkcyjne!

  • map przekształca każdy element.
  • filter wybiera elementy na podstawie warunku.
  • reduce łączy elementy w pojedynczy wynik (wymaga niepustej kolekcji).
  • fold łączy elementy z wartością początkową (jest bezpieczne dla pustych kolekcji).

Operacje te są kluczowe przy pisaniu zwięzłego, niemutowalnego i funkcjonalnego kodu Scala. Następnie omówimy niezawodne obsługiwanie błędów za pomocą Option, Try i Either.

Bezpłatny start

Ucz się Scala dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
39
Lekcje
143

Często zadawane pytania

Czy lekcja „Operacje funkcyjne na kolekcjach” jest bezpłatna?

Tak — pełny tekst „Operacje funkcyjne na kolekcjach” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Scala for Backend Engineering & Functional Programming, przejdź na CoddyKit PRO. Kurs Scala for Backend Engineering & Functional Programming zawiera 3 lekcji w sumie.

Co nauczysz się w „Operacje funkcyjne na kolekcjach”?

Opanuj popularne operacje funkcyjne, takie jak map, filter, fold i reduce, służące do transformacji danych. Ćwiczysz Scala for Backend Engineering & Functional Programming z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Scala for Backend Engineering & Functional Programming?

Nie wymagamy żadnego doświadczenia. Scala for Backend Engineering & Functional Programming w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 3.

Ile czasu zajmuje lekcja „Operacje funkcyjne na kolekcjach”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Scala for Backend Engineering & Functional Programming?

Tak. Każda lekcja Scala for Backend Engineering & Functional Programming zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Dogłębne poznanie niemutowalnych kolekcji
  2. Operacje funkcyjne na kolekcjach
  3. Option, Try i Either do obsługi błędów
← Powrót do Scala for Backend Engineering & Functional Programming