2015-01-15 9 views
6

Chcę odfiltrować błędne dane wejściowe z danych wejściowych. Obecnie używam scala.util.Try do zawijania dowolnych wyjątków. Oto prosty przykład, w którym 3I wyrzuca NumberFormatException. Zastanawiałem się, czy jest lepszy sposób na zrobienie tego w Scali?Konwertowanie listy [Spróbuj [A]] na listę [A] w Scali

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

Odpowiedz

14

Zastosowanie collect zachować tylko wartości, które pasują do wzorca pragnienie:

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

ta będzie również działać, choć nie sądzę, że to aż tak oczywiste:

parsedData.flatMap(_.toOption) 
+1

Dzięki. Ale czy istnieje lepszy sposób obsługi części 'Try'? –

+0

Lepszy sposób, aby dokładnie to zrobić? Nie widzę niczego złego w sposobie, w jaki go używasz, jeśli chcesz tylko odrzucić niepowodzenia. –

+0

Tak, lepszy sposób na odrzucenie awarii. –

0

Jedno podejście, które omija użycie Try, jak następuje,

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

Jednak może to nie być tak skalowalne, jak podejście @ m-z.

Powiązane problemy