Operacje funkcyjne na kolekcjach
Opanuj popularne operacje funkcyjne, takie jak map, filter, fold i reduce, służące do transformacji danych.
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!
mapprzekształca każdy element.filterwybiera 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.
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
- Dogłębne poznanie niemutowalnych kolekcji
- Operacje funkcyjne na kolekcjach
- Option, Try i Either do obsługi błędów