2017-08-30 103 views
0

我有以下代碼:Scala的選項[SEQ [A]]存在

case class Person(name: String, age: Int) 

object Launcher extends App { 

    val people = Option(Seq(Person("Andrii", 20), Person("John", 35), Person("Sam", 15))) 

    def filterPeople(list: Option[Seq[Person]]): Boolean = 
    list.getOrElse(Nil) 
     .exists(_.age < 18) 

    assert(filterPeople(people) == true) 
} 

的問題是:我可以處理Option[Seq[A]]更優雅和安全而不getOrElse(Nil)

list.getOrElse(Nil) 
     .exists(_.age < 18) 

我已經找到另一種方法是:

list.exists(_.exists(_.age > 18)) 

注:我有Option[Seq[A]]只是因爲REST合同。

+0

「注:我有僅僅因爲REST合同,選項[Seq [A]]。「 在這種情況下,我懷疑您經常需要將'None'和'Some(Nil)'視爲等價物,並且'getOrElse(Nil)'會自動處理所有這些情況,以「摺疊」或「存在」的方式。 所以我會說'getOrElse'是更優雅和安全的方法。 –

回答

1

通過@NimrodArgov尖,我寧願使用模式檢查列表類型,因爲它更具有可讀性匹配:

def filterPeople(list: Option[Seq[Person]]): Boolean = { 
    list match { 
    case Some(people) => people.exists(_.age < 18) 
    case None => false 
    } 
} 
+1

這裏使用'case None',因此編譯器可以檢查完整的模式匹配。有時候'case''有點危險,最好不要成爲一種習慣。 – Reactormonk

+0

謝謝,這是目前如何實施的方式。我同意你的看法,它很可讀。還有一個選項(一個人傷心,它是慣用的單子):'list.map(_。exists(_。age <18))match {case Some(true)=> true case _ => false}'。你怎麼看? –

+0

我同意@Reactormonk的說法,它在'None'情況下更具可讀性。你的解決方案@Andrii很好,但是我個人認爲,對於讀取代碼的人來說,使用'map'然後通過'Option [Boolean]'匹配模式可能會更困難。 –

1

另一種可能性。

def filterPeople(list: Option[Seq[Person]]): Boolean = 
    list.fold(false)(_.exists(_.age < 18)) 

測試:

filterPeople(people) // res0: Boolean = true 
filterPeople(None) // res1: Boolean = false 
+2

我更喜歡模式匹配,因爲它使代碼更具可讀性。 – Kraylog

+0

謝謝。 「摺疊」方法對我來說很好。它比getOrElse(Nil)更具可讀性。 –