我一定是做错了。我来自Java背景,所以这个东西应该很容易。
我想在列表中保存的键和多个值之间创建映射:
var keys = Map[String, ListBuffer[String]]()
然而,我似乎无法在列表中添加值!我做错了什么?
def put(key: String, value: String) = {
var valueOption = keys.get(key)
var values = valueOption.getOrElse(ListBuffer)
values += value
// value not added
}
我不想使用MultiMap,因为我需要做一些其他操作,这些操作对MultiMap来说并不容易。
请帮忙。
由于
答案 0 :(得分:7)
其他答案是正确的,关于你如何不将新的ListBuffer
放回Map
,但他们的示例代码是详细的。可变Map
具有getOrElse
和getOrElseUpdate
方法。另外,对于本地人和val
成员,请使用var
而不是keys
,除非您有理由不这样做。我有时更喜欢append
到+=
。
def put(key: String, value: String) = {
keys.getOrElseUpdate(key, ListBuffer()) += value
}
答案 1 :(得分:4)
问题在于:
var valueOption = keys.get(key)
var values = valueOption.getOrElse(ListBuffer)
对于任何不存在的密钥,keys.get
将返回None
Option
。然后,您调用getOrElse
,由于使用了“else”部分(因为它是None
),因此初始化了新的ListBuffer
。但是,这是所有发生的事情。
特别是,新的ListBuffer
不会自动放入地图。这样的操作没有意义 - getOrElse
是Option
API的一部分,它无法“知道”有关Option
生成的任何集合。
要解决您的问题,您必须自己将新ListBuffer
放入地图。例如,如果您使用可变地图:
def put(key: String, value: String) = {
var valueOption = keys.get(key)
var values = valueOption.getOrElse {val b = ListBuffer.empty[String]; keys.put(key,b); b;}
values += value
}
答案 2 :(得分:0)
问题是,通过调用getOrElse(ListBuffer)
,您不会将新的ListBuffer插入Map中。所以你需要添加一个额外的步骤:
def put(key: String, value: String) = {
var valueOption =
var values = keys.get(key) match {
case None => // key not yet defined
buffer = ListBuffer()
// insert into map!
keys += key -> buffer
buffer
case Some(buffer) => buffer // key is already defined just return it
}
values += value
}
请注意,对于keys += key -> buffer
工作,我假设你使用了一个可变的Map(从scala.collection.mutable.Map导入)instad的默认不可变Map
答案 3 :(得分:0)
getOrElse
将返回默认的ListBuffer,它是一个空的ListBuffer。您需要将此与您的密钥相关联。