0Pricing
Scala for Backend Engineering & Functional Programming · Leçon

Générateurs multiples

Itération imbriquée

Générateurs multiples est une leçon Scala for Backend Engineering & Functional Programming gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Scala for Backend Engineering & Functional Programming, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.

Certaines parties de cette leçon n'ont pas encore été traduites et s'affichent en anglais.

Nested iteration made flat

A for-comprehension can have several generators. Each one is a <- line that iterates over a collection. Together they produce every combination, a kind of nested loop written flatly.

object Main {
  def main(args: Array[String]): Unit = {
    val pairs = for {
      x <- List(1, 2)
      y <- List('a', 'b')
    } yield (x, y)
    println(pairs)
  }
}

It is a cartesian product

Two generators of sizes m and n produce m × n results, the full cartesian product. The first generator is the outer loop, the second the inner loop.

object Main {
  def main(args: Array[String]): Unit = {
    val grid = for {
      row <- 1 to 3
      col <- 1 to 3
    } yield s"r$row-c$col"
    println(grid.mkString(", "))
  }
}

Inner generator can depend on outer

A later generator can use values bound by earlier ones. This is impossible with a plain cartesian product and is one reason for-comprehensions are so flexible.

object Main {
  def main(args: Array[String]): Unit = {
    val upperTriangle = for {
      i <- 1 to 4
      j <- i to 4
    } yield (i, j)
    println(upperTriangle)
  }
}

Three or more generators

You can stack as many generators as you like. With three generators you get a triple-nested loop, producing tuples or computed values.

object Main {
  def main(args: Array[String]): Unit = {
    val triples = for {
      a <- 1 to 2
      b <- 1 to 2
      c <- 1 to 2
    } yield (a, b, c)
    println(triples.size + " combinations")
    triples.foreach(println)
  }
}

The classic Pythagorean example

A famous use: find Pythagorean triples. We iterate three numbers and keep only those where a*a + b*b == c*c, combining multiple generators with a guard.

object Main {
  def main(args: Array[String]): Unit = {
    val triples = for {
      a <- 1 to 20
      b <- a to 20
      c <- b to 20
      if a * a + b * b == c * c
    } yield (a, b, c)
    triples.foreach(println)
  }
}

How it desugars

Multiple generators become nested flatMap calls with a final map:

  • xs.flatMap(x => ys.flatMap(y => zs.map(z => ...)))

Each extra generator adds one more nested level.

object Main {
  def main(args: Array[String]): Unit = {
    val sugar = for {
      x <- List(1, 2)
      y <- List(3, 4)
    } yield x * y
    val desugared = List(1, 2).flatMap(x => List(3, 4).map(y => x * y))
    println(sugar == desugared)
  }
}

Mixing generators and guards

You can interleave generators and guards freely. A guard placed between two generators prunes outer values before the inner loop even runs.

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

Flattening nested collections

When you have a collection of collections, two generators flatten it naturally: the first iterates the outer, the second iterates each inner.

object Main {
  def main(args: Array[String]): Unit = {
    val matrix = List(List(1, 2), List(3, 4), List(5, 6))
    val flat = for {
      row <- matrix
      value <- row
    } yield value
    println(flat)
  }
}

Building a string grid

Multiple generators are great for generating structured output, like coordinates or a multiplication table.

object Main {
  def main(args: Array[String]): Unit = {
    val table = for {
      i <- 1 to 3
      j <- 1 to 3
    } yield s"$i*$j=${i * j}"
    println(table.grouped(3).map(_.mkString("  ")).mkString("\n"))
  }
}

Combining different collection sizes

Generators need not be the same length. Each combination of one element from each is produced.

object Main {
  def main(args: Array[String]): Unit = {
    val sizes = List("S", "M", "L")
    val colors = List("red", "blue")
    val products = for {
      s <- sizes
      c <- colors
    } yield s"$c-$s"
    println(products)
  }
}

Order affects the output sequence

Swapping generator order keeps the same set of combinations but changes their order, because the last generator varies fastest.

object Main {
  def main(args: Array[String]): Unit = {
    val ab = for { x <- List(1, 2); y <- List(9, 8) } yield (x, y)
    val ba = for { y <- List(9, 8); x <- List(1, 2) } yield (x, y)
    println(ab)
    println(ba)
  }
}

Quick Check

How many tuples does for { x <- List(1,2,3); y <- List('a','b') } yield (x, y) produce?

Recap

You learned about multiple generators:

  • Each <- line adds a level of nested iteration
  • Together they produce the cartesian product
  • Inner generators can depend on outer bound values
  • They desugar to nested flatMap + a final map
  • Generator order changes the result ordering

Questions Fréquemment Posées

La leçon « Générateurs multiples » est-elle gratuite ?

Oui — le texte complet de « Générateurs multiples » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Scala for Backend Engineering & Functional Programming, passe à CoddyKit PRO. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Générateurs multiples » ?

Itération imbriquée Tu pratiques Scala for Backend Engineering & Functional Programming avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Scala for Backend Engineering & Functional Programming ?

Aucune expérience préalable n'est requise. Scala for Backend Engineering & Functional Programming sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Générateurs multiples » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Scala for Backend Engineering & Functional Programming ?

Oui. Chaque leçon Scala for Backend Engineering & Functional Programming inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Désucrage de for
  2. Filtrer avec if
  3. Générateurs multiples
  4. Utiliser Option et Future
← Retour à Scala for Backend Engineering & Functional Programming