3

I have a Map

val m = Map(1->13, 2->Map(3->444, 4-> List("aaa", "bbb")))

I want to get its nested values:

// these all lead to an error
m.get(2)(3)
m.get(2).get(3)
m.get(2).get.get(3)

How do I do that?

Joe Kennedy
  • 9,365
  • 7
  • 41
  • 55
Alan Coromano
  • 24,958
  • 53
  • 135
  • 205
  • Your problem comes from the fact that inside your map you're mixing values of heterogenous types (some are maps, others aren't) so your Map is interpreted as Map[Int,Any] (because Any is the common root in the type hierarchy for Int and Map.) Since Any does not have a "get" method or an "apply" method it all ends up with an error. – Jerome ROBERT Jun 05 '13 at 06:19

2 Answers2

5

You have lost type information.

You could actually do what you want, but it's not typesafe.

m.get(2).flatMap{ case m2: Map[Int, _] => m2.get(3) }

Since you have lost type information you have to cast explicitly, so if you want to get list's element you should do something like this:

m.get(2).flatMap{ case m2: Map[Int, _] => m2.get(4) }.map{ case l: List[_] => l(1) }

You should try to save type information. At least you could use Either.

Community
  • 1
  • 1
senia
  • 37,745
  • 4
  • 88
  • 129
1

You have a map which has inconsistent types of key-value pairs. Hence there cannot be one generalized answer.

Firstly m.get(2) returns an Option[Any]. Doing m.get(2)(3) is basically trying to do:

val option = m.get(2) //option is of type Option[Any]
option(3) //error

Hence you need to do:

m.get(2) match {
case Some(i) => i match {
     case j:Map[Any,Any] => j(3)
     }
 }

Something of this sort.

Jatin
  • 31,116
  • 15
  • 98
  • 163