2012-09-16 5 views
3

스칼라에서 List (선택 사항 : Option)을 사용하고 있습니다. 예를 들어, 에서 for의 이해력을 사용하고 수익률이 Option 인 경우 발생합니다. 제 경우에는 JSON 객체를 처리하고 필드 목록 (List[JField])에서 for을 사용합니다.0 또는 1 옵션으로 목록을 여는 가장 좋은 방법은 무엇입니까?

목록을 열어 List()None으로, List(Some(a))Some(a)으로 매핑하는 가장 좋은 방법은 무엇입니까?

첫 번째 접근 방식은 개인적으로 세 번째 접근 방식을 선호

def headOrNone[A](list:List[Option[A]]) = 
    list match { 
     case Nil => None 
     case a::Nil => a 
    } 

또 다른 방법

def headOrNone[A](list:List[Option[A]]) = list.headOption.getOrElse(None) 

세 번째 접근합니다 (headOption 구현의 변형)

def headOrNone[A](list:List[Option[A]]) = if (list.isEmpty) None else list.head 

될 것이다. headOrNone보다이 함수에 더 좋은 이름이 있습니까? 쓰는 관용적 인 스칼라 방법은 무엇입니까?

답변

5

이 방법에 대해 :

def headOrNone[A](list: List[Option[A]]) = list.flatten.headOption 

headOrNone(List(Some(4))) // Some(4) 
headOrNone(List())   // None 

첫 번째 선택은 당신이 당신의 설명에 따라, 오류 것 같아 하나 개 이상의 항목으로 목록을 가지고 일이면 당신에게 오류가주는 장점을 가지고 있지만 조건.

개인적으로, 나는 List[Option[A]]을 생성하는 코드를 다시 평가하고 처음부터 올바른 것을 돌려 줄 수있는 방법이 있는지 살펴볼 것입니다!

+0

세 번째 옵션은 headOption 구현의 변형이므로 가장 효율적으로 보입니다. 왜 둘째를 좋아하니? –

+0

@ 마리우스, 내 업데이트를 참조하십시오. – dhg

+0

좋은 flatten.headOption, Out에서 다시 Option으로 :) 코드를 다시 작성하려고합니다. –

6

당신은 아마도 만들어져서는 안되는 문제를 해결하고 있습니다. 대신, 당신은 아마

list.flatMap(f) 

을 할

for (x <- list) yield f(x) // Yields Option 

를 원하는 당신은 (당신이 추출 할 수 headOption를 사용)로 시작하는 목록에서 0 또는 1 중 하나 일을해야합니다.

관련 문제