【问题标题】:Scala Option[Seq[A]] existsScala Option[Seq[A]] 存在
【发布时间】:2017-08-30 23:08:12
【问题描述】:

我有以下代码:

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)
}

问题是:如果没有getOrElse(Nil),我能否更优雅、更安全地处理Option[Seq[A]]?

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

我找到了另一种方法:

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

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

【问题讨论】:

  • "注意:我有 Option[Seq[A]] 只是因为 REST 合同。"在这种情况下,我怀疑您经常需要将None 和Some(Nil) 视为等效,而getOrElse(Nil) 具有自动处理所有这些情况的好处,与fold 或 exists 接近。所以我想说getOrElse 是更优雅、更安全的方法。

标签: scala scala-collections scala-option


【解决方案1】:

@NimrodArgov 指出,我更喜欢使用模式匹配来检查列表类型,因为它更具可读性:

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

【讨论】:

  • 在这里使用case None,这样编译器就可以检查完整的模式匹配。 case _ 有时候有点危险,最好不要养成习惯。
  • 谢谢,这是目前的实现方式。我同意你的观点,它的可读性很强。还有另一种选择(一个人很遗憾它是惯用的单子):list.map(_.exists(_.age &lt; 18)) match { case Some(true) =&gt; true case _ =&gt; false }。你怎么看?
  • 我同意@Reactormonk 所说的,None 的案例更具可读性。您的解决方案@Andrii 很好,但就个人而言,我认为对于阅读代码的人来说,使用map 然后使用Option[Boolean] 进行模式匹配可能会更令人困惑。
  • @CamiloSampedro 我与您分享此选项。
【解决方案2】:

另一种可能性。

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

测试:

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

【讨论】:

  • 我更喜欢模式匹配,因为它使代码更具可读性。
  • 谢谢。 fold 方法对我来说看起来不错。它比getOrElse(Nil)更具可读性
猜你喜欢
  • 2021-08-31
  • 2019-03-03
  • 2020-07-16
  • 1970-01-01
  • 1970-01-01
  • 2019-09-23
  • 1970-01-01
  • 2016-06-13
  • 2011-12-10
相关资源
最近更新 更多