Scala for Backend Engineering & Functional Programming · Lekcja

Filtrowanie za pomocą if

Strażnicy w comprehensions

Lekcja 2 z 413 kroki

Filtrowanie za pomocą if to bezpłatna lekcja Scala for Backend Engineering & Functional Programming na CoddyKit. To lekcja 2 z 4. 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 4 lekcji w sumie.

Warunki w wyrażeniach for-comprehension

Wewnątrz wyrażenia for-comprehension można dodać warunek if nazywany guard. Zachowuje on tylko elementy spełniające warunek, podobnie jak filter.

object Main {
  def main(args: Array[String]): Unit = {
    val evens = for (x <- 1 to 10 if x % 2 == 0) yield x
    println(evens)
  }
}

Warunki są przekształcane na withFilter

Warunek if cond jest przepisywany na wywołanie withFilter (leniwy wariant filter).

  • for (x <- xs if p(x)) yield x
  • staje się xs.withFilter(p).map(x => x)
object Main {
  def main(args: Array[String]): Unit = {
    val sugar = for (x <- List(1, 2, 3, 4) if x > 2) yield x
    val desugared = List(1, 2, 3, 4).withFilter(_ > 2).map(x => x)
    println(sugar == desugared)
  }
}

Dlaczego withFilter, a nie filter

withFilter jest leniwy: nie tworzy kolekcji pośredniej. Warunek jest stosowany dopiero podczas wykonywania kolejnego map lub flatMap, co oszczędza pamięć i czas obliczeń.

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4, 5, 6)
    val result = for (n <- nums if n % 3 == 0) yield n * 100
    println(result)
  }
}

Wiele warunków

Można łączyć kilka warunków. Łączą się one jak logiczna koniunkcja: element musi spełniać wszystkie warunki, aby pozostać w wyniku.

object Main {
  def main(args: Array[String]): Unit = {
    val result = for {
      x <- 1 to 20
      if x % 2 == 0
      if x % 3 == 0
    } yield x
    println(result)
  }
}

Warunki z wieloma generatorami

Warunki mogą występować po dowolnym generatorze i filtrować dany poziom iteracji. Proszę umieścić warunek bezpośrednio za generatorem, którego wartości sprawdza.

object Main {
  def main(args: Array[String]): Unit = {
    val coprimeSums = for {
      x <- 1 to 3
      y <- 1 to 3
      if x != y
    } yield (x, y)
    println(coprimeSums)
  }
}

Łączenie warunku z wiązaniem wartości

Można swobodnie łączyć warunki (if) z wiązaniami wartości (=). Kolejność ma znaczenie: wiązanie zdefiniowane przed warunkiem może być używane wewnątrz tego warunku.

object Main {
  def main(args: Array[String]): Unit = {
    val result = for {
      x <- 1 to 6
      square = x * x
      if square > 10
    } yield square
    println(result)
  }
}

Warunki dla kolekcji String

Warunki działają z dowolnym predykatem, nie tylko z predykatami numerycznymi. W tym przypadku filtrujemy słowa według długości.

object Main {
  def main(args: Array[String]): Unit = {
    val words = List("scala", "go", "java", "rust", "c")
    val longWords = for (w <- words if w.length >= 4) yield w.toUpperCase
    println(longWords)
  }
}

Filtrowanie opcji

W przypadku Option niespełniony warunek zmienia wynik na None. Dzięki temu wyrażenia for-comprehension są czytelnym sposobem walidowania opcjonalnych wartości.

object Main {
  def main(args: Array[String]): Unit = {
    val ok  = for (x <- Some(8) if x > 5) yield x
    val bad = for (x <- Some(3) if x > 5) yield x
    println(ok)
    println(bad)
  }
}

Położenie warunku zmienia znaczenie

Strażnik widzi tylko wartości powiązane powyżej niego. Umieszczenie go przed generatorem, którego potrzebuje, spowoduje błąd kompilacji. Strażnik należy zawsze umieszczać za odpowiednim generatorem.

object Main {
  def main(args: Array[String]): Unit = {
    val result = for {
      x <- 1 to 3
      y <- 1 to 3
      if x + y == 4
    } yield s"$x + $y = ${x + y}"
    result.foreach(println)
  }
}

Strażniki a końcowy filtr

Można odfiltrować wynik po wykonaniu comprehension, ale strażnik filtruje w trakcie iteracji. Przy wielu generatorach strażniki mogą wcześnie odrzucać gałęzie, zmniejszając łączną ilość pracy.

object Main {
  def main(args: Array[String]): Unit = {
    val withGuard = for {
      x <- 1 to 100
      if x % 25 == 0
    } yield x
    println(withGuard)
  }
}

Czytelne potoki walidacji

Łączenie strażników przypomina listę kontrolną warunków. To jedno z najbardziej idiomatycznych zastosowań for-comprehensions w rzeczywistym kodzie Scali.

object Main {
  def main(args: Array[String]): Unit = {
    val valid = for {
      n <- List(4, 7, 12, 15, 20)
      if n > 5
      if n < 18
      if n % 2 == 0
    } yield n
    println(valid)
  }
}

Szybkie sprawdzenie

Do wywołania jakiej metody rozwija się strażnik (if) w for-comprehension?

Podsumowanie

Poznałeś(-aś) strażniki w for-comprehensions:

  • if cond filtruje elementy podczas iteracji
  • Strażniki rozwijają się do withFilter (leniwe filtrowanie)
  • Wiele strażników łączy się jak logiczne AND
  • Strażnik widzi tylko wartości powiązane powyżej niego
  • Strażniki można swobodnie łączyć z generatorami i wiązaniami =
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 „Filtrowanie za pomocą if” jest bezpłatna?

Tak — pełny tekst „Filtrowanie za pomocą if” 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 4 lekcji w sumie.

Co nauczysz się w „Filtrowanie za pomocą if”?

Strażnicy w comprehensions Ć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 4.

Ile czasu zajmuje lekcja „Filtrowanie za pomocą if”?

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. Desugaring for
  2. Filtrowanie za pomocą if
  3. Wiele generatorów
  4. Używanie Option i Future
← Powrót do Scala for Backend Engineering & Functional Programming