user3771345 user3771345 - 3 months ago 6
Scala Question

top value from each group in scala

I have an array of id and scores and I want to find top score for each id.

(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)


and the required output is as fallows

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


I have tried

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


but it gives me

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


and adding reverse as fallows

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


gives

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


I have been able to get the required output by using sort twice and reverse. But I think it would be possible in a more cleaner way. Any suggestions would be appreciated.

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

or

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