Scala中的多键映射

6

我该如何在Scala中创建一个地图(Map),它不仅可以使用单个参数作为键,而是可以使用两个或三个参数作为键。

val map = //..?
map("abc", 1) = 1
println(map("abc", 2)) // => null
println(map("abc", 1)) // => 1

我曾试着使用元组作为键,但是这样我必须像这样分配值。
map(("abc", 1)) = 1

我能否以某种方式摆脱内部括号?

4个回答

12

您也可以使用

map += ("abc", 1) -> 1
如果地图键表示某些内容(例如用户信息),并且您想要为代码添加清晰度(特别是如果键中有3个元素),我建议使用case class作为键。 Case class已经实现了equals和hashcode,因此您可以安全地将它们用作地图中的键。 但是,代码可能会更加冗长:
如果地图键表示某些内容(例如用户信息),并且您想要为代码添加清晰度(特别是如果键中有3个元素),我建议使用case class作为键。 Case class已经实现了equals和hashcode,因此您可以安全地将它们用作地图中的键。 但是,代码可能会更加冗长:
case class MapKey(s: String, i: Int, d: Double)

val map = Map[MapKey, X](MapKey("a", 1, 1.1) -> "value1", MapKey("b", 2, 2.2) -> "value2")

val map2 = map + (MapKey("c", 3, 3.3) -> "value3")

//or for mutable map
map(MapKey("d", 4, 4.4)) = "value4"
//or
map += MapKey("e", 5, 5.5) -> "value5"

1
是的,我考虑过使用 case class,但那比括号还要更加嘈杂。 - knub
我同意case classes在这种情况下会增加代码的冗长程度。它们可以更好地对映射进行类型化,并增加代码的清晰度,因为您可以为表示键的概念命名。但是根据您的使用情况,它们也可能过度复杂化。 - Felix Trepanier
1
这个问题的关键是你无法进行正确的搜索。 - BAR

7
您可以为Map添加自己的增强功能来解决这个问题:
import collection.mutable.Map

implicit class EnhancedMap[A,B,C](m: Map[(A,B),C]) {
  def update(a: A, b: B, c: C) { m((a,b)) = c }
}

那么

val map = Map(("abc", 1) -> 0)
map("abc", 1) = 1

运行得很好。


3
你可以使用“->”语法来表示元组:
map("abc" -> 1) = 1

1
我使用了Luigi Plinge的方法后出现了编译错误。下面的方法适用于我,而且更简单。
scala> var b = Map[(Int, Int), Int]()
b: scala.collection.mutable.Map[(Int, Int),Int] = Map()

scala> b = b + ((1,1)->2)
b: scala.collection.mutable.Map[(Int, Int),Int] = Map((1,1) -> 2)

scala> b
res15: scala.collection.mutable.Map[(Int, Int),Int] = Map((1,1) -> 2)

scala> b = b + ((1,2)->2)
b: scala.collection.mutable.Map[(Int, Int),Int] = Map((1,1) -> 2, (1,2) -> 2)

scala> b(1,1)
res16: Int = 2

scala> b(1,2)
res17: Int = 2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接