Tupel-Entpacken in Kartenoperationen

78

Ich arbeite häufig mit Listen, Seqs und Iteratoren von Tupeln und möchte Folgendes tun:

val arrayOfTuples = List((1, "Two"), (3, "Four"))
arrayOfTuples.map { (e1: Int, e2: String) => e1.toString + e2 }

Der Compiler scheint dieser Syntax jedoch niemals zuzustimmen. Stattdessen schreibe ich am Ende,

arrayOfTuples.map { 
    t => 
    val e1 = t._1
    val e2 = t._2
    e1.toString + e2 
}

Welches ist nur dumm. Wie kann ich das umgehen?

duckworthd
quelle

Antworten:

132

Eine Problemumgehung besteht darin, Folgendes zu verwenden case:

arrayOfTuples map {case (e1: Int, e2: String) => e1.toString + e2}
Nicolas
quelle
36
Und Sie müssen nicht einmal die Tupelelemente eingeben. case (e1, e2) => ist gut genug, die Typen der Tupelelemente sind bekannt.
Didier Dupont
31

Ich mag die Tupelfunktion; Es ist sowohl praktisch als auch nicht zuletzt typsicher:

import Function.tupled
arrayOfTuples map tupled { (e1, e2) => e1.toString + e2 }
thoredge
quelle
18

Warum benutzt du nicht?

arrayOfTuples.map {t => t._1.toString + t._2 }

Wenn Sie die Parameter mehrmals oder in anderer Reihenfolge oder in einer verschachtelten Struktur benötigen, in der _ nicht funktioniert,

arrayOfTuples map {case (i, s) => i.toString + s} 

scheint eine kurze, aber lesbare Form zu sein.

Benutzer unbekannt
quelle
1
Ich denke, der Hauptgrund ist, dass die Verarbeitung der Kartenfunktion die meiste Zeit weitaus komplizierter ist als _.toString + _und er verständlichere Namen als t._1und manipulieren möchte t._2.
Nicolas
Na dann arrayOfTuples map {case (i, s) => i.toString + s}ist das natürlich praktischer. Sie sollten jedoch die Frage stellen, die Sie haben, um die Antwort zu erhalten, die Sie benötigen. :)
Benutzer unbekannt
Nun, wie er "häufig" sagte, hoffe ich, dass es "in verschiedenen Fällen" bedeutet. Ich sehe kein Szenario, in dem Sie häufig eine Int + StringZuordnung benötigen . ;)
Nicolas
7

Eine andere Option ist

arrayOfTuples.map { 
    t => 
    val (e1,e2) = t
    e1.toString + e2
}
Kim Stebel
quelle
2

Beachten Sie, dass mit Dotty(Foundation of Scala 3) das Auflösen von Parametern erweitert wurde, um eine solche Syntax zu ermöglichen:

// val tuples = List((1, "Two"), (3, "Four"))
tuples.map(_.toString + _)
// List[String] = List("1Two", "3Four")

wobei sich jeder _auf den zugehörigen Tupelteil bezieht.

Xavier Guihot
quelle
0

Ich denke zum Verständnis ist hier die natürlichste Lösung:

for ((e1, e2) <- arrayOfTuples) yield {
  e1.toString + e2
}
Yahor
quelle