2011-06-17 10 views
24

Quiero crear una lista de tipo de objeto más complejo a partir de una lista de tipo simple. Por ejemplo, List[String] => List[MyType].Convertir la lista de Scala en una lista con otro tipo

Lo he dado tres va utilizando enfoques basados ​​en mapas. Un mapa sencillo con comodín:

> case class telecom (name:String, longitude:Double, latitude:Double) 
defined class telecom 
> List("foo","bar").map(x:String => telecom(x,0,0)):List[telecom] 
:1: error: ';' expected but ')' found. 

Un método de coincidencia de patrones que utiliza el constructor de la clase caso:

> def foo(c:List[String]){                    
| c match {                        
| case tc:List[telecom] => tc.map(telecom(_,0,0)):List[telecom]; println("matched telephonecomapny"); 
| case _ => println("matched nothing"); throw new ClassCastException(); }} 
warning: there were unchecked warnings; re-run with -unchecked for details 
foo: (c: List[String])Unit 

> foo(List("foo","bar")) 
java.lang.ClassCastException: java.lang.String cannot be cast to usda.rd.broadband.model.DatabaseTables$TelephoneCompany 
    at $anonfun$foo$1.apply(<console>:11) 
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:206) 
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:206) 
    at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:61) 
    at scala.collection.immutable.List.foreach(List.scala:45) 
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:206) 
    at scala.collection.immutable.List.map(List.scala:45) 
    at .foo(<console>:11) 
    at .<init>(<console>:11) 
    at .<clinit>(<console>) 
    at RequestResult$.<init>(<console>:9) 
    at RequestResult$.<clinit>(<console>) 
    at RequestResult$scala_repl_result(<console... 

y un método de coincidencia de patrones más simple:

> def bar(c:List[String]){ 
| c match { 
| case tc:List[telecom] => tc 
| case _ => println("matched nothing")}} 
warning: there were unchecked warnings; re-run with -unchecked for details 
foo: (c: List[String])Unit 
> val r = bar(List("foo","bar")) 
t: Unit =() 
+0

coincidencia de patrones coincide _ lo que ya está allí_. ¡No puedes usar el acto de igualar para transformar tus datos! Usted está pidiendo, "Dada una lista de cadenas, _si ya son una lista de telecomunicaciones_, entonces (bla, bla)". –

Respuesta

33

El primer intento está bastante bien Olvidó usar paréntesis alrededor de los argumentos de la función lambda. En lugar de:

List("foo","bar").map(x:String => telecom(x,0,0)):List[telecom] 

se debe utilizar:

List("foo","bar").map((x:String) => telecom(x,0,0)):List[telecom] 

o más simple:

List("foo","bar").map(x => telecom(x,0,0)) 
+0

¡Agradable y doh! en mi extremo. En mi defensa, si hubiera escrito el mensaje de error, habría estado "faltando paréntesis alrededor de los argumentos de la función lambda" y la corrección sería obvia. ¡Gracias! – Noel

+0

lanzando a List [telecom] en los primeros 2 ejemplos no es necesario – Tim

+0

@Tim: No es un casting, es un tipo de adscripción. De hecho, no es necesario, el objetivo aquí es "probar" que el tipo resultante es correcto. ¿Crees que la respuesta sería más clara si los eliminara? – paradigmatic

1

O puede hacer lo siguiente:

List("foo","bar").map(x => telecom(x,0,0)) 
24

En el interés de uno superior, debo decir que se puede reducir aún más a

List("foo","bar").map(telecom(_,0,0)) 
Cuestiones relacionadas