2011-06-17 17 views
24

Chcę utworzyć bardziej złożoną listę typów obiektów z listy typu prostego. Np. List[String] => List[MyType].Konwersja listy Scala do listy o innym typie

Zrobiłem to za trzy podejście oparte na mapach. Prosta mapa z zamiennika:

> 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. 

Sposób wzór dopasowywania że używa konstruktora klasy obudowy:

> 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... 

i prostszą metodę wzór dopasowywania:

> 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

Dopasowywanie do wzorca dopasowań _co już tam jest_. Nie możesz użyć aktu dopasowywania, aby przekształcić swoje dane! Pytasz: "Biorąc pod uwagę listę strun, jeśli są już listą telekomów, to (bla bla)!" –

Odpowiedz

33

Pierwsza próba jest całkiem OK. Właśnie zapomniałeś użyć nawiasu wokół argumentów funkcji lambda. Zamiast:

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

należy użyć:

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

lub prościej:

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

Fajnie, i doh! po mojej stronie. W mojej obronie, gdybyś napisał komunikat o błędzie, byłby to "brak parensów wokół argumentów funkcji lambda", a korekta byłaby oczywista. Dzięki! – Noel

+0

casting to List [telecom] w pierwszych 2 przykładach nie jest konieczny – Tim

+0

@Tim: To nie jest casting, to typowy opis. W rzeczy samej nie jest to konieczne, celem jest tutaj "udowodnienie", że wynikowy typ jest poprawny. Czy uważasz, że odpowiedź byłaby bardziej przejrzysta, gdybym je usunął? – paradigmatic

1

Albo można zrobić, że:

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

W interesie jedno- Upmanship, muszę powiedzieć, że może być dalej zredukowany do

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