Фильтрация с помощью if
Защитные условия в comprehension
«Фильтрация с помощью if» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Условия в циклах for с вычислением результата
Внутри цикла for с вычислением результата можно добавить условие if, называемое ограничением. Оно оставляет только элементы, удовлетворяющие условию, подобно filter.
object Main {
def main(args: Array[String]): Unit = {
val evens = for (x <- 1 to 10 if x % 2 == 0) yield x
println(evens)
}
}Условия преобразуются в withFilter
Условие if cond преобразуется в вызов withFilter (ленивый вариант filter).
for (x <- xs if p(x)) yield x- превращается в
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)
}
}Почему withFilter, а не filter
withFilter работает лениво: он не создаёт промежуточную коллекцию. Условие применяется только при выполнении следующего map или flatMap, что экономит память и вычислительные ресурсы.
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)
}
}Несколько условий
Можно объединять несколько условий в цепочку. Они объединяются как логическое AND: элемент должен удовлетворять всем условиям, чтобы остаться в результате.
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)
}
}Условия с несколькими генераторами
Условия могут стоять после любого генератора и фильтровать соответствующий уровень итерации. Размещайте условие сразу после генератора, значения которого оно проверяет.
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)
}
}Сочетание условия и связывания значения
Условия (if) можно свободно сочетать со связываниями значений (=). Порядок имеет значение: связывание, определённое перед условием, можно использовать внутри этого условия.
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)
}
}Условия для коллекций String
Условия работают с любым предикатом, а не только с числовыми. Здесь мы фильтруем слова по длине.
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)
}
}Фильтрация Options
Для Option невыполненное условие превращает результат в None. Благодаря этому циклы for с вычислением результата удобно использовать для проверки необязательных значений.
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)
}
}Положение условия меняет смысл
Защитное условие видит только значения, связанные выше него. Если поставить его перед генератором, значения которого оно требует, код не скомпилируется. Всегда размещайте защитное условие после соответствующего генератора.
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)
}
}Защитные условия и итоговый фильтр
Можно отфильтровать результат после for-выражения, но защитное условие фильтрует во время итерации. При наличии нескольких генераторов защитные условия могут заранее отсекать ветви, уменьшая общий объём работы.
object Main {
def main(args: Array[String]): Unit = {
val withGuard = for {
x <- 1 to 100
if x % 25 == 0
} yield x
println(withGuard)
}
}Удобные для чтения конвейеры проверки
Последовательность защитных условий читается как список проверяемых условий. Это один из самых идиоматичных способов использования for-выражений в реальном коде на Scala.
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)
}
}Быстрая проверка
В какой метод преобразуется защитное условие (if) в for-выражении?
Итоги
Вы узнали о защитных условиях в for-выражениях:
if condфильтрует элементы во время итерации- Защитные условия преобразуются в
withFilter(ленивая фильтрация) - Несколько защитных условий объединяются как логическое AND
- Защитное условие видит только значения, связанные выше него
- Защитные условия можно свободно сочетать с генераторами и привязками
=
Изучай Scala с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 39
- Уроки
- 143
Часто задаваемые вопросы
Урок «Фильтрация с помощью if» бесплатный?
Да — полный текст урока «Фильтрация с помощью if» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Чему я научусь в уроке «Фильтрация с помощью if»?
Защитные условия в comprehension Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?
Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Фильтрация с помощью if»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?
Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Десахаризация for
- Фильтрация с помощью if
- Несколько генераторов
- Использование Option и Future