0

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

List[(Schedule,GameResult,Team)]

Schedule 包含一个 gameDate 属性,我需要对其进行分组以获得

Map[JodaTime, List(Schedule,GameResult,Team)]

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

val data = repo.games.findAllByDate(fooDate).groupBy(_._1.gameDate)

现在棘手的一点(对我来说)是,如何进一步细化分组以便能够通过游戏结果成对映射?澄清一下,每个 GameResult 包含一个团队的游戏“版本”(即得分、位置等),与对手团队共享一个公共的 Schedule gameID。

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

3 London Dragons vs. Paris Frogs 2

在 gameDate 上分组让我做类似的事情:

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)的旧版本中,我曾经

for($x = 0; $x < $this->gameCnt; $x = $x + 2) {...}

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

games._._2(rowCnt).total games._._3(rowCnt).name games._._1(rowCnt).location games._._2(rowCnt+1).total games._._3(rowCnt+1).name

也许 zip 或 double up for(t1 <- data; t2 <- data) yield(?) 或其他完全可以解决问题的方法。无论如何,有一个简洁的解决方案,只是现在不来找我......

4

2 回答 2

1

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

val data = repo.games.findAllByDate(fooDate).groupBy(_._1.gameDate).mapValues(_.groupBy(_._1.gameID))

你说它不正确,也许你没有正确使用它?结果中的每个 List 都是一对具有相同 GameId 的游戏。你可以这样处理 html:

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,因此您可以只返回配对游戏:

val data = repo.games.findAllByDate(fooDate).groupBy(_._1.gameDate).mapValues(_.groupBy(_._1.gameID).values)

结果提示现在是:

Map[JodaTime, Iterable[List[(Schedule,GameResult,Team)]]]

每个列表再次列出具有相同 GameId 的两个游戏

于 2012-10-19T17:26:04.477 回答
1

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

repo.games.findAllByDate(fooDate).groupBy(_._1.gameDate).mapValues(_.groupBy(_._1.gameID))

结果将是以下类型:

Map[JodaTime, Map[GameId, List[(Schedule,GameResult,Team)]]]

GameId返回类型的类型在哪里Schedule.gameId

更新:如果您希望结果成对,那么模式匹配是您的朋友,如 Arjan 所示。这会给我们:

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)))

这次结果是类型:

Map[JodaTime, Iterable[ (Schedule,(Team,GameResult),(Team,GameResult))]]

请注意,MatchError如果不完全有 2 个具有相同 gameId 的条目,这将引发 a。在实际代码中,您肯定会想要检查这种情况。

于 2012-10-19T12:49:24.017 回答