名前

2016-05-31 11 views
0

によってクラスフィールドを取得しますたとえば私の場合クラスが名前

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

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

これについてどう思いますか再考することをお勧めします。文字列"id"は実際に何が良いのですか?特定のビットのデータを取り出す機能が必要な場合は、関数を使用しないのはなぜですか?

val f: Item => Long = _.id 

関数タイプを何度も繰り返し入力する必要はありませんか?それも大丈夫です。あなたは型引数にコンパイラのヘルプ充填を要求するための方法を使用することができます。

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

今、あなたはあなたが"id"を使用しているだろうfどこでも使用することができます。 (idFまたはgetIdのように、実際にIDを取得する関数であることを思い出させるものであれば、fの代わりにidと名前を付けることもできます)