如何在 Scala 中使用默认操作实现 Map
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5830458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to implement Map with default operation in Scala
提问by Lukasz
class DefaultListMap[A, B <: List[B]] extends HashMap[A, B] {
override def default(key: A) = List[B]()
}
I wan't to create map A -> List[B]. In my case it is Long -> List[String]but when I get key from map that doesn't have value I would like to create empty Listinstead of Exceptionbeing thrown. I tried different combinations but I don't know how to make code above pass the compiler.
我不想创建 map A -> List[B]。在我的情况下,Long -> List[String]但是当我从地图中获得没有价值的键时,我想创建空List而不是Exception被抛出。我尝试了不同的组合,但我不知道如何使上面的代码通过编译器。
Thanks in advance.
提前致谢。
回答by Ilya Klyuchnikov
Why not to use withDefaultValue(value)?
为什么不使用 withDefaultValue(value)?
scala> val m = Map[Int, List[String]]().withDefaultValue(List())
m: scala.collection.immutable.Map[Int,List[String]] = Map()
scala> m(123)
res1: List[String] = List()
回答by oxbow_lakes
Rather than using applyto access the map, you could always use get, which returns Option[V]and then getOrElse:
而不是apply用于访问地图,您可以始终使用get,它返回Option[V]然后getOrElse:
map.get(k) getOrElse Nil
One great feature of the scalazfunctional-programming libraryis the unary operator ~, which means "or zero",as long as the value type has a "zero" defined (which Listdoes, the zero being Nilof course). So the code then becomes:
scalaz函数式编程库的一个重要特性是一元运算符~,这意味着“或零”,只要值类型定义了“零”(List确实如此,零Nil当然是)。所以代码就变成了:
~map.get(k)
This is doubly useful because the same syntax works where (for example) your values are Int, Doubleetc (anything for which there is a Zerotypeclass).
这是极为有用的,因为相同的语法工程时(例如)你的价值观是Int,Double等(任何事情上有一个Zero类型类)。
There has been a great deal of debate on the scala mailing list about using Map.withDefaultbecause of how this then behaves as regards the isDefinedAtmethod, among others. I tend to steer clear of it for this reason.
在 Scala 邮件列表上有很多关于使用的争论,Map.withDefault因为它在isDefinedAt方法方面的表现等等。出于这个原因,我倾向于避开它。
回答by kassens
There's a method withDefaultValueon Map:
有一个方法withDefaultValue上Map:
scala> val myMap = Map(1 -> List(10), 2 -> List(20, 200)).withDefaultValue(Nil)
myMap: scala.collection.immutable.Map[Int,List[Int]] = Map((1,List(10)), (2,List(20, 200)))
scala> myMap(2)
res0: List[Int] = List(20, 200)
scala> myMap(3)
res1: List[Int] = List()
回答by Landei
Why do you want to manipulate a map when it has already a method for this?
当地图已经有一个方法时,你为什么要操作它?
val m = Map(1L->List("a","b"), 3L->List("x","y","z"))
println(m.getOrElse(1L, List("c"))) //--> List(a, b)
println(m.getOrElse(2L, List("y"))) //--> List(y)
回答by tharindu_DG
withDefaultcan also be used.
也可以使用withDefault。
/** The same map with a given default function.
* Note: `get`, `contains`, `iterator`, `keys`, etc are not affected
* by `withDefault`.
*
* Invoking transformer methods (e.g. `map`) will not preserve the default value.
*
* @param d the function mapping keys to values, used for non-present keys
* @return a wrapper of the map with a default value
*/
def withDefault[B1 >: B](d: A => B1): immutable.Map[A, B1]
Example:
例子:
scala> def intToString(i: Int) = s"Integer $i"
intToString: (i: Int)String
scala> val x = Map[Int, String]().withDefault(intToString)
x: scala.collection.immutable.Map[Int,String] = Map()
scala> x(1)
res5: String = Integer 1
scala> x(2)
res6: String = Integer 2
Hope this helps.
希望这可以帮助。

