2016-05-31 12 views
0

Zum Beispiel mein Fall Klasse istGet Klasse Felder nach Namen

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

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

und ich Stringwert erhalten wie

val checkValue: String = "id" 

ich von Artikel sortieren Tests wollen und ich möchte es wie

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

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

Es ist über Feld der Klasse wie someInstanceOfClass.checkValue

erhalten

Antwort

2

Scala ist keine interpretierte Sprache, daher können Sie nicht einfach Strings als Variablennamen verwenden. Der einfachste Weg, um Ihr Problem zu lösen, ist der Zeichenfolge Wert auf die Variable zur Karte:

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) 

Natürlich gibt es mehr Möglichkeiten, das Problem zu lösen. Sie können Reflection verwenden, um den Namen der Variablen zur Laufzeit zu lesen. Wenn Sie zum Zeitpunkt der Kompilierung bereits den Namen der Variablen kennen, die Sie lesen möchten, könnten Sie auch Makros verwenden, um den Code zu generieren, der das tut, was Sie wollen. Aber das sind beides sehr spezielle Lösungen, ich würde mit dem Runtime-Matching gehen, wie oben gezeigt.

1

Vielleicht möchten Sie darüber nachdenken, wie Sie vorgehen. Was nützt dir die Schnur "id" eigentlich? Wenn Sie nur die Fähigkeit benötigen, ein bestimmtes Datenbit zu extrahieren, warum nicht eine Funktion verwenden?

val f: Item => Long = _.id 

Möchten Sie den Funktionstyp nicht immer wieder eingeben? Das ist auch in Ordnung; Sie können eine Methode verwenden, die Compiler-Hilfe-Füllung in den Typargumente zu beantragen:

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

Jetzt können Sie f überall benutzen Sie "id" verwendet hätte. (Sie können es sogar id anstelle von f nennen, wenn das hilft, oder etwas, das Sie daran erinnert, dass es tatsächlich eine Funktion ist, die eine ID erhält, keine ID selbst, wie idF oder getId.)