获取许多用户的最近位置
Get the most recent location of many users
我相信一定有更好的方法来问这个问题,但我想不出。
考虑这个案例class:
case class UserLocation(id: Int, dateTime: DateTime, lat: Double, lon: Double)
我有一个 List[UserLocation]
包含所有用户所有位置的历史记录,我想过滤此列表以仅包含每个用户的最新位置。
我是这样做的:
implicit def dateTimeOrdering: Ordering[DateTime] = Ordering.fromLessThan(_ isAfter _)
val locations: List[UserLocation] = bigListOfUserLocations()
val groupedById = locations.groupBy(_.id)
val sortedByDate = groupedById.map(_._2.sortBy(_.dateTime))
val finalList = sortedByDate.map(_.head)
这行得通,但我想知道是否有更好的方法来做到这一点,提高性能and/or可读性
重要提示:这主要是一个学术问题,我想知道在操作列表时实现这一点的最有效或最惯用的方法,所以建议像 "try xyz on the database before you receive the list" 不会有帮助
你基本上已经完成了,但是你可以通过以下方式将最后两个操作减少到一个:
val finalList = groupedById.map(_._2.maxBy(_.dateTime))
这更具可读性,也更高效,因为您只需找到组中最大的项,而无需按顺序排列其余项。
已经说过了,这里就不用排序了。
我的解决方案不会提高可读性,但会稍微提高性能(尽管它仍然是 O(n)
),因为它不会存储用户的所有位置,而是存储最近的位置,一次通过列表:
locations
.foldLeft(mutable.Map.empty[Int, UserLocation]) {
case (acc, loc)
if !acc.contains(loc.id) ||
acc(loc.id).dateTime < loc.dateTime => acc.updated(loc.id, loc)
case (acc, _) => acc
}.map(_._2)
我相信一定有更好的方法来问这个问题,但我想不出。
考虑这个案例class:
case class UserLocation(id: Int, dateTime: DateTime, lat: Double, lon: Double)
我有一个 List[UserLocation]
包含所有用户所有位置的历史记录,我想过滤此列表以仅包含每个用户的最新位置。
我是这样做的:
implicit def dateTimeOrdering: Ordering[DateTime] = Ordering.fromLessThan(_ isAfter _)
val locations: List[UserLocation] = bigListOfUserLocations()
val groupedById = locations.groupBy(_.id)
val sortedByDate = groupedById.map(_._2.sortBy(_.dateTime))
val finalList = sortedByDate.map(_.head)
这行得通,但我想知道是否有更好的方法来做到这一点,提高性能and/or可读性
重要提示:这主要是一个学术问题,我想知道在操作列表时实现这一点的最有效或最惯用的方法,所以建议像 "try xyz on the database before you receive the list" 不会有帮助
你基本上已经完成了,但是你可以通过以下方式将最后两个操作减少到一个:
val finalList = groupedById.map(_._2.maxBy(_.dateTime))
这更具可读性,也更高效,因为您只需找到组中最大的项,而无需按顺序排列其余项。
O(n)
),因为它不会存储用户的所有位置,而是存储最近的位置,一次通过列表:
locations
.foldLeft(mutable.Map.empty[Int, UserLocation]) {
case (acc, loc)
if !acc.contains(loc.id) ||
acc(loc.id).dateTime < loc.dateTime => acc.updated(loc.id, loc)
case (acc, _) => acc
}.map(_._2)