Scala列表和选项

时间:2013-12-19 16:08:37

标签: scala

我一定是做错了。我来自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来说并不容易。

请帮忙。

由于

4 个答案:

答案 0 :(得分:7)

其他答案是正确的,关于你如何不将新的ListBuffer放回Map,但他们的示例代码是详细的。可变Map具有getOrElsegetOrElseUpdate方法。另外,对于本地人和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 不会自动放入地图。这样的操作没有意义 - getOrElseOption 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)

如果key不存在,

getOrElse将返回默认的ListBuffer,它是一个空的ListBuffer。您需要将此与您的密钥相关联。