8

reduceByKey(キー、数値)ペアのコレクションを取り、キーごとに削減されたコレクションを返すという単純な関数を作成しています。

  def reduceByKey[K](collection: Traversable[Tuple2[K, Int]]) = {    
    collection
      .groupBy(_._1)
      .map { case (group: K, traversable) => traversable.reduce{(a,b) => (a._1, a._2 + b._2)} }
  }

これは現在、次の場合に機能します。

scala> val col = List((("some","key"),100), (("some","key"),100), (("some","other","key"),50))
col: List[(Product with Serializable, Int)] = List(((some,key),100), ((some,key),100), ((some,other,key),50))

scala>  reduceByKey(col)      
res42: scala.collection.immutable.Map[Product with Serializable,Int] = Map((some,key) -> 200, (some,other,key) -> 50)

しかし、数値に非 Int 型を使用したい場合、Int.

scala> val col = List((("some","key"),100.toDouble), (("some","key"),100.toDouble), (("some","other","key"),50.toDouble))
col: List[(Product with Serializable, Double)] = List(((some,key),100.0), ((some,key),100.0), ((some,other,key),50.0))

scala> reduceByKey(col)
<console>:13: error: type mismatch;
 found   : List[(Product with Serializable, Double)]
 required: Traversable[(?, Int)]
              reduceByKey(col)
                                ^

もちろん、型ごとに異なるメソッドを作成することもできますが、それはばかげています。+基本的に、メソッドが定義されている任意の型でメソッドを機能させたいと考えています。それはDoubleFloatLongIntおよびShortです。

  1. 最初は、Int の代わりに構造型を使用できると考えました。しかし、それは、構造型が何らかの用途で使用されるためには、それ自体を参照する必要があることを意味します。
  2. 役立つと思われる数値特性を調べました。すべての数値型の + メソッドをカプセル化します。ただし、私の場合の使用方法はわかりません。関数が機能するためだけに、関数のユーザーに数値で値をラップするように強制したくありません。関数自体は、どういうわけか暗黙的にそれをラップして呼び出す必要がありNumeric.plusます。

これを解決する方法として、私はどんな提案にもオープンです。

4

1 に答える 1

16

数値のみに関心がある場合は、標準Numeric型クラスを使用してこれを行うことができます。

def reduceByKey[K,V](collection: Traversable[Tuple2[K, V]])(implicit num: Numeric[V]) = {    
  import num._
  collection
    .groupBy(_._1)
    .map { case (group: K, traversable) => traversable.reduce{(a,b) => (a._1, a._2 + b._2)} }
}

暗黙的なパラメーターは、数値型でnumある証拠として機能し、この型の操作を提供します。V+

于 2013-04-12T16:00:28.890 に答える