2015-01-15 3 views
6

Ich möchte fehlerhafte Eingabe aus Eingabedaten herausfiltern. Ich verwende derzeit scala.util.Try, um Ausnahmen zu umbrechen. Es folgt ein einfaches Beispiel, in dem 3I eine NumberFormatException auslöst. Ich habe mich gefragt, ob es in Scala einen besseren Weg dafür gibt?Konvertieren einer Liste [Versuchen Sie [A]] zu Liste [A] in Scala

val data = List (("Joe", "20"), ("James", "30"), ("Pete", "3I")) 

scala> val parsedData = data.map{ d => Try{Person(d._1, d._2.toInt) }} 
parsedData: List[scala.util.Try[Person]] = List(Success(Person(Joe,20)), Success(Person(James,30)), Failure(java.lang.NumberFormatException: For input string: "3I")) 

scala> val validdata = parsedData.map{ x => x match { 
    | case Success(s) => Some(s) 
    | case Failure(f) => None } 
    | } 
validdata: List[Option[Person]] = List(Some(Person(Joe,20)), Some(Person(James,30)), None) 

scala> validdata.flatten 
res13: List[Person] = List(Person(Joe,20), Person(James,30)) 

Antwort

14

Verwenden collect nur die Werte zu halten, die dem Muster entsprechen, die Sie wünschen:

parsedData collect { case Success(x) => x } 

Dies wird auch funktionieren, obwohl ich nicht glaube, es ganz so klar ist:

parsedData.flatMap(_.toOption) 
+1

Danke. Aber gibt es eine bessere Möglichkeit, den "Try" -Teil zu bewältigen? –

+0

Ein besserer Weg, was genau zu tun? Ich sehe nichts falsch mit der Art, wie Sie es verwenden, wenn alles, was Sie wollen, ist, die Fehler zu verwerfen. –

+0

Ja, eine bessere Möglichkeit, Fehler zu verwerfen. –

0

Ein Ansatz, der die Verwendung von Try wie folgt umgeht,

for (d <- data if d._2.forall(_.isDigit)) yield Person(d._1, d._2.toInt) 

Dies ist jedoch möglicherweise nicht so skalierbar wie der @ m-z-Ansatz.

Verwandte Themen