Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-key Map in Scala

How can I create a Map in Scala which does not only take a single parameter as key, but rather two or three.

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

I tried using tuples as a key, but then I have to assign values like this

map(("abc", 1)) = 1

Can I somehow get rid of the inner parentheses?

like image 800
knub Avatar asked Feb 17 '13 23:02

knub


3 Answers

You could also use

map += ("abc", 1) -> 1

If the map key represents something (e.g. user info) and if you want to add clarity to your code (especially if you have 3 elements in the key), I would go with a case class as the key. Case classes have equals and hashcode implemented so you can safely use them as keys in a map. The code would be more verbose though:

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"
like image 184
Felix Trepanier Avatar answered Sep 21 '22 11:09

Felix Trepanier


You can add your own enhancement to Map that will do the trick:

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 }
}

then

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

works just fine.

like image 38
Luigi Plinge Avatar answered Sep 21 '22 11:09

Luigi Plinge


You can use -> syntax for tuples:

map("abc" -> 1) = 1
like image 39
om-nom-nom Avatar answered Sep 22 '22 11:09

om-nom-nom