2015-01-27 18 views
6

Khi làm việc tại Scala, tôi thường muốn phân tích một lĩnh vực loại [A] và chuyển nó sang một Option[A], với một trường hợp duy nhất (ví dụ, "NA" hoặc "") được chuyển đổi sang None và các trường hợp khác được bọc trong một số.Scala cú pháp đường để chuyển đổi cho `Option`

Hiện tại, tôi đang sử dụng cú pháp khớp sau.

match { 
    case "" => None 
    case s: String => Some(s) 
} 
// converts an empty String to None, and otherwise wraps it in a Some. 

Có cách nào ngắn gọn/thành ngữ hơn để viết nội dung này không?

Trả lời

10

Có một cách ngắn gọn hơn. Một trong số:

Option(x).filter(_ != "") 
Option(x).filterNot(_ == "") 

sẽ thực hiện thủ thuật, mặc dù nó kém hiệu quả hơn một chút khi tạo tùy chọn và sau đó có thể vứt bỏ.

Nếu bạn làm điều này rất nhiều, có thể bạn muốn tạo ra một phương pháp mở rộng (hay chỉ là một phương pháp, nếu bạn không nhớ có tên phương pháp đầu tiên):

implicit class ToOptionWithDefault[A](private val underlying: A) extends AnyVal { 
    def optNot(not: A) = if (underlying == not) None else Some(underlying) 
} 

Bây giờ bạn có thể

scala> 47.toString optNot "" 
res1: Option[String] = Some(47) 

(Và, tất nhiên, bạn luôn có thể tạo ra một phương pháp mà cơ thể là giải pháp phù hợp với bạn, hoặc là một tương đương với nếu, vì vậy bạn có thể tái sử dụng nó cho rằng trường hợp cụ thể.)

0

Một phương pháp đơn giản và trực quan bao gồm biểu hiện này,

if (s.isEmpty) None else Some(s) 

này giả s nhãn giá trị để được xuất hiện bằng cách khác (nhờ @RexKerr cho ghi chú).

+0

này giả định bạn có một tên đơn giản cho 's' là gin với. Đó không phải lúc nào cũng vậy. –

4

tôi có lẽ muốn sử dụng filterNot đây:

scala> Option("hey").filterNot(_ == "NA") 
res0: Option[String] = Some(hey) 

scala> Option("NA").filterNot(_ == "NA") 
res1: Option[String] = None 

Nó đòi hỏi bạn phải nghĩ về Option như một bộ sưu tập với một hoặc không có các yếu tố, nhưng nếu bạn nhận được vào thói quen mà nó hợp lý rõ ràng.

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