Scala。附加到Map的值,即ListBuffer

问题描述 投票:0回答:2

我有一个空Map,默认值为ListList空。

val map: Map[String, ListBuffer[String]] = Map.empty.withDefaultValue(ListBuffer())

当我寻址到它尚不存在的键并想要附加一些值时,它执行了意外的操作:

// map += "one" -> ListBuffer("l")
map("one") += "lo"
map("two") += "lol"
map("one") += "la"

println(map("one").result)

我认为它应该打印List(lo, la),但它打印List(lo, lol, la)for(m <- map) println(m)不打印任何内容。如果我取消注释map += "one" -> ListBuffer("t"),它将打印正确的List(l, lo, la),但是println("two(or any other key)")打印List(lo, lol, la)。我该如何解决?有什么我不知道的地方吗?

scala data-structures append key
2个回答
0
投票

发生这种情况是因为您的地图具有默认值-ListBuffer()当您尝试向地图添加内容时:map("one") += "lo"实际在地图中查找键one时一无所获并获得默认值-ListBuffer()。之后,lo附加到ListBuffer(),现在默认值为ListBuffer("lo")twoone键重复相同的算法。这样,键one(以及其余键)将永远不会放置在地图上。

而且您正在使用不可变的地图,添加后它会创建新的地图。如果要使用所有键和值来收集地图,则可以使用foldLeft:

val map: Map[String, ListBuffer[String]] = Map.empty.withDefaultValue(ListBuffer())
val newMap = Seq(
  "one" -> "lo",
  "two" -> "lol",
  "one" -> "la"
).foldLeft(map){
  case (accMap, (key, value)) => accMap + (key -> (value +: accMap(key)))
}
println(newMap("one").result) // List(la, lo)
println(newMap) // Map(one -> ListBuffer(la, lo), two -> ListBuffer(lol))

或您可以使用易变地图:

val map: mutable.Map[String, ListBuffer[String]] = mutable.Map.empty.withDefaultValue(ListBuffer())
map.update("one",  "lo" +: map("one"))
map.update("two",  "lol" +: map("two"))
map.update("one",  "la" +: map("one"))
println(map("one").result) // List(la, lo)
println(map) // Map(one -> ListBuffer(la, lo), two -> ListBuffer(lol))

0
投票

如果您有这样的元组序列

val keyValue = Seq( "one" -> "lo", "two" -> "lol", "one" -> "la" )

我建议您这样使用groupBy

println(x.groupBy(_._1).mapValues(_.map(_._2)))

由于在Scala中使用可变数据结构不是很好,因此您可能会考虑设计并尝试对其进行更改。

为什么无法从代码中获得所需的输出是因为您有一个不可变的Map,如果要更新该Map,则需要一个可变的map,它为您提供方法更新,这里您在map("one") += "la"中取了什么发生这种情况时,当您执行map(“ one”)为空时会得到listBuffer,然后使用"lo"+=使用"two" and "one"更新该listBuffer,但是如果您看到那里的地图仍然为空在地图中没有任何内容,因为您没有更新地图,因此您已经更新了listBuffer。您是从map("one")获得的,这是一个空的listBuffer。

如果您在打印中使用anystring,您将得到相同的结果

println(map("").result) //List("lo", "lol", "la")
© www.soinside.com 2019 - 2024. All rights reserved.