[英]How to implement Map with default operation in Scala
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]
.我不想创建 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 List
instead of Exception
being thrown.在我的情况下,它是Long -> List[String]
但是当我从 map 获得没有价值的密钥时,我想创建空List
而不是抛出Exception
。 I tried different combinations but I don't know how to make code above pass the compiler.我尝试了不同的组合,但我不知道如何使上面的代码通过编译器。
Thanks in advance.提前致谢。
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()
Rather than using apply
to access the map, you could always use get
, which returns Option[V]
and then getOrElse
:与其使用apply
来访问 map,不如使用get
,它返回Option[V]
然后getOrElse
:
map.get(k) getOrElse Nil
One great feature of the scalaz functional-programming library is the unary operator ~
, which means "or zero",as long as the value type has a "zero" defined (which List
does, the zero being Nil
of course). scalaz函数式编程库的一个重要特性是一元运算符~
,这意味着“或零”,只要值类型定义了“零”( List
确实如此, Nil
当然是 Nil)。 So the code then becomes:所以代码就变成了:
~map.get(k)
This is doubly useful because the same syntax works where (for example) your values are Int
, Double
etc (anything for which there is a Zero
typeclass).这是双重有用的,因为相同的语法适用于(例如)你的值是Int
, Double
等(任何Zero
类型类的东西)。
There has been a great deal of debate on the scala mailing list about using Map.withDefault
because of how this then behaves as regards the isDefinedAt
method, among others.关于使用Map.withDefault
的 scala 邮件列表存在很多争论,因为它在isDefinedAt
方法等方面的表现如何。 I tend to steer clear of it for this reason.出于这个原因,我倾向于避开它。
There's a method withDefaultValue
on Map
: Map
withDefaultValue
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()
Why do you want to manipulate a map when it has already a method for this?当 map 已经有方法时,为什么还要操作它?
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)
withDefault can 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.希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.