user445107
user445107

Reputation:

How to avoid the strange order in which maps are concatenated? (A++B++C ---> BAC)

Concatenating three maps a, b and c, I would expect the result to be in the same order as its respective original maps. But, as shown below, the result is like the maps were b, a and c:

  Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
  Type in expressions to have them evaluated.
     Type :help for more information.

  scala> import collection.mutable
  import collection.mutable

  scala> val a = mutable.Map(1->2)
  a: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2)

  scala> val b = mutable.Map(2->2)
  b: scala.collection.mutable.Map[Int,Int] = Map(2 -> 2)

  scala> val c = mutable.Map(3->2)
  c: scala.collection.mutable.Map[Int,Int] = Map(3 -> 2)

  scala> a ++ b ++ c
  res0: scala.collection.mutable.Map[Int,Int] = Map(2 -> 2, 1 -> 2, 3 -> 2)

For four maps, it shows b, d, a, c. For two b, a. The resulting map is always in the same order, no matter the original sequence.


Testing the answer:

  Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
  Type in expressions to have them evaluated.
  Type :help for more information.

  scala> import collection.mutable.LinkedHashMap
  import collection.mutable.LinkedHashMap

  scala> val a = LinkedHashMap(1 -> 2)
  a: scala.collection.mutable.LinkedHashMap[Int,Int] = Map(1 -> 2)

  scala> val b = LinkedHashMap(2 -> 2)
  b: scala.collection.mutable.LinkedHashMap[Int,Int] = Map(2 -> 2)

  scala> val c = LinkedHashMap(3 -> 2)
  c: scala.collection.mutable.LinkedHashMap[Int,Int] = Map(3 -> 2)

  scala> a ++ b ++ c
  res0: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2, 2 -> 2, 3 -> 2)

Upvotes: 4

Views: 179

Answers (1)

Travis Brown
Travis Brown

Reputation: 139048

Scala's Map (like Java's) does not have a defined iteration order. If you need to maintain insertion order, you can use a ListMap (which is immutable) or a LinkedHashMap (which is not):

scala> import collection.mutable.LinkedHashMap
import collection.mutable.LinkedHashMap

scala> val a = LinkedHashMap(1 -> 2)
a: scala.collection.mutable.LinkedHashMap[Int,Int] = Map(1 -> 2)

scala> a += (2 -> 2)
res0: a.type = Map(1 -> 2, 2 -> 2)

scala> a += (3 -> 2)
res1: a.type = Map(1 -> 2, 2 -> 2, 3 -> 2)

scala> a
res2: scala.collection.mutable.LinkedHashMap[Int,Int] = Map(1 -> 2, 2 -> 2, 3 -> 2)

But in general if you care about the order of your elements, you're probably better off with a different data structure.

Upvotes: 10

Related Questions