如何在Scala中使用MaxBy

时间:2017-08-22 14:44:17

标签: scala functional-programming

我有一个列表,我想将其分组,然后为每个组获取最大值。例如,用户的操作列表,获取每个用户的最后一个操作。

case class UserActions(userId: String, actionId: String, actionTime: java.sql.Timestamp) extends Ordered[UserActions] {
  def compare(that: UserActions) = this.actionTime.before(that.actionTime).compareTo(true)
}
val actions = List(UserActions("1","1",new java.sql.Timestamp(0L)),UserActions("1","1",new java.sql.Timestamp(1L)))

当我尝试以下groupBy时:

actions.groupBy(_.userId)

我收到了地图

scala.collection.immutable.Map[String,List[UserActions]] = Map(1 -> List(UserActions(1,1,1970-01-01 00:00:00.0), UserActions(1,1,1970-01-01 00:00:00.001))

哪个好,但是当我尝试添加maxBy时出现错误:

actions.groupBy(_.userId).maxBy(_._2)
<console>:13: error: diverging implicit expansion for type 
Ordering[List[UserActions]]
starting with method $conforms in object Predef
       actions.groupBy(_.userId).maxBy(_._2)

我应该改变什么?

由于 尼尔

3 个答案:

答案 0 :(得分:1)

所以你有一个Map String(userId)-> List[UserActions],你希望每个列表减少到最大元素吗?

actions.groupBy(_.userId).mapValues(_.max)
//res0: Map[String,UserActions] = Map(1 -> UserActions(1,1,1969-12-31 16:00:00.0))

您不需要maxBy(),因为您已经添加了订购/比较不同UserActions元素所需的信息。

同样,如果您只想要原始列表中的最大值。

actions.max

如果你想要通过其他参数测量的最大值,你可以使用maxBy()

actions.maxBy(_.actionId.length)

答案 1 :(得分:1)

您的compare方法应为:

def compare(that: UserActions) = this.actionTime.compareTo(that.actionTime)

然后按@jwvh显示actions.groupBy(_.userId).mapValues(_.max)

答案 2 :(得分:0)

您要使用userId对值进行分组。您可以使用groupBy()来做到这一点。

actions.groupBy(_.userId)

然后,您只能从键值对中获取值。

actions.groupBy(_.userId).values

您已使用maxBy(_._ 2)。因此,我认为您想通过比较第二个值来获得最大值。您可以使用map()来做到这一点。

actions.groupBy(_.userId).values.map(_.maxBy(_._2))