orden - ¿Hay una forma más limpia de emparejar patrones en las funciones anónimas de Scala?
funciones de orden superior scala (4)
Créalo o no, esto funciona:
val b = List(1, 2)
b map({case 1 => "one"
case 2 => "two"})
Puede omitir la p => p match
en casos simples. Entonces esto debería funcionar:
val c = a map {case ((x,y) -> u) =>
(y,x) -> u
}
Me encuentro escribiendo código como el siguiente:
val b = a map (entry =>
entry match {
case ((x,y), u) => ((y,x), u)
}
)
Me gustaría escribirlo de otra manera, si solo esto funcionara:
val c = a map (((x,y) -> u) =>
(y,x) -> u
)
¿Hay alguna manera de que pueda obtener algo parecido a esto?
En su ejemplo citado, la solución más limpia es:
val xs = List((1,2)->3,(4,5)->6,(7,8)->9)
xs map { case (a,b) => (a.swap, b) }
En su ejemplo, hay tres semánticas sutilmente diferentes a las que puede aspirar.
Mapa sobre la colección, transformando cada elemento que coincida con un patrón. Lanza una excepción si algún elemento no coincide. Esta semántica se logra con
val b = a map { case ((x, y), u) => ((y, x), u) }
Mapa sobre la colección, transformando cada elemento que coincida con un patrón. Descarte en silencio los elementos que no coinciden:
val b = a collect { case ((x, y), u) => ((y, x), u) }
Mapa sobre la colección, desestructurando de forma segura y luego transformando cada elemento. Estas son las semánticas que esperaría para una expresión como
val b = a map (((x, y), u) => ((y, x), u)))
Desafortunadamente, no existe una sintaxis concisa para lograr esta semántica en Scala. En cambio, debes destructurarte a ti mismo:
val b = a map { p => ((p._1._2, p._1._1), p._2) }
Uno podría tener la tentación de usar una definición de valor para la desestructuración:
val b = a map { p => val ((x,y), u) = p; ((y, x), u) }
Sin embargo, esta versión no es más segura que la que usa concordancia explícita de patrones . Por esta razón, si desea la semántica de desestructuración segura, la solución más concisa es escribir explícitamente su colección para evitar ampliaciones involuntarias y usar concordancia explícita de patrones:
val a: List[((Int, Int), Int)] = // ... // ... val b = a map { case ((x, y), u) => ((y, x), u) }
Si la definición de un usuario aparece lejos de su uso (por ejemplo, en una unidad de compilación separada), puede minimizar el riesgo al atribuir su tipo en la llamada al mapa:
val b = (a: List[((Int, Int), Int)]) map { case ((x, y), u) => ((y, x), u) }
val b = a map { case ((x,y), u) => ((y,x), u) }