開發中遇到需求:合並兩個Map集合對象(將兩個對應KEY的值累加)
先說解決方案:
( map1 /: map2 ) { case (map, (k,v)) => map + ( k -> (v + map.getOrElse(k, 0)) ) }
這特么什么鬼 (╯‵□′)╯""┻━┻☆))>○<) 。。。。。。莫急,且聽我慢慢道來。。。。。。。。。
首先:
Scala中現有的合並集合操作不能滿足這個需求 。
注意合並后的結果a的G02的值其實是被覆蓋掉了。。
然后:
說說那個表達式中(a /: b)( ... ) 這部分是什么鬼。這個其實是scala簡化的foldLeft函數。
先看foldLeft
List(1,2,3).foldLeft(0)((sum,i)=>sum+i) // 紅色部分是初始值,藍色部分是操作函數
List(1,2,3).foldLeft(0)((sum,i)=>sum+i) 可以寫成 (List(1,2,3) foldLeft 0)((sum,i)=>sum+i) 語法糖 (0 /: List(1,2,3))(_+_)
操作符設計者的腦洞也是夠了 - - 開發者絕對是表情帝
如果接受了這個設定。。。foldRight也可以腦補出來。。 一定是 ((1 to 5) :\ 100)((i,sum)=> sum-i) .......
另外。一個例子說明 foldLeft 和 foldRight:
最后:
來說說操作函數中的case ,這個鬼叫模式匹配 (哦對,模式匹配的時候是要有個大括號包起來的 所以最終結果的操作函數使用大括號包着。)
Map的折疊函數是依次傳入Map的鍵值對。所以操作函數希望傳入的操作數可以是(K,V)形式。。於是用case表達式:(map, (k,v))
具體模式匹配是什么。。簡單說就是scala會嘗試將傳入的值匹配到case后面表達式的樣子(當然這里一定會匹配上,所以沒有寫case的多余分支)具體什么是“模式匹配”,目前理解尚淺此處暫不深入妄加揣測。
壹 Try 勝千言 :
參考
1) http://stackoverflow.com/questions/7076128/best-way-to-merge-two-maps-and-sum-the-values-of-same-key
2) http://blog.csdn.net/wsscy2004/article/details/37698013
3) http://my.oschina.net/sulliy/blog/58266