2013-09-11 2 views
0

Учитывая Some(List("hello")) и желая получить "hello", я наблюдал следующее поведение.Извлечение головки опциона [Список [...]]

scala> val list = Some(List("hello")) 
list: Some[List[String]] = Some(List(hello)) 

scala> list.head.head 
res3: String = hello 

Затем я проверил, в Scaladocs и увидел, что head будет Select the first element of this iterable collection. Он также указывает на то, что будет сгенерировано исключение, если коллекция пуста.

Этот поиск первого элемента опциона [Список] считается идиоматическим?

ответ

5

Это не не идиоматическое, но я был бы склонен предпочесть:

scala> val hd = list.flatMap(_.headOption) 
hd: Option[String] = Some(hello) 

И продолжать работать со значением Option.

4

Ответ действительно зависит от того, что вы хотите сделать дальше со значением. Например, вы можете использовать то, что предложили @Shadowlands, и продолжать работать с Option, используя map и flatMap. Еще одна вещь, которую вы могли бы сделать, это использовать сопоставление с образцом:

list match { 
    case Some(head :: tail) => soSomethingWith(head) 
    case Some(Nil) => dealWithEmptyList 
    case None => dealWithNone 
} 
0

Вы - выражение не идиоматическое. Some - способ Scala, имеющий дело с возможностью нулевого значения. Можно объяснить концепцию Some как список, в котором есть только голова и хвост, но только как метафора, а не как идиоматическое использование. То, что вы на самом деле выражаете вложенный список:

val list: List[List[String]] = List(List("hello")) 

Однако, если у вас было 100% уверенности, что list имеет значение, которое не пустой список, то я хотел бы сделать это:

list match { case Some(xs) => xs.head } 
0

Вы также можете использовать понимание, чтобы получить опцию «head», если вы были так склонны. Я бы предпочел @Shadowlands ответить, потому что это немного более лаконично, но это будет работать также:

val headOpt = 
    for{ 
    list <- listOpt 
    head <- list.headOption 
    } yield head 
Смежные вопросы