I have a list of type List(String,String)
and I wanted to convert it to map. When I used toMap
method I found that it does not preservers the order of data that is there in the List. However my goal is to convert the list to Map by keeping the order of the data same as of List. I learned that ListMap
preserves the insertion order(but it is immutable) so I can use the LinkedHashMap with map function to insert the data sequentially into LinkedHashMap
but that means I need to iterate over all the elements which is pain. Can anyone please suggest me a better approach?
Thanks
Asked
Active
Viewed 4,577 times
13

Explorer
- 1,491
- 4
- 26
- 67
-
"my goal is to convert the list to Map by keeping the order of the data same as of List". Maps don't work like that – n. m. could be an AI Jan 18 '17 at 15:09
-
" I learned that ListMap preserves the insertion order" How did you learn that? There's nothing in the documentation. – n. m. could be an AI Jan 18 '17 at 15:18
-
I got to know from this post http://stackoverflow.com/questions/3835743/scala-map-implementation-keeping-entries-in-insertion-order – Explorer Jan 18 '17 at 15:19
-
Apparently the answers there tell you to use LinkedHashMap, why not give it a try. – n. m. could be an AI Jan 18 '17 at 15:28
-
@n.m. I am trying both and learning about the performance too of both the collections. – Explorer Jan 18 '17 at 15:36
3 Answers
19
This should do it :
val listMap = ListMap(list : _*)

C4stor
- 8,355
- 6
- 29
- 47
-
Thanks @C4stor for your comment, it worked. I am new to scala and a small explanation on the annotation would help a lot in understanding in depth. – Explorer Jan 18 '17 at 15:37
-
1[ListMap#apply](http://www.scala-lang.org/api/2.11.8/index.html#scala.collection.immutable.ListMap$@apply[A,B](elems:(A,B)*):CC[A,B]) accepts tuple varargs. By calling `: _*`, list's elements are applied in a varargs fashion, as I understand. Perhaps this [gist](https://gist.github.com/kevinmeredith/b4b3e35bf7bfadce253a8d74aef1c7ef) will help. See, also, http://stackoverflow.com/questions/1008783/using-varargs-from-scala for more info. – Kevin Meredith Jan 18 '17 at 15:42
-
1@KevinMeredith got it right. I think a more relevant question to understand : _* is http://stackoverflow.com/questions/6051302/what-does-colon-underscore-star-do-in-scala which have, hopefully, all information you need :) – C4stor Jan 18 '17 at 15:46
-
"colon underscore star" works nice, but my favorite is `mylist.to(ListMap)` (Scala >=2.13) mentioned by @Jasper-M – Hartmut Pfarr Mar 16 '21 at 12:48
-
Sure, but scala 2.13 was released more than 2 years after this question was asked, so there's that ^^ – C4stor Mar 17 '21 at 09:04
4
In Scala 2.13 or later:
scala> import scala.collection.immutable.ListMap
import scala.collection.immutable.ListMap
scala> val list = List((1,2), (3,4), (5,6), (7,8), (9,0))
list: List[(Int, Int)] = List((1,2), (3,4), (5,6), (7,8), (9,0))
scala> list.to(ListMap)
res3: scala.collection.immutable.ListMap[Int,Int] = ListMap(1 -> 2, 3 -> 4, 5 -> 6, 7 -> 8, 9 -> 0)

Jasper-M
- 14,966
- 2
- 26
- 37
0
Don't use a ListMap. They are extremely imperformant. Since they are structured as lists they have linear lookup performance (https://docs.scala-lang.org/overviews/collections/performance-characteristics.html)
I'd advise instanciating a mutable LinkedHashmap and then assigning it to a val defined as a collections.Map. The collection.Map interface doesn't expose mutable methods so the map is immutable to any entity accessing it.

Andrew Norman
- 843
- 9
- 22