2016-11-10 38 views
1

在這裏,我試圖從(String , Option[Int])列表中移除None類型,其中None類型可以是在元組位置2:如何從列表[(String,Option [Int])]中刪除無類型?

val l : List[(String , Option[Int])] = List(
     ("a" , None), 
     ("b" , Option(1)), 
     ("c" , Option(2)) 
    ) 

val filteredSomes = for { 
    (e <- l) 
     if(e._2 >= 0) 
} yield e 

println(filteredSomes); 

但是,這並不編譯:

原因錯誤:

')' expected but '<-' found. 
[error]     (e <- l) 
[error]     ^

可以使用flatten而不是每個?

回答

5

類似於瑞士Cheseaux的答案,但更地道:

l.filter(_._2.isDefined) 
+2

哪裏非負約束?如果我正確理解OP要的是什麼,表達式應該是'l.filter(_._ 2.exists(_> = 0))'。 – Jubobs

+0

哦,我沒有看到那部分。您也可以摺疊選項: 1.filter(_._ 2.fold(false)(_> = 0)) 哪一個basicall表示如果_._ 2是None,則返回false,否則返回結果> = 0 – rleibman

2

爲什麼不乾脆

l.filter(_._2 != None) 

或者,如果你真的想使用for comprehensions形式來表達它,你可以做這樣的

for(e <- l; if (e._2 != None)) yield e 
2

您可以使用具有某些圖案墊的過濾器來完成相同的操作清:

val filteredSomes = l.filter { 

    // This is the only case that you want to pass your filter. 
    // We are pattern matching the tuple and saying that we don't 
    // care about the String's value but we want the Option[Int] 
    // to be defined and be greater-than-or-equal to zero 
    case (_, Some(i)) if i >= 0 => true 

    // Any other case should not pass the filter 
    case _ => false 
} 

這裏是斯卡拉REPL

scala> val l : List[(String , Option[Int])] = List(("a" , None), ("b" , Option(1)), ("c" , Option(2))) 
l: List[(String, Option[Int])] = List((a,None), (b,Some(1)), (c,Some(2))) 

scala> l.filter { 
    |  case (_, Some(i)) if i >= 0 => true 
    |  case _ => false 
    | } 
res6: List[(String, Option[Int])] = List((b,Some(1)), (c,Some(2))) 
+1

儘管在Option中模式匹配通常是一種代碼味道。有很多有用的'Option'組合器,幾乎不需要模式匹配。例如,請參閱https://www.youtube.com/watch?v=ol2AB5UN1IA – Jubobs

+0

更簡潔地說:'for(a @(_,Some(b))<- l if b > 0)yield a' –

+0

@Jubobs我會說這個有一種情況是在Option中進行模式匹配可能更受歡迎,因爲它可以讓我們更清楚地知道'i'的來源。另一方面,當映射到文字'true'或'false'時,通常有更好的方法。 –

0

另一種選擇是一個例子使用collect

List(
    ("a" , None), 
    ("b" , Option(1)), 
    ("c" , Option(2)), 
    ("d", Option(-1)) 
) collect {case t @ (_, Some(i)) if i >= 0 => t} 
//result: List((b,Some(1)), (c,Some(2))) 
相關問題