Map.++
is defined as:
override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): immutable.Map[A, B1] =
((repr: immutable.Map[A, B1]) /: xs.seq) (_ + _)
donde repr
es su mapa actual y xs.seq
le da una secuencia de los pares/asignaciones almacenados en el mapa que se pasa a ++
.
Map./:
is described as:
def /:[B](z: B)(op: (B, (A, B)) ⇒ B): B
Applies a binary operator to a start value and all elements of this
immutable map, going left to right.
Note: /: is alternate syntax for foldLeft;
z /: xs is the same as xs foldLeft z.
Tenga en cuenta que no se especifica qué "de izquierda a derecha" significa para un mapa desordenada.
El siguiente ejemplo ilustra lo que sucede detrás de la escena por reimplementar ++
y aumentando con depuración println
declaraciones:
val m1 = Map(1 -> "A", 2 -> "B", 3 -> "C")
val m2 = Map(2 -> "X", 3 -> "Y", 4 -> "Z")
println(m1.repr)
/* Map(1 -> A, 2 -> B, 3 -> C) */
println(m1.repr.getClass.getName)
/* scala.collection.immutable.Map$Map3 */
def ++[K, V](ts: Map[K, V], xs: Map[K, V]): Map[K, V] =
(ts /: xs) {case (acc, entry) =>
println("acc = " + acc)
println("entry = " + entry)
acc + entry
}
val m3 = ++(m1, m2)
/*
acc = Map(1 -> A, 2 -> B, 3 -> C)
entry = (2,X)
acc = Map(1 -> A, 2 -> X, 3 -> C)
entry = (3,Y)
acc = Map(1 -> A, 2 -> X, 3 -> Y)
entry = (4,Z)
*/
println(m3)
/* Map(1 -> A, 2 -> X, 3 -> Y, 4 -> Z) */
Gracias. Si también puede decirme por qué (o dar una referencia donde se define la regla), obtendrá la respuesta aceptada. :-) –
En la mayoría de los casos, la implementación de '++' se basa en '+', que a su vez se basa en 'updated' y en [this] (http://www.scala-lang.org/api/current /scala/collection/immutable/Map.html) scaladoc se afirma que 'updated' devuelve un nuevo mapa inmutable actualizado con los nuevos valores. Sí, lo sé, no es una prueba absoluta, por lo que probablemente no deberías cerrar esta pregunta aún y esperar una mejor referencia. Sin embargo, la referencia de "Mapa de Java" es bull $ hit. –