2015-01-27 8 views
6

При работе в Scala, я часто хочу разобрать поле типа [A] и преобразовать его в Option[A] с одного случая (например, "NA" или "") преобразуются в None , а другие - в некоторых случаях.Scala синтаксический сахар для преобразования `Option`

Прямо сейчас, я использую следующий синтаксис соответствия.

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

Есть ли более лаконичный/идиоматический способ написать это?

ответ

10

Есть более сжатые способы. Один из:

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

будет делать свое дело, хотя это немного менее эффективным, поскольку он создает один вариант и может затем выбросить.

Если вы сделаете это много, то вы, вероятно, хотите создать метод расширения (или просто метод, если вы не против, имя метода первого):

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

Теперь вы можете

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

(И, конечно, всегда можно создать метод, чье тело ваше решение матч, или эквивалент один с, если, так что вы можете использовать его для этого конкретного случая.)

0

Простой и интуитивный подход включает в себя это выражение,

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

Это предполагает s этикетки значение, которое должно быть в противном случае соответствует (благодаря @RexKerr для заметки).

+0

Это предполагает, что вы есть простое имя '' ' джин с. Это не всегда так. –

4

я бы, вероятно, использовать filterNot здесь:

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

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

Это требует, чтобы думать о Option как коллекция с одним или нулевых элементов, но если вы получаете в эту привычку, это достаточно ясно.

Смежные вопросы