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

reduce et agrégation

Découvrez d’autres façons de combiner les éléments.

reduce et agrégation est une leçon Scala for Backend Engineering & Functional Programming gratuite sur CoddyKit. Ceci est la leçon 4 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.

De fold à reduce

Parfois, vous souhaitez combiner les éléments sans fournir une valeur initiale distincte.

reduce utilise le premier élément comme accumulateur initial et y combine les autres.

C'est une variante plus légère de fold pour les cas où le type des éléments et celui du résultat sont identiques.

Principes de base de reduce

reduce reçoit une fonction binaire (a, b) et l'applique à toute la collection, sans valeur initiale explicite.

Pour une somme, il additionne simplement tous les éléments.

val xs = List(1, 2, 3, 4)
val total = xs.reduce((a, b) => a + b)

@main def run(): Unit =
  println(total)  // 10

Le piège de la collection vide

Comme reduce n'a pas de valeur initiale, l'appeler sur une collection vide lève une UnsupportedOperationException.

fold et foldLeft sont sûrs sur les collections vides, car ils utilisent la valeur initiale fournie.

N'utilisez reduce que lorsque vous savez que la collection n'est pas vide.

// List.empty[Int].reduce(_ + _)
// throws UnsupportedOperationException

List.empty[Int].foldLeft(0)(_ + _)  // safe, returns 0

reduceOption pour plus de sécurité

reduceOption renvoie un Option et donne None pour une collection vide au lieu de lever une exception.

C'est la manière sûre d'effectuer une réduction lorsque la collection peut être vide.

val xs = List(5, 9, 2)
val maybeMax = xs.reduceOption(_ max _)

@main def run(): Unit =
  println(maybeMax)  // Some(9)

reduceLeft et reduceRight

Comme fold, reduce possède des variantes directionnelles.

reduceLeft combine de gauche à droite, et reduceRight de droite à gauche. La version simple de reduce ne garantit pas l'ordre pour les collections parallèles ; utilisez donc la variante explicite lorsque la direction compte.

val xs = List(1, 2, 3)
val l = xs.reduceLeft(_ - _)   // (1-2)-3 = -4
val r = xs.reduceRight(_ - _)  // 1-(2-3) = 2

@main def run(): Unit =
  println((l, r))  // (-4, 2)

Pourquoi aggregate existe

fold et reduce exigent que les types de l'accumulateur et des éléments soient liés de manière simple.

aggregate est la réduction la plus générale : il permet à l'accumulateur d'avoir un type différent ET indique à Scala comment fusionner les accumulateurs partiels, ce qui est important pour le traitement parallèle.

Signature de aggregate

aggregate reçoit une valeur initiale, un seqop qui intègre un élément à l'accumulateur, et un combop qui fusionne deux accumulateurs.

Sur une collection séquentielle, combop est rarement utilisé ; sur une collection parallèle, il réunit les résultats de chaque bloc.

val xs = List(1, 2, 3, 4)
val sum = xs.aggregate(0)(
  (acc, x) => acc + x,   // seqop
  (a, b)   => a + b      // combop
)

@main def run(): Unit = println(sum)  // 10

aggregate avec un type différent

Ici, aggregate réduit une liste de mots en un total de longueur unique de type Int.

seqop ajoute la longueur de chaque mot, tandis que combop additionne deux totaux partiels.

Le type de l'accumulateur (Int) diffère du type des éléments (String).

val words = List("hi", "there", "you")
val chars = words.aggregate(0)(
  (acc, w) => acc + w.length,
  (a, b)   => a + b
)

@main def run(): Unit = println(chars)  // 10

Agrégation parallèle

La véritable puissance de aggregate apparaît avec les collections parallèles.

Chaque thread réduit son propre bloc avec seqop, puis les blocs sont fusionnés avec combop. Ces deux fonctions permettent à Scala de répartir puis de réunir le travail en toute sécurité.

// Conceptual: par splits the work
// val n = data.par.aggregate(0)(_ + _.length, _ + _)
// seqop runs per chunk, combop merges chunk results

Choisir le bon outil

Utilisez reduce ou reduceOption lorsque le type du résultat est égal à celui des éléments et que la combinaison est associative.

Utilisez foldLeft lorsque vous avez besoin d'une valeur initiale ou d'un type de résultat différent dans un traitement séquentiel.

Utilisez aggregate lorsque les types de l'accumulateur et des éléments diffèrent et que vous souhaitez une fusion adaptée au traitement parallèle.

// reduce:    same type, non-empty, associative
// foldLeft:  seed + different type, sequential
// aggregate: different type + parallel merge

Combiner en un seul parcours

aggregate peut calculer plusieurs résultats à la fois en accumulant dans un tuple.

Ici, nous obtenons à la fois la somme et le compte en un seul parcours, en fusionnant les tuples dans combop.

val xs = List(2, 4, 6, 8)
val (s, c) = xs.aggregate((0, 0))(
  (acc, x) => (acc._1 + x, acc._2 + 1),
  (a, b)   => (a._1 + b._1, a._2 + b._2)
)

@main def run(): Unit = println((s, c))  // (20, 4)

Vérification rapide

Déterminez quelle opération est la plus sûre pour une liste potentiellement vide.

Récapitulatif

reduce combine les éléments sans valeur initiale, en utilisant le premier élément comme point de départ ; il lève une exception sur une collection vide, tandis que reduceOption renvoie None.

aggregate est la réduction la plus générale : une valeur initiale, un seqop pour réduire les éléments et un combop pour fusionner les accumulateurs partiels lors d'un traitement parallèle.

Choisissez reduce pour une combinaison associative de valeurs du même type, foldLeft pour une réduction séquentielle avec valeur initiale, et aggregate lorsque les types diffèrent ou que vous travaillez en parallèle.

Questions Fréquemment Posées

La leçon « reduce et agrégation » est-elle gratuite ?

Oui — le texte complet de « reduce et agrégation » 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 « reduce et agrégation » ?

Découvrez d’autres façons de combiner les éléments. 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 4 sur 4.

Combien de temps prend la leçon « reduce et agrégation » ?

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. Raisonner de façon récursive
  2. Schémas d’accumulation
  3. foldLeft et foldRight
  4. reduce et agrégation
← Retour à Scala for Backend Engineering & Functional Programming