0

各レコードがいくつかの 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]] よりも優れたデータ タイプはありますか?

ありがとうございました。

4

1 に答える 1

2

Orderingここでの問題は、暗黙のスコープに正しいインスタンスがないことです。存在しない理由はOrdering[Any]無意味です。そのようなインスタンスがあったとしても、それはどのような目的に役立つのでしょうか?Stringとを比較することは何を意味するのIntでしょうか? それともObjectList?順序付けを行うことはできますが、タイプの何かについて興味深いものを取得する方法がないため、役に立ちませんAny。目的を達成するための複雑な方法がいくつかありますが、これは設計上の問題を示しているようです。アプローチを再考することをお勧めします。

于 2013-04-30T19:35:32.807 に答える