Pengin
Pengin

Reputation: 4772

Scala foldLeft on Maps

How do you use Map.foldLeft? According to the docs it looks like

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

But I'm having difficulty:

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

error: not a legal formal parameter

The error points to the open bracket in front of k.

Upvotes: 40

Views: 35111

Answers (4)

Theo
Theo

Reputation: 132972

The trick is to use a partial function as the code block, in other words you add a case statement that matches on the arguments:

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

Upvotes: 8

oxbow_lakes
oxbow_lakes

Reputation: 134330

This is not really an answer to your question but I found it useful when starting out with folds, so I'll say it anyway! Note that the /: method "alias" for foldLeft can be clearer for two reasons:

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

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

Note that in the second line:

  • it's more clear that the value y is being folded into the collection xs
  • you can easily remember the ordering of the Tuple2 argument is the same as the ordering of the method "call"

Upvotes: 4

Debilski
Debilski

Reputation: 67888

If you want to use the (a, (k, v)) syntax, you need to advise the compiler to use pattern matching.

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

Note that a case statement requires curly braces.

Upvotes: 93

Thomas Jung
Thomas Jung

Reputation: 33092

I think, you can't do the pattern match on tuples as you expect:

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

Actually, using values and sum is simpler.

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

Upvotes: 18

Related Questions