2012-10-19 37 views
0

我需要通過List[(A,B,C)]來生成html報告。具體來說,如何分組?

List[(Schedule,GameResult,Team)] 

計劃包含gameDate財產,我需要通過組上得到

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

,我用它來顯示gameDate錶行頭。很容易的:

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

現在(對我來說)棘手位,如何進一步細化分組,以便通過比賽的結果對啓用映射?爲了澄清,每個GameResult包含一個團隊的遊戲「版本」(即分數,位置等),與對手團隊共享一個共同的Schedule遊戲ID。

基本上,我需要在一排顯示遊戲結果的結果爲:

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) {...} 

但我更願意引用變量名和n OT了過來,背稍後WTF-是 - 即誘導:

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

也許ZIP或加倍彌補(T1 < - 數據;數據)收益率(?)或其他東西完全可以做到這一點。無論如何,有一個簡潔的解決方案,只是不來找我現在...

+0

爲什麼不只是做另一個組? games.groupBy(_._ 1.gameID) – Arjan

+0

因爲它不配對gameID – virtualeyes

回答

1

也許我誤解你的要求,但在我看來,所有你需要的是一個額外的GROUPBY:

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

其結果將是類型:

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

(其中GameIdSchedule.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項用相同的遊戲ID。在真實的代碼中,你一定會想要檢查這種情況。

+0

實際上不起作用,需要配對的遊戲,我用zipWithIndex砍了它 – virtualeyes

+0

然後,我建議你更新你的問題是更明確關於你需要什麼,然後發佈(並接受)你自己的答案。 –

+0

由於您首先提供了原始解決方案,因此我將再次向您提供點頭。與配對結果小組的匹配是「case List(a,b)=>」,因爲我現在正在處理案例類而不是Tuple3。斯卡拉繼續驚歎,感謝您的簡潔解決方案!順便說一句,爲了在遊戲日期保留排序,我不得不求助於ListMap和這個難以理解的後續單行程:「ListMap(repo.games.findAllByDate(fooDate).groupBy(_。schedule.gameDate).mapValues (_.groupBy(_。schedule.id).values).toList.sortBy(_._ 1.ms):_ *)「其中ms是JodaTime的getMillis的別名() – virtualeyes

1

好從雷吉斯讓吉爾斯一個soultion:

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

你說這是不正確的,也許你只是沒有使用正確的方式? 結果中的每個列表都是一對具有相同GameId的遊戲。 你可以pruduce 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))) => 
    ... 
    } 
} 

而且因爲你不需要一個遊戲ID,您可以返回剛剛配對遊戲:

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

TIPE現在是:

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

每一個名單再次一個兩個遊戲相同GameId

+0

+1,sh * t確實不錯;-)認爲groupBy在「Map [JodaDate,List [...] ]]「非常類似於數據庫查詢組,並且每個遊戲日期返回一個遊戲。不是這樣,一定是我錯誤地嘗試創建配對。 – virtualeyes

+0

現在要解決這個事實,即gameDate上的groupBy創建一個沒有保證的地圖:排序(通過gameDate再次閱讀:db查詢順序)。可以轉換爲一個ListMap。無論如何...至於配對,我會得到一個編譯器警告,但這個工作:「games.map {case(List(a,b))=> ...」來產生遊戲結果評分行(更好,IMO,比「map {x => x(0).total x(0).name ... x(1).total」) – virtualeyes