Question

Is it possible to write a method like

def enumToMap[E <: Enumeration]: Map[String, Int]

that for a given enumeration, f.e.

object PROTOCOL_TYPE extends Enumeration{
  type PROTOCOL_TYPE = Value
  val HELLO = Value(0)
  val ERROR = Value(1)
  ...
} 

will produce a map

Map("HELLO" -> 0, "ERROR" -> 1, ...)

I found a similar question: Using Scala 2.10 reflection how can I list the values of Enumeration?, but I cant grasp how to get integer id's.

Was it helpful?

Solution 2

I found a solution. The main idea is to find companion object by value type. Here is my code:

def enumObjectForType[T <: Enumeration](implicit tt: TypeTag[T]) = {
  val universeMirror = runtimeMirror(getClass.getClassLoader)
  val objModule = typeOf[T].asInstanceOf[TypeRef].pre
                           .typeSymbol
                           .companionSymbol
                           .asModule
  val companionMirror = universeMirror.reflectModule(objModule)
  companionMirror.instance
}

def enumToMap[T <: Enumeration#Value](implicit tt: TypeTag[T]) = {
  val ett = tt.asInstanceOf[TypeTag[Enumeration]]
  val instance = enumObjectForType(ett).asInstanceOf[Enumeration]
  instance.values map { v => (v.toString, v.id)} toMap
}

Usage:

object PROTOCOL_TYPE extends Enumeration{
  type PROTOCOL_TYPE = Value
  val HELLO = Value(0)
  val ERROR = Value(1)
}

import PROTOCOL_TYPE._
println(enumToMap[PROTOCOL_TYPE]) // output is Map(HELLO -> 0, ERROR -> 1)

OTHER TIPS

Try this,

def enumToMap[E <: Enumeration](e:E) = e.values.map { v => (v.toString,v.id) }.toMap

Note this approach does not use reflection.

Then

scala> enumToMap(PROTOCOL_TYPE)
res9: scala.collection.immutable.Map[String,Int] = Map(ERROR -> 1, HELLO -> 0)

Update

Another way to call enumToMap,

implicit def test[E <: Enumeration] (e:E) = new { def !() = enumToMap(e) }

Thus,

scala>  PROTOCOL_TYPE !
res4: scala.collection.immutable.Map[String,Int] = Map(ERROR -> 1, HELLO -> 0)

This syntax, ! , may be changed as desired to a more context related operator/symbol.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top