2017-04-26 5 views
1

Hier ist mein Beispiel für eine verschachtelte Map mit den Daten als Literale. Das Programm funktioniert wie vorgesehen.Scala verschachtelte Karten - wie zu verarbeiten?

var x = scala.collection.mutable.Map(
     ("Early", Map(("a", 1), ("b", 2))), 
     ("Late", Map(("x", 24), ("y", 25)))) 

for (ticker <- x.keys) { 
    val trades = x(ticker) 
    for (tradetime <- trades.keys) { 
     val tradetotal = trades(tradetime) 
     println(ticker + " | " + tradetime + " | " + tradetotal) 
    } 
    println(ticker + " | " + trades) 
} 

Allerdings möchte ich die Literale zu beseitigen und die oben genannten Werte aus einer CSV-Datei lesen. Hier ist die csv:

Early,a,1 
Early,b,2 
Late,x,24 
Late,y,25 

Hier ist der Code, den csv zu lesen und die Werte in einer Art und Weise ähnlich dem obigen Programm mit Literalen ausdrucken.

val bufferedSource = io.Source.fromFile("mapt.csv") 
    val builder = StringBuilder.newBuilder 

    for (line <- bufferedSource.getLines) { 
    val cols = line.split(",").map(_.trim) 
    println(s"${cols(0)}|${cols(1)}|${cols(2)}") 
    var tmp = cols(0) // s"${cols(0)}" 

    val inner = scala.collection.mutable.Map.empty[String, Int] 
    inner(cols(1)) = cols(2).toInt 
    println(inner) 

    val outer = scala.collection.mutable.Map.empty[String, String] 
    outer(cols(0)) = inner 
    println(outer) 

    } 
    bufferedSource.close 

Mein Code funktioniert nicht. Ich habe Schwierigkeiten, Anleitungen zur Verarbeitung verschachtelter Karten zu finden. Ich lerne Scala. Dankbar für alle Vorschläge zum Erstellen von verschachtelten Karten aus CSV-Datei-Daten.

bekomme ich folgende Fehlermeldung:

enter image description here

+0

Welchen Fehler bekommen Sie? – mfirry

+0

Ich habe einen Screenshot des Fehlers hinzugefügt. – Fred

Antwort

3
val lines = scala.io.Source.fromFile("mapt.csv").getLines() 
val row = lines.map(_.split(",").map(_.trim)) 
val outerMap=row.groupBy(_.head) 
val result = outerMap.map{case (key,values)=> 
    key-> values.map(v=>(v(1)->v(2))).toMap} 
+0

Schön. Ich denke, die Verwendung von 'mapValues ​​()' würde die letzte Zeile vereinfachen. – jwvh

0

Danke für die Antwort, Arnon. Deine letzte Zeile verwirrte mich. Es zeigte mir jedoch eine neue Technik, die mir half, das Problem zu lösen. Hier ist mein Arbeitscode:

val bufferedSource = io.Source.fromFile("mapt.csv") 
    val builder = StringBuilder.newBuilder 

    for (line <- bufferedSource.getLines) { 
    val cols = line.split(",").map(_.trim) 
    println(s"${cols(0)}|${cols(1)}|${cols(2)}") 

    val outerMap = Map(cols(0) -> Map(cols(1) -> cols(2).toInt)) 
    println("outerMap looks like this: " + outerMap) 
    println("Accessing the lowest-level value: " + outerMap(cols(0))(cols(1))) 
    } 
    bufferedSource.close 

Mein Denken ist fehlerhaft, ich weiß. Der obige Ansatz ist eine Kopie der Verschachtelung von assoziativen Arrays in awk. Eines Tages werde ich in Scala anfangen zu denken.

0

speziell auf Ihre Zusammenstellung Fehler beheben:

Sie besagt, dass die outer Karte einen String Schlüssel hat und und String Wert.

Aber später, wenn Sie tun outer(cols(0)) = ??? Sie sagen "Ich möchte diesen Wert auf den Schlüssel cols(0) setzen".

Der Compiler beschwert sich also, dass das, was Sie in die Map einfügen möchten, von einem anderen Typ ist als der erwartete String.

Hinweis: Mutabilität ist in Scala entmutigt. Wenn Sie es nicht wirklich benötigen, können Sie die gleiche Art von Code mit unveränderlichen Sammlungen schreiben.

+1

Danke für die klare Erklärung und den Rat, mfirry. Ich brauche alles, was ich bekommen kann. Wie Sie sehen können, krieche ich immer noch, habe noch nicht angefangen zu laufen. Eines Tages werde ich ein großartiger Scala-Programmierer sein! – Fred

Verwandte Themen