首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何groupBy groupBy?

如何groupBy groupBy?
EN

Stack Overflow用户
提问于 2012-10-19 20:32:17
回答 2查看 661关注 0票数 0

我需要通过List[(A,B,C)]映射来生成html报告。具体地说,一个

代码语言:javascript
复制
List[(Schedule,GameResult,Team)]

Schedule包含一个gameDate属性,我需要按该属性进行分组才能获得

代码语言:javascript
复制
Map[JodaTime, List(Schedule,GameResult,Team)]

我用它来显示gameDate表行标题。很简单:

代码语言:javascript
复制
val data = repo.games.findAllByDate(fooDate).groupBy(_._1.gameDate)

现在棘手的一点(对我来说)是,如何进一步优化分组,以便在游戏结果中实现成对映射?为了澄清,每个GameResult由一个团队的“版本”游戏(即得分,位置等)组成,与对手团队共享一个共同的时间表gameID。

基本上,我需要在一行上显示游戏结果如下:

代码语言:javascript
复制
3 London Dragons vs. Paris Frogs 2

在gameDate上分组让我这样做:

代码语言:javascript
复制
data.map{case(date,games) =>
  // game date row headers
  <tr><td>{date.toString("MMMM dd, yyyy")}</td></tr>

  // print out game result data rows
  games.map{case(schedule,result, team)=>
    ...
    // BUT (result,team) slice is ungrouped, need grouped by Schedule gameID
  }
}

在旧版本的现有应用程序(PHP)中,我习惯于

代码语言:javascript
复制
for($x = 0; $x < $this->gameCnt; $x = $x + 2) {...}

但我更喜欢引用变量名,而不是后来居上的wtf-is-inducing:

代码语言:javascript
复制
games._._2(rowCnt).total games._._3(rowCnt).name games._._1(rowCnt).location games._._2(rowCnt+1).total games._._3(rowCnt+1).name

可能压缩或加倍(t1 <- data;t2 <- data)输出(?)或者其他完全不同的东西也能解决这个问题。无论如何,有一个简洁的解决方案,只是现在不会出现在我面前...

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-19 20:49:24

也许我误解了您的要求,但在我看来,您需要的只是一个额外的groupBy:

代码语言:javascript
复制
repo.games.findAllByDate(fooDate).groupBy(_._1.gameDate).mapValues(_.groupBy(_._1.gameID))

结果的类型为:

代码语言:javascript
复制
Map[JodaTime, Map[GameId, List[(Schedule,GameResult,Team)]]]

(其中GameIdSchedule.gameId的返回类型的类型)

如果你想要成对的结果,那么模式匹配就是你的朋友,如Arjan所示。这将为我们提供:

代码语言:javascript
复制
val byDate = repo.games.findAllByDate(fooDate).groupBy(_._1.gameDate)
val data = byDate.mapValues(_.groupBy(_._1.gameID).mapValues{ case List((sa, ra, ta), (sb, rb, tb)) => (sa, (ta, ra), (tb, rb)))

这次的结果是这样的:

代码语言:javascript
复制
Map[JodaTime, Iterable[ (Schedule,(Team,GameResult),(Team,GameResult))]]

请注意,如果没有2个条目具有相同的gameId,这将抛出MatchError。在实际的代码中,你肯定会想要检查这种情况。

票数 1
EN

Stack Overflow用户

发布于 2012-10-20 01:26:04

好的,来自Régis Jean-Gilles的灵魂:

代码语言:javascript
复制
val data = repo.games.findAllByDate(fooDate).groupBy(_._1.gameDate).mapValues(_.groupBy(_._1.gameID))

你说它不正确,也许你只是没有正确地使用它?结果中的每个列表都是一对具有相同GameId的游戏。你可以像这样修改html:

代码语言:javascript
复制
data.map{case(date,games) =>
  // game date row headers
  <tr><td>{date.toString("MMMM dd, yyyy")}</td></tr>

  // print out game result data rows
  games.map{case (gameId, List((schedule, result, team), (schedule, result, team))) =>
    ...
  }
}

因为你不需要gameId,所以你可以只返回成对的游戏:

代码语言:javascript
复制
val data = repo.games.findAllByDate(fooDate).groupBy(_._1.gameDate).mapValues(_.groupBy(_._1.gameID).values)

结果的类型现在是:

代码语言:javascript
复制
Map[JodaTime, Iterable[List[(Schedule,GameResult,Team)]]]

每个列表又是一对具有相同GameId的两个游戏

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12974369

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档