2010-11-14 14 views
25

¿Cómo se usa Map.foldLeft? De acuerdo con la docs se ve comoScala foldLeft en Maps

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

Pero estoy teniendo dificultad:

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

error: not a legal formal parameter

Los puntos de error en el soporte abierto delante de k.

Respuesta

66

Si desea utilizar la sintaxis (a, (k, v)), es necesario informar al compilador que utilice la coincidencia de patrones.

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

Tenga en cuenta que una declaración case requiere llaves.

16

creo, no se puede hacer la comparación de patrones de tuplas como se esperaba:

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

En realidad, el uso de los valores y la suma es más simple.

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

Él _es coincidencia de patrón de tuplas. Para emparejar el patrón, sin embargo, uno necesita usar 'case'. –

+0

@Daniel Esa es la ventaja de mi oración tipo abogado: es correcta (no puede ajustar el patrón como esperaba) pero he olvidado la sintaxis del caso. –

+1

Para problemas como este, el uso de 'values' o' mapValues' es absolutamente la solución más clara (que casi siempre será la elección correcta) –

5

Esto no es realmente una respuesta a su pregunta, pero me pareció útil cuando comencé con pliegues, ¡así que lo diré de todos modos! Tenga en cuenta que la /: método de "alias" para foldLeft puede ser más claro por dos razones:

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

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

Tenga en cuenta que en la segunda línea:

  • es más claro que el valor y es ser doblado en la colección xs
  • puede recordar fácilmente el orden del argumento Tuple2 es el mismo que el orden del método "llamar"
6

El truco es utilizar una función parcial como el bloque de código, es decir, se agrega una declaración case que coincide en los argumentos:

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