如何将Map转换为Scala中的case类?

编程入门 行业动态 更新时间:2024-10-27 18:28:02
本文介绍了如何将Map转换为Scala中的case类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

如果我有一个 Map [String,String](url - >xxx,title - >yyy)一种将其转换为案例类Image(url:String,title:String)?

If I have a Map[String,String]("url" -> "xxx", "title" -> "yyy"), is there an way to generically transform it into a case class Image(url:String, title:String)?

可以写一个帮助器:

object Image{ def fromMap(params:Map[String,String]) = Image(url=params("url"), title=params("title")) }

但是有一种方法可以一次性地将地图写入任何案例类别。

but is there a way to generically write this once for a map to any case class?

推荐答案

是一些安全的选择,你可以做,如果你只是想缩短你的代码。伴随对象可以被当作一个函数,所以你可以使用这样的东西:

First off, there are some safe alternatives you could do if you just want to shorten your code. The companion object can be treated as a function so you could use something like this:

def build2[A,B,C](m: Map[A,B], f: (B,B) => C)(k1: A, k2: A): Option[C] = for { v1 <- m.get(k1) v2 <- m.get(k2) } yield f(v1, v2) build2(m, Image)("url", "title")

这将返回一个包含结果的选项。或者,您可以使用Scalaz中的 ApplicativeBuilder ,它在内部做的几乎相同,但更好的语法:

This will return an option containing the result. Alternatively you could use the ApplicativeBuilders in Scalaz which internally do almost the same but with a nicer syntax:

import scalaz._, Scalaz._ (m.get("url") |@| m.get("title"))(Image)

如果你真的需要通过反射做这个最简单的方法是使用Paranamer(作为Lift框架)。 Paranamer可以通过检查字节码来恢复参数名称,因此存在性能损失,并且由于类加载器问题(例如REPL),它不能在所有环境中工作。如果你限制自己只有 String 构造函数参数的类,那么你可以这样做:

If you really need to do this via reflection then the easiest way would be to use Paranamer (as the Lift-Framework does). Paranamer can restore the parameter names by inspecting the bytecode so there is a performance hit and it will not work in all environments due to classloader issues (the REPL for example). If you restrict yourself to classes with only String constructor parameters then you could do it like this:

val pn = new CachingParanamer(new BytecodeReadingParanamer) def fill[T](m: Map[String,String])(implicit mf: ClassManifest[T]) = for { ctor <- mf.erasure.getDeclaredConstructors.filter(m => m.getParameterTypes.forall(classOf[String]==)).headOption parameters = pn.lookupParameterNames(ctor) } yield ctor.newInstance(parameters.map(m): _*).asInstanceOf[T] val img = fill[Image](m)

(注意,此示例可以选择一个默认构造函数,因为它不会检查您要执行的参数计数)

(Note that this example can pick a default constructor as it does not check for the parameter count which you would want to do)

更多推荐

如何将Map转换为Scala中的case类?

本文发布于:2023-07-13 03:23:26,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1099793.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:转换为   如何将   case   Map   Scala

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!