以值作为列表附加到Map

时间:2015-06-18 15:57:54

标签: scala

我已经初始化了一个可变Map(不确定我是否应该在这里使用mutable,但是从使用mutable开始):

val aKey = "aa"
val myMap = scala.collection.mutable.Map[String, List[String]]()
if (myMap.exists(_._1 == aKey))
    myMap(aKey) = myMap.get(aKey) :: "test"

但在myMap.get(aKey)我收到以下错误:

  

Type Mismatch expected List [String]实际选项[String]

我认为我做的方式是正确的,可以附加到列表中。

6 个答案:

答案 0 :(得分:5)

您可以使用+=附加到可变地图。

scala> myMap += ("placeholders" -> List("foo", "bar", "baz"))
res0: scala.collection.mutable.Map[String,List[String]] = Map(placeholders -> List(foo, bar, baz))

将新项目添加到提交中提到的aKey列表中。

myMap.get("placeholders") match {
 case Some(xs:List[String]) => myMap.update("placeholders", xs :+ "buzz")
 case None => myMap
}
res22: Any = ()

scala> myMap
res23: scala.collection.mutable.Map[String,List[String]] = Map(placeholders -> List(foo, bar, baz, buzz))

答案 1 :(得分:4)

一切都很好。除了列表追加运算符

将元素添加到列表中。运算符应该类似于

myList = element :: myList
myList = myList :: element  // wrong

所以你的程序应该是

val aKey = "aa"
var myMap = scala.collection.mutable.Map[String, List[String]]().withDefaultValues(List())
myMap(aKey) = "test" :: myMap(aKey) 

答案 2 :(得分:3)

如果您有mutable Map并且在该地图内immutable List。这是一个关于如何做的简单示例。该示例还定义了使用withDefaultValue - 以便您始终从Map获得回复。

var posts: collection.mutable.Map[Int, List[String]] = collection.mutable.Map().
  withDefaultValue List.empty[String]

def addTag(postID: Int, tag: String): Unit = posts.get(postID) match {
  case Some(xs: List[String]) => posts(postID) = xs :+ tag
  case None => posts(postID) = List(tag)
}

posts(42)
// List[String] = List() 

addTag(42, "tag-a")
addTag(42, "tag-b")
addTag(42, "tag-c")

posts(42)
// List[String] = List(tag-a, tag-b, tag-c)

答案 3 :(得分:1)

Scala 2.13开始,您也可以在可变的Map上使用Map#updateWith(或在不可变的Map上使用Map#updatedWith):

map.updateWith("a")({
  case Some(list) => Some("test" :: list)
  case None       => Some(List("test"))
})
  

def updateWith(key:K)(remappingFunction:(Option [V])=> Option [V]):Option [V]


例如,

val map = collection.mutable.Map[String, List[String]]()
// map: collection.mutable.Map[String, List[String]] = HashMap()
val key = "key"
// key: String = "key"

如果密钥不存在:

map.updateWith(key)({ case Some(list) => Some("test" :: list) case None => Some(List("test")) })
// Option[List[String]] = Some(List("test"))
map
// collection.mutable.Map[String, List[String]] = HashMap("key" -> List("test"))

,如果密钥存在:

map.updateWith(key)({ case Some(list) => Some("test2" :: list) case None => Some(List("test2")) })
// Option[List[String]] = Some(List("test2", "test"))
map
// collection.mutable.Map[String, List[String]] = HashMap("key" -> List("test2", "test"))

答案 4 :(得分:0)

我想到了如何做到这一点:

  val aKey = "aa"
  var myMap = scala.collection.mutable.Map[String, List[String]]()
  if (myMap.exists(_._1 == aKey))
    myMap.get(aKey).get :+ "foo"
  else {
    myMap(aKey) = List("zoo")
  }

这可能不是scala的做法,但这会给出正确的结果。

答案 5 :(得分:0)

首先,您不应该将Mutable Map :)。要在Map中的列表上添加一项,您可以使用Map的get方法。

val m = Map(1 -> List(2))
val m2 = m.get(1).fold{
  // In this case don't exist any List for this key
  m + (1 -> List(3))
}{ list =>
  // In this case exist any List for this key
  m + (1 -> (3 :: list))
}