Is there a way to check if a Map
has a defined default value? What I would like is some equivalent of myMap.getOrElse(x, y)
where if the key x
is not in the map,
- if
myMap
has a default value, return that value - else return
y
A contrived example of the issue:
scala> def f(m: Map[String, String]) = m.getOrElse("hello", "world")
f: (m: Map[String,String])String
scala> val myMap = Map("a" -> "A").withDefaultValue("Z")
myMap: scala.collection.immutable.Map[String,String] = Map(a -> A)
scala> f(myMap)
res0: String = world
In this case, I want res0
to be "Z"
instead of "world"
, because myMap
was defined with that as a default value. But getOrElse
doesn't work that way.
I could use m.apply
instead of m.getOrElse
, but the map is not guaranteed to have a default value, so it could throw an exception (I could catch the exception, but this is nonideal).
scala> def f(m: Map[String, String]) = try {
| m("hello")
| } catch {
| case e: java.util.NoSuchElementException => "world"
| }
f: (m: Map[String,String])String
scala> val myMap = Map("a" -> "A").withDefaultValue("Z")
myMap: scala.collection.immutable.Map[String,String] = Map(a -> A)
scala> f(myMap)
res0: String = Z
scala> val mapWithNoDefault = Map("a" -> "A")
mapWithNoDefault: scala.collection.immutable.Map[String,String] = Map(a -> A)
scala> f(mapWithNoDefault)
res1: String = world
The above yields the expected value but seems messy. I can't pattern match and call apply
or getOrElse
based on whether or not the map had a default value, because the type is the same (scala.collection.immutable.Map[String,String]
) regardless of default-ness.
Is there a way to do this that doesn't involve catching exceptions?