reduce und aggregate
Weitere Möglichkeiten, Elemente zu kombinieren.
reduce und aggregate ist eine kostenlose Scala for Backend Engineering & Functional Programming-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Scala for Backend Engineering & Functional Programming-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Scala for Backend Engineering & Functional Programming-Kurs umfasst insgesamt 4 Lektionen.
Von Fold zu Reduce
Manchmal möchten Sie Elemente kombinieren, ohne einen separaten Startwert anzugeben.
reduce verwendet das erste Element als Startakkumulator und kombiniert die übrigen Elemente damit.
reduce ist eine schlankere Variante von fold für Fälle, in denen Elementtyp und Ergebnistyp identisch sind.
Grundlagen von reduce
reduce übernimmt eine binäre Funktion (a, b) und faltet sie ohne expliziten Anfangswert über die Collection.
Bei einer Summe addiert reduce einfach alle Elemente.
val xs = List(1, 2, 3, 4)
val total = xs.reduce((a, b) => a + b)
@main def run(): Unit =
println(total) // 10Die Falle der leeren Collection
Da reduce keinen Startwert besitzt, löst der Aufruf auf einer leeren Collection eine UnsupportedOperationException aus.
fold und foldLeft sind für leere Collections sicher, weil sie auf den angegebenen Startwert zurückgreifen.
Verwenden Sie reduce nur, wenn Sie wissen, dass die Collection nicht leer ist.
// List.empty[Int].reduce(_ + _)
// throws UnsupportedOperationException
List.empty[Int].foldLeft(0)(_ + _) // safe, returns 0reduceOption für mehr Sicherheit
reduceOption gibt ein Option zurück und liefert bei einer leeren Collection None, statt eine Exception auszulösen.
Das ist die sichere Möglichkeit, reduce zu verwenden, wenn die Collection leer sein kann.
val xs = List(5, 9, 2)
val maybeMax = xs.reduceOption(_ max _)
@main def run(): Unit =
println(maybeMax) // Some(9)reduceLeft und reduceRight
Wie fold hat auch reduce Varianten mit einer bestimmten Richtung.
reduceLeft kombiniert von links nach rechts, reduceRight von rechts nach links. Plain reduce garantiert bei parallelen Collections keine Reihenfolge. Verwenden Sie daher die explizite Variante, wenn die Richtung wichtig ist.
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)Warum aggregate existiert
fold und reduce setzen voraus, dass Akkumulator- und Elementtyp auf einfache Weise zusammenpassen.
aggregate ist der allgemeinste Fold: Der Akkumulator darf einen anderen Typ haben UND Sie geben Scala vor, wie partielle Akkumulatoren zusammengeführt werden. Das ist für die parallele Verarbeitung wichtig.
Signatur von aggregate
aggregate erhält einen Startwert, ein seqop, das ein Element in den Akkumulator einarbeitet, und ein combop, das zwei Akkumulatoren zusammenführt.
Bei einer sequenziellen Collection wird combop selten verwendet; bei einer parallelen Collection verbindet es die Ergebnisse der einzelnen Teilbereiche.
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) // 10aggregate mit einem anderen Typ
Hier fasst aggregate eine Liste von Wörtern zu einer einzigen Gesamtlänge vom Typ Int zusammen.
seqop addiert die Länge jedes Wortes, während combop zwei Teilsummen addiert.
Der Akkumulatortyp (Int) unterscheidet sich vom Elementtyp (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) // 10Parallele Aggregation
Die eigentliche Stärke von aggregate zeigt sich bei parallelen Collections.
Jeder Thread verarbeitet seinen eigenen Teilbereich mit seqop. Anschließend werden die Teilbereiche mit combop zusammengeführt. Durch diese beiden Funktionen kann Scala die Arbeit sicher aufteilen und wieder zusammenführen.
// Conceptual: par splits the work
// val n = data.par.aggregate(0)(_ + _.length, _ + _)
// seqop runs per chunk, combop merges chunk resultsDas richtige Werkzeug auswählen
Verwenden Sie reduce oder reduceOption, wenn der Ergebnistyp dem Elementtyp entspricht und die Kombination assoziativ ist.
Verwenden Sie foldLeft, wenn Sie sequenziell einen Startwert oder einen anderen Ergebnistyp benötigen.
Verwenden Sie aggregate, wenn sich Akkumulator- und Elementtyp unterscheiden und Sie eine für parallele Verarbeitung geeignete Zusammenführung benötigen.
// reduce: same type, non-empty, associative
// foldLeft: seed + different type, sequential
// aggregate: different type + parallel mergeIn einem Durchlauf kombinieren
Mit aggregate können Sie mehrere Dinge gleichzeitig berechnen, indem Sie in einem Tupel akkumulieren.
Hier erhalten Sie Summe und Anzahl in einem einzigen Durchlauf und führen die Tupel in combop zusammen.
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)Schnelltest
Entscheiden Sie, welche Operation für eine möglicherweise leere Liste am sichersten ist.
Zusammenfassung
reduce kombiniert Elemente ohne Startwert und verwendet das erste Element als Anfang. Bei einer leeren Collection löst es eine Exception aus, während reduceOption stattdessen None zurückgibt.
aggregate ist der allgemeinste Fold: ein Startwert, ein seqop zum Einarbeiten von Elementen und ein combop zum Zusammenführen partieller Akkumulatoren für parallele Verarbeitung.
Wählen Sie reduce für assoziative Kombinationen desselben Typs, foldLeft für sequenzielle Folds mit Startwert und aggregate, wenn sich die Typen unterscheiden oder Sie parallel arbeiten.
Häufig gestellte Fragen
Ist die Lektion „reduce und aggregate“ kostenlos?
Ja — der vollständige Text von „reduce und aggregate“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Scala for Backend Engineering & Functional Programming-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Scala for Backend Engineering & Functional Programming-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „reduce und aggregate“?
Weitere Möglichkeiten, Elemente zu kombinieren. Du übst Scala for Backend Engineering & Functional Programming mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Scala for Backend Engineering & Functional Programming zu starten?
Keine Vorkenntnisse erforderlich. Scala for Backend Engineering & Functional Programming auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.
Wie lange dauert die Lektion „reduce und aggregate“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Scala for Backend Engineering & Functional Programming-Lektion Code schreiben und ausführen?
Ja. Jede Scala for Backend Engineering & Functional Programming-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Rekursiv denken
- Akkumulator-Muster
- foldLeft und foldRight
- reduce und aggregate