2015-01-15 17 views
6

Tôi muốn lọc đầu vào không hợp lệ khỏi dữ liệu đầu vào. Tôi hiện đang sử dụng scala.util.Try để bao gồm bất kỳ ngoại lệ nào. Sau đây là một ví dụ đơn giản trong đó 3I ném một số NumberFormatException. Tôi đã tự hỏi nếu có một cách tốt hơn để làm điều này trong Scala?Chuyển đổi danh sách [Thử [A]] thành Danh sách [A] trong 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)) 

Trả lời

14

Sử dụng collect để giữ chỉ các giá trị phù hợp với mô hình mà bạn mong muốn:

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

này cũng sẽ làm việc, mặc dù tôi không nghĩ rằng nó khá là rõ ràng:

parsedData.flatMap(_.toOption) 
+1

Cảm ơn. Nhưng có cách nào tốt hơn để xử lý phần 'Thử nghiệm 'không? –

+0

Một cách tốt hơn để làm những gì, chính xác? Tôi không thấy bất cứ điều gì sai trái với cách bạn đang sử dụng nó, nếu tất cả những gì bạn muốn là loại bỏ những thất bại. –

+0

Vâng, cách tốt hơn để loại bỏ lỗi. –

0

Một cách tiếp cận bỏ qua việc sử dụng Try, như sau,

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

Tuy nhiên, điều này có thể không chứng minh là có thể mở rộng như tiếp cận @ m-z.

Các vấn đề liên quan