Reputation: 11237
Going a bit nutty here trying to multi-sort on the following.
case class WeeklyResults(
schedule: Schedule,
result: GameResult
)
val games = // returns correctly sorted List of WeeklyResults
repo.gameresult.findAllByDate(date)
Things go awry when I groupBy on game date (to display game date header per game day) and id (to group home/away team pairs) as an unsorted map is returned, fun ;-)
val unsorted = // Map[JodaTime, Iterable[List[WeeklyResults]]]
games.groupBy(_.schedule.gameDate).mapValues(_.groupBy(_.schedule.id).values)
Ok, well, ListMap is one way to get a sorted map, let's try that, sorting on game date JodaTime in milliseconds.
val sorted =
ListMap(unsorted.toList.sortBy(_._1.getMillis):_*)
All good, games are sorted under game date headers in correct order...but, the games within each game day are sorted at random ;-(
So, the question is, how on earth can I sort both by game date and game result id? (where id is PK of game results table, effectively the sort order at DB level)
I have tried various combinations of futility:
unsorted.flatMap{x=>
ListMap(
Seq( (x._1, x._2.map(_._2.sortBy(_.result.id))) ).sortBy(_.1.getMillis)
:_*)
}
No matter what I do, the Iterable[List[WeeklyResults]]
remains unsorted
Ideas greatly appreciated, am at my wits end, entire morning gone on this
Upvotes: 2
Views: 1716
Reputation: 475
I think the key problem is that your groupBy inside a groupBy returns a complex type (Iterable over List).
If I simplify that part using 'flatten', things become much simpler. I've used a dumbed-down version of your case class
case class WeeklyResults(
schedule: DateTime,
id: Int
)
and then used the following:
val unsorted = // Map[JodaTime, List[WeeklyResults]]
games.groupBy(_.schedule).mapValues(_.groupBy(_.id).values.flatten.toList)
sorted just like you did (cool trick with the ListMap, by the way):
val sorted = //ListMap[DateTime, List[WeeklyResults] ]
ListMap(unsorted.toList.sortBy(_._1.getMillis):_*)
and then the secondary sort is just:
val reallySorted = sorted.mapValues( v => v.sortBy( _.id) )
I hope that helps.
Upvotes: 2
Reputation: 11237
This is heinously bad, but not sure how else to approach the problem without restructuring the model.
So, I pass in the semi-sorted ListMap (i.e. sorted on game date) to the view:
@(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
...
}
}
Basically, since each gameresult is a List'd pair, I sort on the first game result id in the pair (could do on the 2nd just as well, same game id, different game result/outcome for each team).
This works, but is really painful given that the original database query returns the result set in desired order. Spent about 3 hours hashing through this, interesting but...a total waste of the little time I have available right now. Would ABSOLUTELY LOVE a groupBy that preserved collection order.
If someone has a "real" solution vs. the hacked one I've come up with, please do chime in...
Upvotes: 0