在 Scala 中将嵌套案例类转换为嵌套映射 [英] Convert Nested Case Classes to Nested Maps in Scala

查看:56
本文介绍了在 Scala 中将嵌套案例类转换为嵌套映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个嵌套的案例类:

I have two nested case classes:

case class InnerClass(param1: String, param2: String)
case class OuterClass(myInt: Int, myInner: InnerClass)
val x = OuterClass(11, InnerClass("hello", "world"))

我想将其转换为 Map[String,Any] 类型的嵌套 Map,以便得到如下结果:

Which I want to convert to nested Maps of type Map[String,Any] so that I get something like this:

Map(myInt -> 11, myInner -> Map(param1 -> hello, param2 -> world))

当然,解决方案应该是通用的并且适用于任何案例类.

Of course, the solution should be generic and work for any case class.

注意:本次讨论就如何将单个案例类映射到地图.但我无法将其适应嵌套的案例类.相反,我得到:

Note: This discussion gave a good answer on how to map a single case class to a Map. But I couldn't adapt it to nested case classes. Instead I get:

Map(myInt -> 11, myInner -> InnerClass(hello,world)

推荐答案

正如 Luigi Plinge 在上面的评论中指出的那样,这是一个非常糟糕的主意——你将类型安全抛到了窗外,并且会被很多丑陋的强制转换和运行时错误.

As Luigi Plinge notes in a comment above, this is a very bad idea—you're throwing type safety out the window and will be stuck with a lot of ugly casts and runtime errors.

也就是说,使用新的 Scala 2.10 反射 API:

That said, it's pretty easy to do what you want with the new Scala 2.10 Reflection API:

def anyToMap[A: scala.reflect.runtime.universe.TypeTag](a: A) = {
  import scala.reflect.runtime.universe._

  val mirror = runtimeMirror(a.getClass.getClassLoader)

  def a2m(x: Any, t: Type): Any = {
    val xm = mirror reflect x

    val members = t.declarations.collect {
      case acc: MethodSymbol if acc.isCaseAccessor =>
        acc.name.decoded -> a2m((xm reflectMethod acc)(), acc.typeSignature)
    }.toMap

    if (members.isEmpty) x else members
  }

  a2m(a, typeOf[A])
}

然后:

scala> println(anyToMap(x))
Map(myInt -> 11, myInner -> Map(param1 -> hello, param2 -> world))

尽管如此,请不要这样做.事实上,您应该尽最大努力在 Scala 中完全避免运行时反射——这几乎从来没有必要.我发布这个答案只是因为如果您决定必须使用运行时反射,那么使用 Scala 反射 API 比使用 Java 更好.

Do not do this, though. In fact you should do your absolute best to avoid runtime reflection altogether in Scala—it's really almost never necessary. I'm only posting this answer because if you do decide that you must use runtime reflection, you're better off using the Scala Reflection API than Java's.

这篇关于在 Scala 中将嵌套案例类转换为嵌套映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆