web-dev-qa-db-fra.com

Comment puis-je convertir immutable.Map en mutable.Map dans Scala?

Comment convertir immutable.Map en mutable.Map dans Scala afin de pouvoir mettre à jour les valeurs dans Map?

79
Łukasz Lew

Le moyen le plus propre serait d’utiliser l’usine mutable.Map varargs. Contrairement à l'approche ++, cette méthode utilise le mécanisme CanBuildFrom et a donc le potentiel d'être plus efficace si le code de la bibliothèque était écrit pour tirer parti de ceci:

val m = collection.immutable.Map(1->"one",2->"Two")
val n = collection.mutable.Map(m.toSeq: _*) 

Cela fonctionne car une Map peut également être vue comme une séquence de paires.

110
Kevin Wright
val myImmutableMap = collection.immutable.Map(1->"one",2->"two")
val myMutableMap = collection.mutable.Map() ++ myImmutableMap
36
Rex Kerr

Pourquoi ne pas utiliser collection.breakOut?

import collection.{mutable, immutable, breakOut}
val myImmutableMap = immutable.Map(1->"one",2->"two")
val myMutableMap: mutable.Map[Int, String] = myImmutableMap.map(identity)(breakOut)
4
ymnk

Démarrer Scala 2.13, via les constructeurs d’usine appliqués avec .to(factory) :

Map(1 -> "a", 2 -> "b").to(collection.mutable.Map)
// collection.mutable.Map[Int,String] = HashMap(1 -> "a", 2 -> "b")
0
Xavier Guihot

Il existe une variante pour créer une variable Map mutable vide dont les valeurs par défaut sont extraites de la variable Map immuable. Vous pouvez stocker une valeur et remplacer la valeur par défaut à tout moment:

scala> import collection.immutable.{Map => IMap}
//import collection.immutable.{Map=>IMap}

scala> import collection.mutable.HashMap
//import collection.mutable.HashMap

scala> val iMap = IMap(1 -> "one", 2 -> "two")
//iMap: scala.collection.immutable.Map[Int,Java.lang.String] = Map((1,one), (2,two))

scala> val mMap = new HashMap[Int,String] {      
     | override def default(key: Int): String = iMap(key)
     | }
//mMap: scala.collection.mutable.HashMap[Int,String] = Map()

scala> mMap(1)
//res0: String = one

scala> mMap(2)
//res1: String = two

scala> mMap(3)
//Java.util.NoSuchElementException: key not found: 3
//  at scala.collection.MapLike$class.default(MapLike.scala:223)
//  at scala.collection.immutable.Map$Map2.default(Map.scala:110)
//  at scala.collection.MapLike$class.apply(MapLike.scala:134)
//  at scala.collection.immutable.Map$Map2.apply(Map.scala:110)
//  at $anon$1.default(<console>:9)
//  at $anon$1.default(<console>:8)
//  at scala.collection.MapLike$class.apply(MapLike.scala:134)....

scala> mMap(2) = "three"

scala> mMap(2)          
//res4: String = three

Avertissement (voir le commentaire de Rex Kerr): Vous ne pourrez pas supprimer les éléments provenant de la carte immuable:

scala> mMap.remove(1)
//res5: Option[String] = None

scala> mMap(1)
//res6: String = one
0
Alexander Azarov