2016-12-28 1 views
2

Ich habe eine Liste von StringsKonvertieren Liste in eine Karte mit Schlüsseln ein Index in Scala sind

val list = List("a", "b", "c", "d", "e") 

und ich möchte eine Karte mit Schlüssel als Indizes der Elemente in der Liste haben. Also habe ich folgendes:

def mapByIndexes(list: List[String]): Map[Int, String] = (1 to list.size).zip(list).toMap 

Allerdings ist die resultierende Karte nicht den Index, um zu erhalten und ich bin immer dies als Resultat:

Map(5 -> "e", 1 -> "a", 2 -> "b", 3 -> "c", 4 -> "d") 

Wie kann ich über so ändern Sie den Code I bekomme ich eine Karte mit der folgenden, natürlichen Reihenfolge?

Map(1 -> "a", 2 -> "b", 3 -> "c", 4 -> "d", 5 -> "e") 

Hinweis: Ich bin mir bewusst, dass ich nur die resultierende Karte sortieren kann, aber kann ich diesen Schritt vermeiden und eine Karte erstellen, die bereits den Auftrag erhält?

Edit: Lösung mit ListMap beschrieben um Scala LinkedHashMap.toMap preserves order? funktioniert, aber ich mag keine zusätzlichen Klammern und _* für so einfache Sache. Gibt es sonst noch etwas, so kann ich nur eine Kette haben? Wenn nicht, werde ich @pamu antworten annehmen.

+1

Mögliches Duplikat von [Scala LinkedHashMap.toMap bewahrt die Reihenfolge?] (Http://Stackoverflow.com/questions/6199186/scala-linkedhashmap-tomap-preserve-order) –

Antwort

3

Ich bin mir bewusst, dass ich nur die resultierende Karte Kein

sortieren kann, kann man nicht. Eine Map Sortierung ist nicht sinnvoll. Aber es gibt Map Implementierungen, die Schlüssel in natürlicher Reihenfolge speichern, wie TreeMap (IntMap auch, IIRC). Beachten Sie, dass es nicht das gleiche wie die Einhaltung der Reihenfolge ist, wie ListMap und tun.

Lösung mit ListMap beschrieben auf Scala LinkedHashMap.toMap bewahrt die Reihenfolge? funktioniert, aber ich mag keine zusätzlichen Klammern und _ * für so einfache Sache. Gibt es sonst noch etwas, so kann ich nur eine Kette haben?

Nein (zumindest glaube ich nicht so), aber man kann es leicht definieren:

implicit class ToListMap[A, B](x: Seq[(A, B)]) { 
    def toListMap = ListMap(x: _*) 
} 

// somewhere where ToListMap is in scope or imported: 
val list = List(1 -> 2, 3 -> 4) 
list.toListMap 

Beachten Sie, dass ListMap ist im Grunde eine Liste (wie der Name schon sagt), so Lookups darin sind langsamer als jede vernünftige Kartenimplementierung.

Natürlich können Sie genau das gleiche mit TreeMap tun.

+0

Durch das Sortieren der Karte habe ich die Dinge gemeint, die du beschrieben hast. Wenn du nach "sort map scala" suchst, zeigt es genau diese :) –

+0

BTW, Code, den du zur Verfügung gestellt hast, kompiliert nicht. Ich bekomme 'Typenkonflikt; gefunden: Seq [(A, B)] benötigt: (?,?) def toListMap = ListMap (x) ' –

+0

Hallo Alexey - warum hast du' SortedMap' nicht erwähnt? Bewirbt es nicht den Wunsch des OP nach einer nach seinen Schlüsseln sortierten "Karte"? –

2

Verwenden Sie ListMap. Nach dem Zippen anstelle von toMap, konstruieren Sie einfach die ListMap, die die Reihenfolge der Elemente erhält. Sie können eine ListMap mit ihrem Begleitobjekt erstellen. Es akzeptiert var args von Tupeln.

def mapByIndexes(list: List[String]): ListMap[Int, String] = ListMap((1 to list.size).zip(list): _*) 

Scala REPL

scala> import scala.collection.immutable._ 
import scala.collection.immutable._ 

scala> def mapByIndexes(list: List[String]): ListMap[Int, String] = ListMap((1 to list.size).zip(list): _*) 
mapByIndexes: (list: List[String])scala.collection.immutable.ListMap[Int,String] 

scala> mapByIndexes(list) 
res10: scala.collection.immutable.ListMap[Int,String] = Map(1 -> a, 2 -> b, 3 -> c, 4 -> d, 5 -> e) 
+0

Schön, funktioniert auch für mich.Ich mag keine zusätzlichen Klammern und '_ *' obwohl. Gibt es sonst noch etwas, so kann ich einfach eine einfache Kette haben? –

Verwandte Themen