6
在斯卡拉,在集合上調用groupBy()
返回Map
其中的值是集合,但我想要一個MultiMap
。什麼是最簡單的轉換方式?我可以避免創建一個新的MultiMap
並複製一切嗎?我是否必須創建一個新對象來混合Scala特性?
在斯卡拉,在集合上調用groupBy()
返回Map
其中的值是集合,但我想要一個MultiMap
。什麼是最簡單的轉換方式?我可以避免創建一個新的MultiMap
並複製一切嗎?我是否必須創建一個新對象來混合Scala特性?
我認爲答案是「我必須創建一個新對象來混合Scala特性嗎?」是是的」。您可以通過包裝對象和隱式轉換來減少一些痛苦。
爲了您的具體問題,我無法強迫GROUPBY(...)的可變地圖返回可變集,你需要用「MapProxy與多重映射」來包裝它。但是,這是不是代碼太多行實現自己的「GROUPBY」的版本:
package blevins.example
object App extends Application {
implicit def multiMapable[B](c: Iterable[B]) = new {
def groupByMM[A](f: B => A) = {
import scala.collection.mutable._
val ret = new HashMap[A,Set[B]] with MultiMap[A,B]
for (e <- c) { ret.addBinding(f(e), e) }
ret
}
}
val c = List(1,2,3,4,5,6,7,8,9)
val mm = c.groupByMM { i => if (i < 5) "alpha" else "beta" }
mm.addBinding("alpha",12)
println(mm) // Map(beta -> Set(5, 7, 6, 9, 8), alpha -> Set(3, 1, 4, 2, 12))
}
附錄
這裏被包裝現有地圖[字符串,設置的例子[INT]]成多重映射而不復制值:
object App extends Application {
import scala.collection.mutable._
val seed: Map[String,Set[Int]] = Map("even" -> Set(2,4,6), "odd" -> Set(1,3,5))
val multiMap = new MapProxy[String,Set[Int]] with MultiMap[String,Int] {
val self = seed
}
multiMap.addBinding("even", 8)
println(multiMap) // Map(odd -> Set(5, 3, 1), even -> Set(6, 8, 4, 2))
}
注意,這不能在GROUPBY的結果(...),因爲種子地圖需要到b來完成e mutable和groupBy(...)返回一個不可變的映射。
調用groupBy()和一個可變集合確實會返回一個mutable.Map。 – 2009-11-29 15:48:44
你能證明groupBy返回一個可變的Map嗎?我收到如下所示的編譯器錯誤(http://gist.github.com/245062)。 – 2009-11-29 20:56:01
我想它會返回一個可變集的不可變映射嗎?無論如何,我根本不需要地圖,我想要一個多地圖。 – 2009-12-09 20:22:29