Scala的选项[SEQ [A]]存在

问题描述:

我有以下代码: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'是更优雅和安全的方法。 –

通过@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 true case _ => false}'。你怎么看? –

+0

我同意@Reactormonk的说法,它在'None'情况下更具可读性。你的解决方案@Andrii很好,但是我个人认为,对于读取代码的人来说,使用'map'然后通过'Option [Boolean]'匹配模式可能会更困难。 –

另一种可能性。

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)更具可读性。 –