各レコードがいくつかの x 個のフィールドで構成されるレコードのリストを作成したいとしましょう。ただし、フィールドの数とフィールドの型はコンパイル時にはわかりません。実行時にのみ、フィールドの数と各フィールドの型の両方がわかります。このリストを表すために、List[Array[Any]] を使用します。
ユーザーは、特定のフィールドの最小 (最大) 値を持つこのリストからレコードを見つけることができるはずです。
以下は非常に単純化されたサンプル コードです。
class Data(val colValues: List[Array[Any]]) {
def min(i: Int): Array[Any] = {
colValues.minBy { _(i) }
}
}
ユーザーは次のように使用できるはずです。
val rawData = List(Array("a", 20, "z", "m", 3.0), Array("b", 10, "y", "f", 4.0), Array("c", 40, "z", "m", 2.0))
val d = new Data(rawData)
val m1 = d.min(1)
val m2 = d.min(4)
上記のコードは機能しません。Scalaはこのエラーを出します:
- メソッド minBy: (implicit cmp: Ordering[Any])Array[Any] の十分な引数がありません。指定されていない値のパラメーター cmp。
- Any に対して暗黙の順序付けが定義されていません。
実際、予想どおり、このリストで maxBy、sortWith、および sum などの高次メソッドを呼び出すと、Scala からエラーが発生します。
そこで、コードを次のように変更しました。
class Data(val colValues: List[Array[Any]]) {
def withType(x: Any) = x match {
case i: Int => i
case l: Long => l
case f: Float => f
case d: Double => d
}
def min(i: Int): Array[Any] = {
colValues.minBy { x:Array[Any] => withType(x(i)) }
}
}
このコードは、期待どおりにコンパイルおよび実行されます。ただし、これよりもエレガントなソリューションが必要だと思います。さらに、min メソッドが String 型のフィールドのインデックスで呼び出された場合、上記のコードは機能しません。
配列がさまざまなタイプの要素を格納し、そのタイプが実行時にのみ知られている Array[Any] の場合に、タイプの消去とタイプの安全性を処理するより良い方法はありますか?
さらに、フィールド タイプ (および番号) が実行時にのみ知られているレコードのリストを表すために、List[Array[Any]] よりも優れたデータ タイプはありますか?
ありがとうございました。