如何判断地图是否具有默认值? [英] How to tell if a Map has a default value?

查看:97
本文介绍了如何判断地图是否具有默认值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法检查 Map 是否具有定义的默认值?我想要的是一些相当于 myMap.getOrElse(x,y)的地方,如果密钥 x 不在如果 myMap 具有默认值,则返回该值





  • else return y



问题的例子:

  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

在这种情况下,我想要code> res0 为Z而不是world,因为 myMap 被定义为默认值。但是 getOrElse 不能这样工作。






我可以使用 m.apply 而不是 m.getOrElse ,但是地图不能保证具有默认值,所以它可能会抛出异常(我可以抓到异常,但这是非常的)。

  scala> def f(m:Map [String,String])= try {
| m(你好)
| 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)

阶> f(mapWithNoDefault)
res1:String = world

以上产生了预期值,但似乎乱。根据地图是否具有默认值,我无法模式匹配,并调用应用 getOrElse 类型是相同的( scala.collection.immutable.Map [String,String] ),不管默认值。


解决方案

你可以检查地图是否是一个实例 Map.WithDefault

 隐式类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)

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

这种反思是否比使用非特殊控制流程的异常更好是一个悬而未决的问题。


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?

解决方案

You can check whether the map is an instance of 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)
}

And then:

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

Whether this kind of reflection is any better than using exceptions for non-exceptional control flow is an open question.

这篇关于如何判断地图是否具有默认值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆