scala中每个组的最高值

时间:2016-09-05 11:30:42

标签: scala sorting grouping

我有一系列的id和分数,我想找到每个id的最高分。

val idAndScore = Array(
    ("10022 10021", -6.1825),
    ("10022 10021", -6.477912),
    ("10022 10021", -7.207875),
    ("10022 10021", -6.251606),
    ("10022 10021", -6.343815),
    ("10022 10021", -6.62864),
    ("29920 29919", -9.134842),
    ("29920 29919", -9.049803),
    ("29920 29919", -9.658904),
    ("29920 29919", -9.186851),
    ("29920 29919", -8.525129),
    ("29920 29919", -9.46663),
    ("29920 29919", -8.496784),
    ("29920 29919", -9.2584),
    ("29946 29945", -10.010943),
    ("29946 29945", -8.588902),
    ("29946 29945", -8.915169),
    ("29946 29945", -8.538752)
)

并且所需的输出为休闲

(10022 10021,-6.1825)
(29920 29919,-8.496784)
(29946 29945,-8.538752)

我试过了

val top = idAndScore.groupBy { case (id, score) => id }
.flatMap(_._2.toList.sortBy { case (id, score) => score })

但它给了我

(29946 29945,-8.538752)
(29920 29919,-8.496784)
(10022 10021,-6.1825)

并添加反向作为休闲

val top = idAndScore.groupBy { case (id, score) => id }
.flatMap(_._2.toList.sortBy { case (id, score) => score }.reverse)

给出

(29946 29945,-10.010943)
(29920 29919,-9.658904)
(10022 10021,-7.207875)

我已经能够通过使用sort两次并反向获得所需的输出。但我认为有可能以更清洁的方式。任何建议将不胜感激。

2 个答案:

答案 0 :(得分:1)

idAndScore.groupBy(_._1).mapValues(_.max).map(_._2).toList.sortBy(- _._2)

idAndScore.groupBy(_._1).mapValues(_.max).map(_._2).toList.sortBy { case (k, v) => -v }

答案 1 :(得分:1)

可能更高效的版本,因为它只保留最大值,而不是值列表,以便以后获取最大值。

idAndScore.foldLeft(Map[String, Double]() withDefaultValue Double.MinValue)
                   { case (m, (k, v)) => m updated (k, v max m(k))}
          .toSeq
          .sortBy{-_._2}

// Seq[(String, Double)] = ArrayBuffer((10022 10021,-6.1825),
                                       (29920 29919,-8.496784),
                                       (29946 29945,-8.538752))