2009-11-27 49 views

回答

5

我认为答案是“我必须创建一个新对象来混合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(...)返回一个不可变的映射。

+0

调用groupBy()和一个可变集合确实会返回一个mutable.Map。 – 2009-11-29 15:48:44

+0

你能证明groupBy返回一个可变的Map吗?我收到如下所示的编译器错误(http://gist.github.com/245062)。 – 2009-11-29 20:56:01

+0

我想它会返回一个可变集的不可变映射吗?无论如何,我根本不需要地图,我想要一个多地图。 – 2009-12-09 20:22:29

相关问题