按名称获取类字段

时间:2016-05-31 15:59:17

标签: scala

例如我的案例类是

case class Test(id: String, myValues: List[Item])

case class Item(id: Long, order: Long)

我得到像

这样的字符串值
val checkValue: String = "id"

我希望按项目排序测试,我希望它看起来像

val test= Test("0", List(Item(0, 14), Item(1, 34))

val sortedItems = test.myValues.map(_.*checkValue*).sorted

关于get someInstanceOfClass.checkValue

等类的字段

2 个答案:

答案 0 :(得分:2)

Scala不是解释型语言,因此您不能只使用字符串作为变量名。解决问题的最简单方法是将字符串值映射到变量:

scala> def get(item: Items, str: String) = str match {
     |   case "id" => item.id
     |   case "order" => item.order
     | }
get: (item: Items, str: String)Long

scala> test.myValues.map(get(_, checkValue)).sorted
res0: List[Long] = List(0, 1)

scala> test.myValues.map(get(_, "order")).sorted
res1: List[Long] = List(14, 34)

当然有更多方法可以解决这个问题。您可以使用Reflection在运行时读取变量的名称。如果您在编译时已经知道要读取的变量的名称,您还可以使用宏来生成正在执行所需操作的代码。但这些都是非常专业的解决方案,我会使用如上所示的运行时匹配。

答案 1 :(得分:1)

您可能希望重新考虑如何解决这个问题。字符串"id"实际上对你有什么好处?如果您只需要提取特定数据的功能,为什么不使用函数?

val f: Item => Long = _.id

您是否不想一遍又一遍地键入功能类型?那太好了;您可以使用一种方法来请求编译器帮助填写类型参数:

def pick[A](x: Item => A) = x
val f = pick(_.id)

现在,您可以在使用f的任何地方使用"id"。 (你甚至可以将它命名为id而不是f如果这会有所帮助,或者提醒你它实际上是一个获取id的函数,而不是id本身,例如{{ 1}}或idF。)