2016-05-06 5 views
2

私は、同じタイプのケースオブジェクトのリストを持っています。特定のタイプのオブジェクトからマップを生成しますか?

object Countries { 
    sealed abstract class Country (val name: String) 
    case object SE extends Country("Sweden") 
    case object AE extends Country("United Arab Emirates") 
    case object GB extends Country("United Kingdom") 
    case object US extends Country("United States of America") 
} 

ここで、このようなマッピングを作成します。

val map = Map[String, Country](

     CH.name -> CH, 
     AE.name -> AE, 
     GB.name -> GB, 
     US.name -> US 

     ) 

私はこれを行うことができます。 Stringキーを渡して、適切なcaseオブジェクトへの参照を取得します。

val us = Countries.map.get("United Kingdom") 

mapを自動的に生成する方法はありますか?

+0

関連 - http://underscore.io/blog/posts/2014/09/03/enumerations.html –

答えて

2
object ReflectUtils { 
    import scala.reflect.runtime.universe.{TypeTag, typeOf} 

    def knownDirectSubclassesAsMap[T: TypeTag](keyGenerator: T => String): Map[String, T] = 
    typeOf[T].typeSymbol.asClass.knownDirectSubclasses.map { c => 
     reflect.runtime.currentMirror.reflectModule(c.owner.typeSignature.member(c.name.toTermName).asModule).instance 
    }.asInstanceOf[Set[T]].map(obj => keyGenerator(obj) -> obj).toMap 
} 

、その後:

object Countries { 
    sealed abstract class Country(val name: String) 
    case object SE extends Country("Sweden") 
    case object AE extends Country("United Arab Emirates") 
    case object GB extends Country("United Kingdom") 
    case object US extends Country("United States of America") 

    lazy val countriesByName = ReflectUtils.knownDirectSubclassesAsMap[Country](_.name) 
    def forName = countriesByName.apply _ 
} 

E。 g。 Countries.forName("United States of America")Countries.USオブジェクトを返します。

+0

重複しています - これは正しい実行時の解決策ですか? – JamieP

+0

@JamiePはい、実行時の解決策です。 – TeWu

関連する問題