开发者

Do I have to create a new object to mix in a Scala trait?

开发者 https://www.devze.com 2022-12-12 22:09 出处:网络
In Scala, calling groupBy() on a collection returns a Map where the values are collections, but I want a MultiMa开发者_开发百科p.What\'s the easiest way to do the conversion?Can I avoid creating a new

In Scala, calling groupBy() on a collection returns a Map where the values are collections, but I want a MultiMa开发者_开发百科p. What's the easiest way to do the conversion? Can I avoid creating a new MultiMap and copying everything over?


I think the answer to "Do I have to create a new object to mix in a Scala trait?" is "Yes". You can minimize the pain some with wrapping objects and implicit conversions.


For your specific problem, I was unable to coerce groupBy(...) to return a mutable map to mutable sets, which you would need to wrap it with "MapProxy with MultiMap". But, it is not too many lines of code to implement your own version of "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))

}

Addendum

Here is an example of wrapping an existing Map[String,Set[Int]] into a MultiMap without copying the values:

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

Note that this cannot be done on the result of groupBy(...) because the seed map is required to be mutable and groupBy(...) returns an immutable map.

0

精彩评论

暂无评论...
验证码 换一张
取 消