【问题标题】:Scala reduceByKey function - use any type that has + methodScala reduceByKey 函数 - 使用任何具有 + 方法的类型
【发布时间】:2013-04-05 05:14:26
【问题描述】:

我正在编写一个名为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)
                                ^

当然,我可以为不同的类型制定不同的方法,但这很愚蠢。基本上我希望我的方法适用于定义了+ 方法的任何类型。那将是Double、Float、Long、Int 和 Short。

  1. 起初,我认为我可以使用结构类型而不是 Int。但这意味着结构类型需要引用自身才能发挥作用。
  2. 我研究了我认为可能有用的Numeric trait。它封装了所有数字类型的 + 方法。但是,我不确定如何在我的情况下使用它。我不想强迫我的函数的用户将值包装在 Numeric 中,只是为了让我的函数正常工作。函数本身应该以某种方式隐式包装并调用Numeric.plus。

我愿意接受有关如何解决此问题的任何建议。

【问题讨论】:

  • 这是一个答案,但如此简洁以至于不值得这样提出:使用类型类。其他人可能会尽快提供详细信息。如果没有,我会争取时间。

标签: scala


【解决方案1】:

如果您只对数值感兴趣,可以使用标准的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 是数字类型的证据,并为该类型提供+ 操作。

【讨论】:

    猜你喜欢
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    • 2018-08-30
    相关资源
    最近更新 更多