foldLeft et foldRight
Réduisez des collections à une valeur.
foldLeft et foldRight 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.
Réduire une collection
La réduction condense une collection en une seule valeur en combinant répétitivement les éléments avec un accumulateur.
Le modèle de l'accumulateur que vous avez appris est exactement ce qu'abstrait fold. Au lieu d'écrire vous-même la fonction auxiliaire récursive, vous fournissez une valeur initiale et une fonction de combinaison.
Principes de base de foldLeft
foldLeft reçoit un accumulateur initial et une fonction (acc, element), puis parcourt la collection de gauche à droite.
À chaque étape, il remplace l'accumulateur par le résultat de la fonction.
val xs = List(1, 2, 3, 4)
val total = xs.foldLeft(0)((acc, x) => acc + x)
@main def run(): Unit =
println(total) // 10Comment foldLeft associe les éléments
foldLeft regroupe les opérations en partant de la gauche. Pour List(1, 2, 3) avec la valeur initiale z, il calcule f(f(f(z, 1), 2), 3).
L'accumulateur est l'argument de gauche ; il s'enrichit donc au fur et à mesure que vous avancez vers la droite dans la liste.
// List(1, 2, 3).foldLeft(0)(_ + _)
// = ((0 + 1) + 2) + 3
// = 6Principes de base de foldRight
foldRight combine également les éléments, mais commence par la droite.
Sa fonction reçoit (element, acc), avec l'élément à gauche et l'accumulateur à droite.
val xs = List(1, 2, 3, 4)
val total = xs.foldRight(0)((x, acc) => x + acc)
@main def run(): Unit =
println(total) // 10Comment foldRight associe les éléments
foldRight regroupe les opérations en partant de la droite. Pour List(1, 2, 3) avec la valeur initiale z, il calcule f(1, f(2, f(3, z))).
La valeur initiale se trouve tout à droite et la liste est combinée vers l'intérieur à partir de la fin.
// List(1, 2, 3).foldRight(0)(_ + _)
// = 1 + (2 + (3 + 0))
// = 6Quand la direction compte
Pour des opérations associatives et commutatives comme une somme ou un produit, les deux réductions donnent le même résultat.
Pour des opérations non commutatives comme la soustraction ou la construction d'une liste, la direction modifie le résultat. Choisissez-la délibérément.
val xs = List(1, 2, 3)
val l = xs.foldLeft(0)(_ - _) // ((0-1)-2)-3 = -6
val r = xs.foldRight(0)(_ - _) // 1-(2-(3-0)) = 2
@main def run(): Unit =
println((l, r)) // (-6, 2)Construire une liste
foldRight est le choix naturel pour reconstruire une liste dans l'ordre, car il travaille de la queue vers l'intérieur et que l'ajout au début conserve la position des éléments.
Il transforme chaque élément tout en préservant l'ordre.
val xs = List(1, 2, 3)
val doubled = xs.foldRight(List.empty[Int]) { (x, acc) =>
(x * 2) :: acc
}
@main def run(): Unit =
println(doubled) // List(2, 4, 6)foldLeft inverse l'ordre
Si vous construisez une liste avec foldLeft et que vous ajoutez les éléments au début, le résultat est inversé, car les éléments sont ajoutés par l'avant lorsque vous avancez vers la droite.
C'est parfois exactement ce que vous souhaitez.
val xs = List(1, 2, 3)
val rev = xs.foldLeft(List.empty[Int]) { (acc, x) =>
x :: acc
}
@main def run(): Unit =
println(rev) // List(3, 2, 1)Sécurité de la pile
foldLeft est récursif terminal et s'exécute comme une boucle ; il est donc sûr pour les collections gigantesques.
foldRight sur une List n'est pas récursif terminal et peut faire déborder la pile pour des listes très longues. Préférez foldLeft lorsque vous n'avez pas besoin de l'ordre de droite à gauche.
// Safe even for millions of elements:
val n = (1 to 1000000).foldLeft(0L)(_ + _)
// foldRight on a long List risks StackOverflowErrorModifier le type du résultat
Le type de l'accumulateur peut différer du type des éléments.
Ici, nous réduisons une liste d'entiers en une chaîne ; la valeur initiale est donc une chaîne vide et chaque étape ajoute du texte.
Le type de la réduction est déterminé par la valeur initiale.
val xs = List(1, 2, 3)
val s = xs.foldLeft("")((acc, x) => acc + x.toString)
@main def run(): Unit =
println(s) // "123"La réduction, outil polyvalent
De nombreuses opérations sur les listes sont des cas particuliers de fold : somme, produit, longueur, max, map, filtrage, inversion.
Reconnaître la réduction sous-jacente vous aide à écrire un code concis et déclaratif plutôt qu'une récursivité écrite manuellement.
val xs = List(4, 1, 7, 3)
val maxV = xs.foldLeft(Int.MinValue)(_ max _)
val len = xs.foldLeft(0)((acc, _) => acc + 1)
@main def run(): Unit =
println((maxV, len)) // (7, 4)Vérification rapide
Raisonnez sur la direction de la réduction et la position de la valeur initiale.
Récapitulatif
foldLeft parcourt la collection de gauche à droite avec l'accumulateur à gauche et calcule ((z op a) op b) op c. Il est récursif terminal et ne risque pas de faire déborder la pile.
foldRight parcourt la collection de droite à gauche avec la valeur initiale à droite et calcule a op (b op (c op z)). Il convient à la construction de listes qui préserve l'ordre, mais peut faire déborder la pile sur les listes longues.
La valeur initiale détermine le type du résultat ; les réductions peuvent donc transformer une collection en n'importe quelle valeur.
Questions Fréquemment Posées
La leçon « foldLeft et foldRight » est-elle gratuite ?
Oui — le texte complet de « foldLeft et foldRight » 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 « foldLeft et foldRight » ?
Réduisez des collections à une valeur. 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 « foldLeft et foldRight » ?
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
- Raisonner de façon récursive
- Schémas d’accumulation
- foldLeft et foldRight
- reduce et agrégation