213 votes

différence entre foldLeft et reduceLeft en Scala

J’ai appris la différence fondamentale entre foldLeft et reduceLeft

foldLeft :

  • la valeur initiale doit être passé

reduceLeft :

  • prend le premier élément de la collection comme valeur initiale
  • lève l’exception si la collection est vide

y a-t-il une autre différence ?

aucune raison particulière d’avoir deux méthodes dotés de fonctionnalités similaires ?

324voto

agilesteel Points 8330

Peu de choses à mentionner ici, avant de donner la réponse exacte:

  • Votre question n'a rien à voir avec left, c'est plutôt à propos de la différence entre la réduction et le pliage
  • La différence n'est pas la mise en œuvre à tous, il suffit de regarder les signatures.
  • La question n'a rien à voir avec Scala en particulier, c'est plutôt sur les deux concepts de la programmation fonctionnelle.

Pour revenir à ta question:

Ici est la signature d' foldLeft (il pourrait aussi avoir été foldRight pour le point, je vais faire):

def foldLeft [B] (z: B)(f: (B, A) => B): B

Et voici la signature de l' reduceLeft (à nouveau la direction n'a pas d'importance ici)

def reduceLeft [B >: A] (f: (B, A) => B): B

Ces deux sont très similaires et ainsi provoqué la confusion. reduceLeft est un cas spécial de l' foldLeft (qui signifie que vous parfois peut exprimer la même chose en utilisant l'un ou l'autre).

Lorsque vous appelez reduceLeft - dire sur un List[Int] il va littéralement réduire l'ensemble de la liste d'entiers en une seule valeur, qui va être de type Int (ou un supertype de Int, par conséquent [B >: A]).

Lorsque vous appelez foldLeft - dire sur un List[Int] il va se plier à l'ensemble de la liste (imagerie rouler un morceau de papier) en une seule valeur, mais cette valeur ne doit pas être liés, même à l' Int (d'où l' [B]).

Voici un exemple:

def listWithSum(numbers: List[Int]) = numbers.foldLeft((List[Int](), 0)) {
   (resultingTuple, currentInteger) =>
      (currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)
}

Cette méthode prend un List[Int] et renvoie un Tuple2[List[Int], Int] ou (List[Int] -> Int). Il calcule la somme et renvoie un tuple avec une liste d'entiers et de la somme. Par la façon dont la liste est retournée en arrière, parce que nous avons utilisé foldLeft au lieu de foldRight.

203voto

Kim Stebel Points 22873

``est juste une méthode pratique. Il est équivalent à

49voto

thoredge Points 5829

foldLeft est plus générique, vous pouvez l'utiliser pour produire quelque chose de complètement différent de ce que vous avez initialement mis en. Alors qu' reduceLeft ne peut produire un résultat du même type ou de la super-type du type de collection. Par exemple:

List(1,3,5).foldLeft(0) { _ + _ }
List(1,3,5).foldLeft(List[String]()) { (a, b) => b.toString :: a }

L' foldLeft s'appliquera à la fermeture avec la dernière plié résultat (première fois à l'aide de la valeur initiale) et la valeur suivante.

reduceLeft sur l'autre main sera la première à combiner deux valeurs à partir de la liste et de les appliquer à la fermeture. Ensuite, il va combiner le reste des valeurs avec le résultat cumulatif. Voir:

List(1,3,5).reduceLeft { (a, b) => println("a " + a + ", b " + b); a + b }

Si la liste est vide foldLeft peut présenter la valeur initiale comme un résultat de l'analyse juridique. reduceLeft d'autre part n'ont pas de valeur juridique s'il ne peut pas trouver au moins une valeur dans la liste.

6voto

Martin Smith Points 21

Pour référence, `` sera erreur si appliqué à un conteneur vide avec l’erreur suivante.

Retravailler le code à utiliser

est une option possible. Une autre consiste à utiliser la `` variante qui retourne une Option enveloppé de résultat.

5voto

Alexey Romanov Points 39124

La raison fondamentale, ils sont tous deux en Scala bibliothèque standard est probablement parce qu’ils sont tous deux dans la bibliothèque standard Haskell (appelés et ). Si `` n’était pas, il serait assez souvent défini comme une méthode de pratique dans différents projets.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X