Desembalaje de tuplas en operaciones de mapas

79

Con frecuencia me encuentro trabajando con listas, secuencias e iteradores de tuplas y me gustaría hacer algo como lo siguiente:

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

Sin embargo, el compilador nunca parece estar de acuerdo con esta sintaxis. En cambio, termino escribiendo,

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

Lo cual es una tontería. ¿Cómo puedo evitar esto?

digno de pato
fuente

Respuestas:

137

Una solución alternativa es usar case:

arrayOfTuples map {case (e1: Int, e2: String) => e1.toString + e2}
Nicolas
fuente
37
Y ni siquiera necesita escribir los elementos de tupla. case (e1, e2) => es suficientemente bueno, se conocen los tipos de elementos de tupla.
Didier Dupont
32

Me gusta la función tuplicada; es conveniente y no menos importante, escriba seguro:

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

¿Por qué no usas

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

Si necesita los parámetros varias veces, o en un orden diferente, o en una estructura anidada, donde _ no funciona,

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

parece ser una forma breve pero legible.

usuario desconocido
fuente
1
Supongo que la razón principal es que la mayoría de las veces, el procesamiento de la función del mapa es mucho más complicado _.toString + _y quiere manipular nombres más comprensibles que t._1y t._2.
Nicolas
Bueno, entonces arrayOfTuples map {case (i, s) => i.toString + s}es, por supuesto, más útil. Sin embargo, debe hacer la pregunta que tenga para obtener la respuesta que necesita. :)
usuario desconocido
Bueno, como dijo "con frecuencia", espero que signifique "en diferentes casos", no veo ningún escenario en el que necesites un Int + Stringmapeo con frecuencia . ;)
Nicolas
7

Otra opcion es

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

Tenga en cuenta que con Dotty(foundation of Scala 3), se ha extendido el desarme de parámetros , lo que permite tal sintaxis:

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

donde cada uno se _refiere en orden a la parte de tupla asociada.

Xavier Guihot
fuente
1

Creo que la comprensión es la solución más natural aquí:

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