Muss ich ein neues Objekt erzeugen in einer Scala Charakterzug zu mischen?
Frage
In Scala, ruft groupBy()
auf einer Sammlung gibt einen Map
, wo die Werte Sammlungen sind, aber ich möchte ein MultiMap
. Was ist der einfachste Weg, um die Konvertierung zu tun? Kann ich vermeiden, dass eine neue MultiMap
Erstellen und Kopieren alles vorbei?
Lösung
Ich denke, die Antwort auf „Brauche ich ein neues Objekt erstellen habe in einer Scala Charakterzug zu mischen?“ ist ja". Sie können die Schmerzen minimieren einige mit Objekten und implizite Konvertierungen Einwickeln.
Für Ihr spezielles Problem, ich war nicht in der Lage groupBy (...) zu zwingen, eine veränderbare Karte zu wandelbar Sätze zurück, die Sie brauchen, wäre es zu wickeln mit „MapProxy mit MultiMap“. Aber es ist nicht zu viele Zeilen Code Ihre eigene Version von „groupBy“ zu implementieren:
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))
}
Nachtrag
Hier ist ein Beispiel für Umwickeln eines vorhandenen Map [String, Set [Int]] in ein MultiMap, ohne die Werte zu kopieren:
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))
}
Beachten Sie, dass dies nicht auf dem Ergebnis der groupBy (...), weil die Samen Karte erforderlich ist, getan werden, um seine wandelbar und groupBy (...) gibt eine unveränderliche Karte.