使用多种排序映射groupBy

时间:2012-12-02 15:09:17

标签: scala map group-by sorted

在这里尝试对以下内容进行多重排序时,有点疯狂。

case class WeeklyResults(
  schedule: Schedule,
  result: GameResult
)
val games = // returns correctly sorted List of WeeklyResults
  repo.gameresult.findAllByDate(date)

当我在游戏日期上分组(显示每个游戏日的游戏日期标题)和id(分组主页/远离团队对)时会出现错误,因为返回了未排序的地图,很有趣; - )

val unsorted = // Map[JodaTime, Iterable[List[WeeklyResults]]]
  games.groupBy(_.schedule.gameDate).mapValues(_.groupBy(_.schedule.id).values)

好吧,ListMap是一种获取有序地图的方法,让我们试试吧,在游戏日期JodaTime上进行排序,以毫秒为单位。

val sorted =
  ListMap(unsorted.toList.sortBy(_._1.getMillis):_*)

所有优秀的游戏都以正确的顺序排列在游戏日期标题下...但是,每个游戏日内的游戏都是随机排序的; - (

所以,问题是,我怎样才能按游戏日期和游戏结果ID 对进行排序? (其中id是游戏结果表的PK,实际上是DB级别的排序顺序)

我尝试了各种无用的组合:

unsorted.flatMap{x=>
  ListMap(
    Seq( (x._1, x._2.map(_._2.sortBy(_.result.id))) ).sortBy(_.1.getMillis)
  :_*)
}

无论我做什么,Iterable[List[WeeklyResults]]都保持未分类

我非常感激,我的智慧结束了,整个上午都在这个

2 个答案:

答案 0 :(得分:2)

我认为关键问题是你的groupBy在groupBy中返回一个复杂的类型(Iterable over List)。

如果我使用'flatten'简化那部分,事情会变得简单得多。我使用了你的案例类的简化版本

case class WeeklyResults(
  schedule: DateTime,
  id: Int
)

然后使用以下内容:

val unsorted = // Map[JodaTime, List[WeeklyResults]]
    games.groupBy(_.schedule).mapValues(_.groupBy(_.id).values.flatten.toList)

就像你一样排序(顺便说一下,ListMap的酷炫技巧):

val sorted = //ListMap[DateTime, List[WeeklyResults] ]
    ListMap(unsorted.toList.sortBy(_._1.getMillis):_*)

然后辅助排序只是:

val reallySorted = sorted.mapValues( v => v.sortBy( _.id) )

我希望有所帮助。

答案 1 :(得分:0)

这非常糟糕,但不确定如何在不重组模型的情况下解决问题。

因此,我将半分类的ListMap(即按游戏日期排序)传递给视图:

@(model: Map[org.joda.time.DateTime, Iterable[List[ushr.model.WeeklyResults]]])

@model.map{ case(date,games) =>
  // display game date headers
  ...

  // the ugliness ensues
  @games.toSeq.map(x=>x).sortBy(_(0).result.id).map{ case(List(a,b))=>
    // display game results on this particular game date
    ...
  }
}

基本上,由于每个游戏结果都是List'd对,我对该对中的第一个游戏结果id进行排序(也可以在第2个游戏结果中进行,同样的游戏ID,每个团队的不同游戏结果/结果)。

这很有效,但由于原始数据库查询以所需顺序返回结果集,因此非常痛苦。花了大约3个小时来完成这个,有趣但是......完全浪费了我现在可用的那些时间。绝对会喜欢一个保留收集顺序的groupBy。

如果某人有一个“真正的”解决方案,而不是我提出的被黑客攻击的解决方案,请在...中加入...