Scala的新功能,比reduceLeft更好/惯用的方式来查找集合中的max(key,val)?

时间:2017-04-07 04:47:49

标签: scala

Scala的新功能...我试图从(键,值)对的集合中找到最佳匹配,其中最佳匹配被定义为最高频率。 reduceLeft方法是理想的,但是集合大小可能小于2(1或0),因此小集合的明确定义的行为是好的。

是否有更惯用的scala方法来寻找最大值? 其他消息来源解释了reduceLeft,它有意义并且读取得很好,但其他方法提出了不同的方法。

有没有更好的方法从size = 1的集合中提取单个项?

假设我的地图有一些未知数量的值,     米:地图[字符串,INT]

val vm = m.filterNot{ case (k,v) => k.equals("ignore") }
val size = vm.size

val best = if(size>1) {
  val list = vm.map{ case (k,v) => KeyCount(k,v) }
  list.reduceLeft( maxKey )
} else if(size == 1) {
  vm.toList(0)
  //another source has suggested vm.head as an alternative
} else {
  KeyCount("default",0)
}

将KeyCount和maxKey声明为,

case class KeyCount( key:String, count:Long ) {
  def max( a:KeyCount, z:KeyCount ) = { if( a.count>z.count) a else z; }
  def min( a:KeyCount, d2:KeyCount ) = { if( a.count<z.count) a else z; }
}

val maxKey = (x:KeyCount, y:KeyCount) => if( x.count > y.count ) x else y;

1 个答案:

答案 0 :(得分:1)

reduceLeft适用于大小为1的列表。如果count始终大于0,则可以使用默认大小写的foldLeft

val list = vm.map{ case (k,v) => KeyCount(k,v) }
val best = list.foldLeft(KeyCount("default",0))(maxKey)

否则只需使用maxByreduceLeft

的条件
val best = if(size>0) {
  val list = vm.map{ case (k,v) => KeyCount(k,v) }
  list.maxBy(_.count)
} else {
  KeyCount("default",0)
}

请注意,您可以在原始maxBy上使用Map[String, Int],而无需将元素转换为KeyCount