Fold vs Reduce en Kotlin : quand utiliser quoi ? Analyse complète

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Fold ou Reduce en Kotlin : la question éternelle des débutants

\n\n

Si vous programmez en Kotlin depuis au moins une semaine, vous avez sûrement déjà rencontré les fonctions fold et reduce. À première vue, elles font la même chose : parcourir une collection et accumuler un résultat. Mais le diable, comme toujours, se cache dans les détails. Un mauvais choix peut entraîner des bugs, des exceptions ou simplement un code peu élégant.

\n\n

Dans cet article, nous allons analyser la différence entre fold et reduce en Kotlin, observer des exemples concrets issus de projets réels et mémoriser une fois pour toutes quelle fonction utiliser. C'est parti !

\n\n

Que sont fold et reduce ? Compréhension de base

\n\n

Les deux fonctions sont des opérations terminales pour les collections. Elles prennent tous les éléments et les réduisent à une seule valeur. Imaginez que vous ayez une pile de crêpes et que vous vouliez obtenir un grand burger. fold et reduce sont deux techniques différentes pour les empiler.

\n\n

Reduce : une approche minimaliste

\n\n

La fonction reduce utilise le premier élément de la collection comme valeur initiale de l'accumulateur. Cela signifie qu'elle ne peut tout simplement pas fonctionner avec une collection vide — elle lèvera une UnsupportedOperationException.

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

Ici, acc est initialement égal à 1 (le premier élément), puis on y ajoute 2, puis 3, et ainsi de suite. Simple et élégant, mais il y a un détail.

\n\n

Fold : le contrôle du début

\n\n

fold, contrairement à reduce, nécessite de spécifier explicitement une valeur initiale. Cela vous donne un contrôle total et, plus important encore, permet de travailler avec des collections vides.

\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, aucune erreur !
\n\n

Vous voyez la différence ? fold renvoie la valeur initiale si la collection est vide. reduce échouerait dans une telle situation.

\n\n

Différences clés entre fold et reduce en Kotlin

\n\n

Organisons ces connaissances. Voici un tableau qui vous aidera à vous repérer rapidement :

\n\n
    \n
  • Valeur initiale : Dans fold, vous la définissez vous-même. Dans reduce, c'est le premier élément de la collection.
  • \n
  • Type du résultat : Dans fold, le type du résultat peut être différent du type des éléments (par exemple, additionner des Int pour obtenir une String). Dans reduce, le type du résultat correspond toujours au type des éléments.
  • \n
  • Collection vide : fold la gère correctement (renvoie la valeur initiale). reduce lève une exception.
  • \n
  • Performance : Les deux fonctions s'exécutent en O(n). La différence de performance est négligeable.
  • \n
\n\n

Voyons maintenant cela dans le code.

\n\n

Exemple 1 : Types différents de l'accumulateur et des éléments

\n\n

Supposons que nous ayons une liste de nombres et que nous voulions obtenir une chaîne de caractères — leur somme sous une forme lisible. fold s'en sort parfaitement, car le type de l'accumulateur (String) est différent du type des éléments (Int).

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

Essayez de faire la même chose avec reduce — le compilateur générera une erreur, car reduce exige que le type de l'accumulateur corresponde au type des éléments.

\n\n

Exemple 2 : Calcul de la somme avec une valeur initiale

\n\n

Une tâche courante : calculer le montant total des commandes, mais nous avons déjà un solde initial sur le compte.

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

Blogs

Book Recommendations