How to determine if a map value has a default value?

Is there a way to check if a Mapspecific default value matters? I would like to have an equivalent myMap.getOrElse(x, y)if the key is xnot on the card,

  • If it myMaphas a default value, return this value
  • else return y

A contrived example of a problem:

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 to res0be "Z"instead "world", because I myMapwas defined with this default value. But getOrElsedoes not work.


I could use m.applyinstead m.getOrElse, but the default value is not guaranteed on the map, so it can throw an exception (I could catch an exception, but it's imperfect).

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

, . apply getOrElse , , (scala.collection.immutable.Map[String,String]), .

, catching?

+4
2

, Map.WithDefault:

implicit class EnrichedMap[K, V](m: Map[K, V]) {
  def getOrDefaultOrElse(k: K, v: => V) =
    if (m.isInstanceOf[Map.WithDefault[K, V]]) m(k) else m.getOrElse(k, v)
}

:

scala> val myMap = Map("a" -> "A").withDefaultValue("Z")
myMap: scala.collection.immutable.Map[String,String] = Map(a -> A)

scala> myMap.getOrDefaultOrElse("hello", "world")
res11: String = Z

scala> val myDefaultlessMap = Map("a" -> "A")
myDefaultlessMap: scala.collection.immutable.Map[String,String] = Map(a -> A)

scala> myDefaultlessMap.getOrDefaultOrElse("hello", "world")
res12: String = world

, , .

+3

Try try/catch, .

val m = Map(1 -> 2, 3 -> 4)

import scala.util.Try 

Try(m(10)).getOrElse(0)

res0: Int = 0

val m = Map(1 -> 2, 3 -> 4).withDefaultValue(100)

Try(m(10)).getOrElse(0)

res1: Int = 100
+2

Source: https://habr.com/ru/post/1548092/


All Articles