2015-01-15 6 views
6

Desidero filtrare input non validi dai dati di input. Attualmente sto usando scala.util.Try per avvolgere eventuali eccezioni. Di seguito è riportato un semplice esempio in cui 3I genera uno NumberFormatException. Mi stavo chiedendo se c'è un modo migliore per farlo in Scala?Conversione di un elenco [Prova [A]] in Elenco [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)) 

risposta

14

Usa collect per mantenere solo i valori che corrispondono al modello che desiderate:

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

Questo sarà anche funzionare, anche se non credo che sia abbastanza chiaro:

parsedData.flatMap(_.toOption) 
+1

Grazie. Ma c'è un modo migliore di gestire la parte "Prova"? –

+0

Un modo migliore per fare cosa, esattamente? Non vedo niente di sbagliato nel modo in cui lo stai usando, se tutto ciò che vuoi è scartare i fallimenti. –

+0

Sì, un modo migliore per scartare i fallimenti. –

0

Un approccio che ignora l'utilizzo di Try, come segue,

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

Tuttavia, questo potrebbe non essere scalabile come l'approccio di @ m-z.