2012-10-16 5 views
22

Ich möchte map() auf einer Liste von Paaren aufrufen, aber ich bekomme einen Typenkonfliktfehler.
Angenommen, ich eine Liste von Paaren von Int auf eine Liste ihrer Summen abbilden will:Wie man .map() auf einer Liste von Paaren in scala aufruft?

scala> val ll=List((1,2),(3,4),(5,6)) 
ll: List[(Int, Int)] = List((1,2), (3,4), (5,6)) 

scala> ll.map((x:Int,y:Int)=>x+y) 
<console>:9: error: type mismatch; 
found : (Int, Int) => Int 
required: ((Int, Int)) => ? 
       ll.map((x:Int,y:Int)=>x+y) 
           ^

By the way, wenn sie versuchen, foreach() bekomme ich einen sehr ähnlichen Fehler zu laufen.

scala> ll.foreach((x:Int,y:Int)=>println(x,y)) 
<console>:9: error: type mismatch; 
found : (Int, Int) => Unit 
required: ((Int, Int)) => ? 
       ll.foreach((x:Int,y:Int)=>println(x,y)) 
           ^

Was bedeutet das? Zeichen stehen für? Was fehlt mir hier?

dank

+0

Ich bekomme einen anderen Fehler, wenn ich einfach '(x, y) => x + y' verwenden Warum ist das? ': 17: Fehler: falsche Anzahl von Parametern; erwartet = 1 c.map ((x, y) => x + y) ' –

Antwort

42

Sie können pattern matching verwenden, um die Elemente des Paares zu erhalten.

ll.map{ case (x:Int,y:Int) => x + y } 

Sie brauchen nicht einmal die Typen angeben:

ll.map{ case (x, y) => x + y } 

Das gleiche funktioniert mit foreach natürlich.

Die Fehlermeldung besagt, dass der Compiler erwartet eine Funktion von ein Parameter (ein Paar von Ints) auf jede Art (Fragezeichen) zu finden und stattdessen eine Funktion von zwei Parameter gefunden, beide ints.

18

Sie verwenden können:

ll.map(x => x._1 + x._2) 

wo x steht für das Tupel selbst oder

ll.map(x:(Int,Int) => x._1 + x._2) 

wenn Sie explizit die Typen zu erklären.

+2

Während wahr; Ich denke, das ist ein schlechter Stil; Wir sollten 'case (x, y)' jederzeit verwenden –

+1

Können Sie eine Begründung hinzufügen? Es scheint mir, dass wir wissen, dass wir ein Tupel haben und es so zu diskreditieren, dass es nicht unvernünftig ist. Der Fall "entpackt" das Tupel und Sie wollen vielleicht nicht in allen Fällen –

+0

Wenn man die scala -print-Ausgabe beider Wege betrachtet, scheint es im Wesentlichen dasselbe zu tun (beide führen eine asInstanceOf-Prüfung durch, box und entpacken), und ich denke, dass die Fallform ästhetisch ansprechender ist - ich wünschte, ich hätte erkannt, dass dies vorher möglich war! – iainmcgin

6

Sie können Tupel eine Funktion, was bedeutet, von einem, der N Args nimmt, zu einem, der 1 Arg nimmt, das ist ein N-Tupel. Die Funktion höherer Ordnung hierfür ist auf dem Objekt Function verfügbar. Dies führt zu einer netten Syntax plus der zusätzlichen Typensicherheit, die in den Kommentaren zu Brian Agnews Antwort hervorgehoben wird.

import Function.tupled 

ll map tupled(_ + _) 
Verwandte Themen