2010-11-14 15 views
25

Comment utilisez-vous Map.foldLeft? Selon le docs il ressemble àScala foldGauche sur Cartes

foldLeft [B] (z: B)(op: (B, (A, B)) ⇒ B) : B 

Mais je difficulté:

Map("first"->1,"second"->2).foldLeft(0)((a,(k,v)) => a+v) 

error: not a legal formal parameter

Les points d'erreur au support ouvert devant k.

Répondre

66

Si vous souhaitez utiliser la syntaxe (a, (k, v)), vous devez informer le compilateur pour utiliser la correspondance de motif.

Map("first"->1, "second"->2).foldLeft(0){ case (a, (k, v)) => a+v } 

Notez qu'une déclaration case exige des accolades.

16

Je pense, vous ne pouvez pas faire le match de motif sur tuples comme prévu:

Map("first"->1,"second"->2).foldLeft(0)((a, t) => a + t._2) 

En fait, en utilisant des valeurs et la somme est plus simple.

Map("first"->1,"second"->2).values.sum 
+6

Il _can_ match de motif sur tuples. Pour modéliser, cependant, il faut utiliser 'case'. –

+0

@Daniel C'est l'avantage de ma phrase d'avocat: c'est correct (il ne peut pas correspondre à son modèle comme il s'y attendait) mais j'ai oublié la syntaxe du cas. –

+1

Pour des problèmes comme celui-ci, utiliser 'values' ou' mapValues' est absolument la solution la plus claire (ce qui en fera presque toujours le bon choix) –

5

Ce n'est pas vraiment une réponse à votre question mais je l'ai trouvé utile en commençant avec des plis, donc je vais le dire quand même! Notez que la méthode /: « alias » pour foldLeft peut être plus clair pour deux raisons:

xs.foldLeft(y) { (yy, x) => /* ... */ } 

(y /: xs) { (yy, x) => /* ... */ } 

Notez que dans la deuxième ligne:

  • il est plus clair que la valeur y est d'être pliée en vous pouvez facilement vous rappeler que la commande de l'argument Tuple2 est la même que celle de la commande "call"
6

L'astuce est d'utiliser une fonction partielle que le bloc de code, en d'autres termes vous ajoutez une déclaration case qui correspond aux arguments:

Map("first" -> 1, "second" -> 2).foldLeft(0) { case (a, (k, v)) => a + v }