0Pricing
Scala for Backend Engineering & Functional Programming · درس

التصفية باستخدام if

حراس في comprehensions

التصفية باستخدام 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 دروس في المجموع.

بعض أجزاء هذا الدرس لم تُترجم بعد وتظهر باللغة الإنجليزية.

Guards in for-comprehensions

Inside a for-comprehension you can add an if condition called a guard. It keeps only the elements that satisfy the condition, just like filter.

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

Guards desugar to withFilter

A guard if cond is rewritten into a call to withFilter (a lazy variant of filter).

  • for (x <- xs if p(x)) yield x
  • becomes 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)
  }
}

Why withFilter, not filter

withFilter is lazy: it does not build an intermediate collection. The condition is applied only when the following map or flatMap runs, which saves memory and work.

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)
  }
}

Multiple guards

You can chain several guards. They combine like a logical AND: an element must satisfy all conditions to survive.

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)
  }
}

Guards with multiple generators

Guards can appear after any generator and filter that level of iteration. Place the guard right after the generator whose values it tests.

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)
  }
}

Combining a guard and a value binding

You can freely mix guards (if) with value bindings (=). Order matters: a binding defined before a guard can be used inside that guard.

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)
  }
}

Guards on String collections

Guards work with any predicate, not just numeric ones. Here we filter words by length.

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)
  }
}

Filtering Options

For an Option, a guard that fails turns the result into None. This makes for-comprehensions a clean way to validate optional values.

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)
  }
}

Guard position changes meaning

A guard only sees values bound above it. Putting it before a generator that it needs will not compile. Always place a guard after the relevant generator.

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)
  }
}

Guards versus a final filter

You could filter the result after the comprehension, but a guard filters during iteration. With multiple generators, guards can prune branches early, doing less total work.

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

Readable validation pipelines

Stacking guards reads like a checklist of conditions. This is one of the most idiomatic uses of for-comprehensions in real Scala code.

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)
  }
}

Quick Check

What method does a guard (if) in a for-comprehension desugar into?

Recap

You learned about guards in for-comprehensions:

  • if cond filters elements during iteration
  • Guards desugar to withFilter (lazy filtering)
  • Multiple guards combine like logical AND
  • A guard only sees values bound above it
  • Guards mix freely with generators and = bindings

الأسئلة الشائعة

هل درس «التصفية باستخدام if» مجاني؟

نعم — نص درس «التصفية باستخدام if» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Scala for Backend Engineering & Functional Programming، انتقل إلى CoddyKit PRO. تتضمن دورة Scala for Backend Engineering & Functional Programming 4 دروس في المجموع.

ماذا ستتعلم في «التصفية باستخدام if»؟

حراس في comprehensions تتمرن على 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 يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. إزالة السكر النحوي من for
  2. التصفية باستخدام if
  3. مولدات متعددة
  4. الاستخدام مع Option وFuture
← العودة إلى Scala for Backend Engineering & Functional Programming