2012-04-02 14 views
4

Ich habe eine Liste von Tupeln, und ich möchte durchqueren und den Wert jedes Elements erhalten.Scala Neuling Probleme mit Tupeln und Verschlüsse

Dies ist der Code:

scala> val myTuples = Seq((1, "name1"), (2, "name2")) 
myTuples: Seq[(Int, java.lang.String)] = List((1,name1), (2,name2)) 

scala> myTuples.map{ println _ } 
(1,name1) 
(2,name2) 
res32: Seq[Unit] = List((),()) 

So weit, so gut, aber

scala> myTuples.map{ println _._1 } 
<console>:1: error: ';' expected but '.' found. 
    myTuples.map{ println _._1 } 

ich auch versucht, mit:

scala> myTuples.map{ println(_._1) } 
<console>:35: error: missing parameter type for expanded function ((x$1) => x$1._1) 
      myTuples.map{ println(_._1) } 

scala> myTuples.map{ val (id, name) = _ } 
<console>:1: error: unbound placeholder parameter 
     myTuples.map{ val (id, name) = _ } 

scala> myTuples.map{ x => println x } 
<console>:35: error: type mismatch; 
found : Unit 
required: ?{val x: ?} 
Note that implicit conversions are not applicable because they are ambiguous: 
both method any2Ensuring in object Predef of type [A](x: A)Ensuring[A] 
and method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A] 
are possible conversion functions from Unit to ?{val x: ?} 
       myTuples.map{ x => println x } 

die Variable deklarieren, und die Verwendung von Klammern haben der Trick, aber ich würde gerne wissen, warum die anderen Optionen nicht funktionierten

diese funktionierte gut

myTuples.map{ x => println("id: %s, name: %s".format(x._1, x._2)) } 

scala> myTuples.map{ x => println("id: %s, name: %s".format(x._1, x._2)) } 
id: 1, name: name1 
id: 2, name: name2 
res21: Seq[Unit] = List((),()) 

scala> myTuples.map{ x => val(id, name) = x; println("id: %s, name: %s".format(id, name)) } 
id: 1, name: name1 
id: 2, name: name2 
res22: Seq[Unit] = List((),()) 

scala> myTuples.map{ x => println(x._1) } 

Was passiert mit mir, mit meinem ersten Schritte mit scala, das ist ein wenig darauf, Sie bekommen, was Sie wollen, aber Sie sind nicht sicher, warum Sie die ersten Optionen nicht versucht haben Arbeit ...

+1

FWIW, 'map' verwendet, wenn Sie den Inhalt einer Sammlung verwandeln möchten. Da Ihnen die Ergebnisse egal sind, ist 'foreach' die bevorzugte Methode. – leedm777

+0

netter Tipp, und es macht auch viel deutlicher die Absicht des Entwicklers – opensas

Antwort

6

Für die Optionen, die nicht funktionierten:

scala> myTuples.map{ println _._1 } 

Kurze Antwort: In Scala müssen Sie immer Parens um println Argument verwenden. Lange Antwort: Scala bezieht sich nur auf Klammern für Infixmethoden, dh Code der Formulare object method argument wird als object.method(argument) interpretiert. Es ist kein Objekt angegeben, daher werden keine Klammern abgeleitet. Sie können dies sehen Sie direkt von:

scala> println "Boom!" 
<console>:1: error: ';' expected but string literal found. 
     println "Boom!" 
      ^

Als nächstes myTuples.map{ println(_._1) }. Es ist mir nicht sofort klar, warum das nicht funktioniert, da dies myTuples.map{ x => println(x._1) } entspricht, was funktioniert. Wie the answers to this question zeigen, gilt Platzhalter/teilweise angewandte Methodensyntax für den kleinstmöglichen Bereich. Also äquivalenter Code wäre myTuples.map { println(x => x._1) }. Da es für scala nicht genügend Informationen gibt, um den Typ x abzuleiten, erhalten Sie den Fehler 'fehlender Parametertyp'.

Bezüglich werden Platzhalter in anonymen Funktionen verwendet, während Sie hier val initialisieren.

Dann für , vermissen Sie auch Parens.

Schließlich funktionierte die Option, die für Sie funktionierte myTuples.map{ x => println("id: %s, name: %s".format(id, name)) }, nicht wirklich (schauen Sie sich die Daten an, die gedruckt wurden). Meine Vermutung, wenn Sie bereits in der REPL id und name definiert hätten, und das sind die Werte, die gedruckt werden. Ihre Arbeitslösungen funktionieren jetzt gut.

Meine Lösung für das, was Sie versuchen zu tun wäre:

myTuples foreach { 
    case (id, name) => printf("id: %s, name: %s\n", id, name) 
} 

oder

myTuples foreach { 
    x => printf("id: %s, name: %s\n", x._1, x._2) 
} 
+0

Vielen Dank, ausgezeichnete Antwort, und Sie haben Recht, die Lösung, die ich gab, hat nicht funktioniert, tut dies: myTuples.map {x => println ("id:% s, name:% s" .format (x._1, x._2))} und auch das: myTuples.map {x => val (id, name) = x; println ("id:% s, name:% s" .format (id, name))} – opensas

+0

Ich habe meine Lösung repariert – opensas

+2

'myTuples.map {println (_._ 1)}' ist äquivalent zu 'myTuples.map {println (x => x._1)} '. Warum sollte es etwas anderes sein? –

4

ich glaube, Sie wollen etwas, wie:

myTuples map { case(id, name) => println(id+": "+name) }