Scala convert Option to an Int
Asked Answered
R

4

8

I have looked at these links

http://blog.danielwellman.com/2008/03/using-scalas-op.html

http://blog.tmorris.net/scalaoption-cheat-sheet/

I have a map of [String, Integer] and when I do a map.get("X") I get an option. I would like the following.

val Int count = map.get(key); 
// If the key is there I would like value if it is not I want 0

How do I achieve this in one line? I need to do this several times. It looks a bit inefficient to write a function everytime for doing this. I am sure there is some intelligent one line quirk that I am missing but I really like to get the value into an integer in ONE line :)

Reptile answered 17/4, 2012 at 8:50 Comment(3)
If you get an Option then you have a Map[String, Option[Int]] not a Map[String, Int].Labanna
@MirkoN. No, it is because get returns Option[Value]. scala> Map(1 -> 2).get(1) res2: Option[Int] = Some(2)Fuselage
Well, what will you do if the Int is not available? Depending on the answer to that, the optimal solution is different.Mutual
F
18

Just use getOrElse method:

val count: Int = map.getOrElse(key,0);

Note also, that in Scala you write type after name, not before.

Fuselage answered 17/4, 2012 at 8:56 Comment(1)
The problem I got is the type is still Any instead of being an Integer. map.getOrElse(key,0) returns a type of AnyMartymartyn
E
6

@om-nom-nom (classic screen name) has the correct answer, but in the interest of providing yet another way

val count = map.get(key) fold(0)(num => num)

Before in-the-know users bash me with, "Option has no fold!", fold has been added to Option in Scala 2.10

getOrElse is of course better in the current case, but in some Some/None scenarios it may be interesting to 1-liner with fold like so (edited complements of @Debiliski who tested against latest 2.10 snapshot):

val count = map.get(k).fold(0)(dao.userlog.count(_))

I suppose in 2.9.2 and under we can already do:

val count = map get(k) map ( dao.userlog.count(_) ) getOrElse(0)

Which is to say, in Scala there is often more than one way to do the same thing: in the linked thread, the OP shows more than 10 alternative means to achieve Option fold ;-)

Ergonomics answered 17/4, 2012 at 10:17 Comment(10)
yah, I got excited too when I came across the scala-lang thread ;-) Hopefully 2.10 M3 will be released soon after Scala Days conference finishes, a lot to look forward to in Scala.NextErgonomics
@virtualeyes: That would be map.get(key).fold(0)(num => num) in 2.10 (at least going by the current nightly).Perpetua
@Debilski, right, was going with OP's approach in the scala-lang thread; there was a lot of back & forth over the order (some, none) or (none, some); looks like Paul Phillips went with (none)(some) based on his latest commit "github.com/scala/scala/commit/bb4935e92c". I'll edit my answer so at not mislead further ;-) thanksErgonomics
"fold(0)(num => num)" is a bit annoying, "fold(0)(x)" would be wonderfully concise...Ergonomics
This makes no sense: (none => 0, num => num). There's no value to pass in the None case, so folding it doesn't take a function.Mutual
@Debiliski, set that straight, but neglected to fix in the first example, corrected now...Ergonomics
@virtualeyes: If you want to set a single x in case of a Some (regardless of the Somes value), you don’t need a fold anyway. And if all you have is fold(0)(x => x) or fold(0)(identity), then a getOrElse is more concise anyway.Perpetua
indeed, for the getOrElse case. I was more pointing out (or trying to) a possible use case for fold with Option similar to folding over an Either, where one performs an operation based on the left (none) or right (some) condition; that is, vs. simply returning a default value.Ergonomics
in Scala there is often more than one way to do the same thing. That really scare me sometimes: I don't want Scala to become new Perl.Fuselage
@Fuselage too late, Martin O wants to simplify, but the Scala train has already left the station, all aboard ;-) I would describe Scala as refined Perl with added hieroglyphic symbolism, the overmind (++) being one of my favorites. SBT and FP take things to an entirely different level, from the outside looking in, no wonder Scala has the "complex" stigma. A few months into learning Scala, I absolutely love it, but the beginning was chock full of WTFsErgonomics
C
3

Yet another way.

import scalaz._, Scalaz._

scala> val m = Map(9 -> 33)
m: scala.collection.immutable.Map[Int,Int] = Map(9 -> 33)

scala> m.get(9).orZero
res3: Int = 33

scala> m.get(8).orZero
res4: Int = 0
Ching answered 17/4, 2012 at 16:35 Comment(0)
T
0

for import scala.collection.mutable.SortedMap

val myMap =  SortedMap[[Integer,Integer]
val theGotten = myMap.getOrElse(aKey,0)
returned an Any   but

val myMap =  SortedMap[[Int,Int]
val theGotten = myMap.getOrElse(aKey,0)
returns an Int
Traction answered 22/10, 2023 at 12:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.