Fold vs Reduce in Kotlin: Wann was verwenden? Vollständige Analyse

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Fold oder Reduce in Kotlin: Die ewige Frage der Anfänger

\n\n

Wenn Sie auch nur eine Woche in Kotlin programmieren, sind Sie mit ziemlicher Sicherheit bereits auf die Funktionen fold und reduce gestoßen. Auf den ersten Blick tun sie dasselbe: Sie durchlaufen eine Sammlung und akkumulieren ein Ergebnis. Aber der Teufel steckt, wie immer, im Detail. Die falsche Wahl kann zu Bugs, Ausnahmen oder einfach zu unschönem Code führen.

\n\n

In diesem Artikel analysieren wir den Unterschied zwischen fold und reduce in Kotlin, sehen uns Live-Beispiele aus echten Projekten an und merken uns ein für alle Mal, wann welche Funktion zu verwenden ist. Los geht's!

\n\n

Was sind fold und reduce? Grundlegendes Verständnis

\n\n

Beide Funktionen gehören zu den terminalen Operationen für Sammlungen. Sie nehmen alle Elemente und falten sie zu einem einzigen Wert zusammen. Stellen Sie sich vor, Sie haben einen Stapel Pfannkuchen und möchten einen großen Burger daraus machen. fold und reduce sind zwei verschiedene Falttechniken.

\n\n

Reduce: Der minimalistische Ansatz

\n\n

Die Funktion reduce verwendet das erste Element der Sammlung als Anfangswert des Akkumulators. Das bedeutet, dass sie einfach nicht mit einer leeren Sammlung arbeiten kann – es wird eine UnsupportedOperationException ausgelöst.

\n\n
val numbers = listOf(1, 2, 3, 4, 5)\nval sum = numbers.reduce { acc, i -> acc + i }\nprintln(sum) // 15
\n\n

Hier ist acc anfangs gleich 1 (das erste Element), dann wird 2 hinzugefügt, dann 3 und so weiter. Ganz einfach und elegant, aber es gibt einen Haken.

\n\n

Fold: Kontrolle über den Anfang

\n\n

fold erfordert im Gegensatz zu reduce, dass Sie explizit einen Anfangswert angeben. Das gibt Ihnen die volle Kontrolle und, was noch wichtiger ist, ermöglicht die Arbeit mit leeren Sammlungen.

\n\n
val numbers = listOf(1, 2, 3, 4, 5)\nval sum = numbers.fold(0) { acc, i -> acc + i }\nprintln(sum) // 15\n\nval emptyList = listOf<Int>()\nval emptySum = emptyList.fold(0) { acc, i -> acc + i }\nprintln(emptySum) // 0, kein Fehler!
\n\n

Sehen Sie den Unterschied? fold gibt den Anfangswert zurück, wenn die Sammlung leer ist. reduce würde in einer solchen Situation abstürzen.

\n\n

Wesentliche Unterschiede zwischen fold und reduce in Kotlin

\n\n

Lassen Sie uns das Wissen systematisieren. Hier ist eine Tabelle, die Ihnen hilft, sich schnell zu orientieren:

\n\n
    \n
  • Anfangswert: Bei fold geben Sie ihn selbst vor. Bei reduce ist es das erste Element der Sammlung.
  • \n
  • Ergebnistyp: Bei fold kann sich der Ergebnistyp vom Elementtyp unterscheiden (z.B. Sie addieren Int, erhalten aber einen String). Bei reduce stimmt der Ergebnistyp immer mit dem Elementtyp überein.
  • \n
  • Leere Sammlung: fold verarbeitet sie normal (gibt den Anfangswert zurück). reduce wirft eine Ausnahme.
  • \n
  • Leistung: Beide Funktionen arbeiten mit O(n). Der Leistungsunterschied ist vernachlässigbar.
  • \n
\n\n

Schauen wir uns das nun im Code an.

\n\n

Beispiel 1: Unterschiedliche Typen von Akkumulator und Elementen

\n\n

Angenommen, wir haben eine Liste von Zahlen und möchten einen String erhalten – ihre Summe in lesbarer Form. fold meistert das hervorragend, da sich der Typ des Akkumulators (String) vom Typ der Elemente (Int) unterscheidet.

\n\n
val numbers = listOf(1, 2, 3)\nval result = numbers.fold("Summe: ") { acc, i -> "$acc$i " }\nprintln(result) // "Summe: 1 2 3 "
\n\n

Versuchen Sie dasselbe mit reduce – der Compiler wird einen Fehler ausgeben, weil reduce erfordert, dass der Typ des Akkumulators mit dem Typ der Elemente übereinstimmt.

\n\n

Beispiel 2: Summenberechnung unter Berücksichtigung eines Anfangswerts

\n\n

Eine häufige Aufgabe: Berechnung des Gesamtbetrags von Bestellungen, wobei wir bereits einen Anfangsguthaben auf dem Konto haben.

\n\n
val orders = listOf(100, 250, 75)\nval initialBalance = 500\nval totalBalance = orders.fold(initialBa                

Blogs

Buchempfehlungen