2012-05-18 75 views
2

我有Option[Set[String]]型,我想在收集filter方法使用的斯卡拉值:過濾的斯卡拉選擇[設置]

val opt: Option[Set[String]] = ... 

collection.filter { 
    value => 
    opt match { 
    case Some(set) => set.contains(value) 
    case None => true 
    } 
} 

如果optSome(...)我想用封閉Set過濾集合,否則我想包括集合中的所有項目。

有沒有更好的(更地道)的方式來使用OptionmapfiltergetOrElse等)?

opt來自可選命令行參數,其中包含要包含的術語列表。如果缺少命令行參數,則包含所有術語。

回答

6

我會用事實Set[A]擴展A => Boolean和傳遞常數函數返回truegetOrElse

val p: String => Boolean = opt.getOrElse(_ => true) 

或者:

val p = opt.getOrElse(Function.const(true) _) 

現在你可以隨便寫collection.filter(p)。如果你想要一個一行,下面的任也能發揮作用:

collection filter opt.getOrElse(_ => true) 
collection filter opt.getOrElse(Function.const(true) _) 
+0

Function.const(...)的目的是什麼? –

+1

@ om-nom-nom http://stackoverflow.com/questions/5924875/whats-the-purpose-of-function-const – tenshi

+0

如果集合包含一個自定義類而不是'String',有什麼方法可以檢查其中一個實例字段(例如'name')使用你的方法?如果在集合上執行'map'將其轉換爲'String',那麼我將丟失課程內容,我稍後在方法鏈中需要這些內容。順便說一句,你的方法已經很好地爲我的String集合工作。謝謝。 – Ralph

4

這似乎有點浪費在_ => true過濾,所以我寧願

opt match { 
    case Some(s) => collection filter s 
    case None => collection 
} 

我猜,這相當於:

opt map (collection filter) getOrElse collection 
+0

我同意你的解決方案比原始版本更清潔,對於大型集合,內部循環等可能更好,但在這種情況下,它覺得過早優化 - 這是一種大概只發生一次的操作,並且在非常小的集合(命令行參數),所以我會選擇更具表現力的版本。 –