2012-09-16 42 views
3

在斯卡拉我有一個List與可選Option。例如,當您在List上使用for時,您的收益率將返回Option。在我的情況下,我正在處理一個JSON對象並在字段列表(List[JField])上使用for理解。打開0或1個選項列表的最佳方式是什麼?

什麼是最好的方式來打開清單和地圖List()NoneList(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

@Marius,看我的更新。 – dhg

+0

Nice flatten.headOption,出來,然後回到選項:)我會嘗試重寫代碼。 –

6

您正在解決可能不應該創建的問題。相反,你可能想

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

list.flatMap(f) 

,然後你必須在你的列表中零個或一個事物開始(使用headOption您可以提取)。

相關問題