gmds
gmds

Reputation: 19885

How to cast a Map based on the type of its keys?

I have a function, getMap, that returns Map[Any, Double], to reflect that the type of the keys can vary.

However, the keys of each Map returned will all be of the same type, depending deterministically on the input, for example:

val intMap = getMap(someParam)

// the keys of intMap are all of type Int

val stringMap = getMap(someOtherParam)

// the keys of stringMap are all of type String

I would like to downcast each Map at runtime.

This is what I tried:

val actuallyIntMap = Map[Any, Double](1 -> 1.0)
type keyType = actuallyIntMap.head._1.getClass

val intMap = actuallyIntMap.asInstanceOf[Map[keyType, Double]]

// I expect intMap to be a Map[Int, Double]

The result is the following error:

error: stable identifier required, but this.intMap.head._1 found.
       type keyType = intMap.head._1.getClass

I suppose it's because keyType cannot be resolved at compile time...? While I could pattern match on the first value and create a Map that way, that seems like poor design (and tedious besides).

Is there any way to do this in Scala, assuming I cannot change the getMap function?

Upvotes: 1

Views: 125

Answers (1)

Tim
Tim

Reputation: 27421

Your supposition is correct; this does not work because the type of intMap is not known at compile time.

If the result type is known at compile time, you can do something like this:

actuallyIntMap.collect{ case (i: Int, v) => i -> v }

This will return Map[Int, Double] and discard any entries where the key is not Int.

Upvotes: 1

Related Questions