【问题标题】:Idiomatically evaluate true if Option contains specific value如果 Option 包含特定值,则惯用地评估 true
【发布时间】:2014-10-02 16:17:54
【问题描述】:

如果Option[Int] 包含特定值,我想编写一个返回true 的方法,否则返回false。这样做的惯用方式是什么?

var trueIf5(intOption: Option[Int]): Boolean {
  intOption match {
    case Some(i) => i == 5
    case None => false
  }
}

上述解决方案显然有效,但 Scala 文档将此方法标记为 less-idiomatic

有什么方法可以让我使用mapfilter 或其他方法来做同样的事情吗?

我已经做到了这一点,但它只是将问题更改为“如果 Option 包含 true,则返回 true”,这实际上与“如果 Option 包含 5,则返回 true”相同。

var trueIf5(intOption: Option[Int]): Boolean {
  intOption.map(i => i == 5).???
}

【问题讨论】:

  • exists 是正确答案,但您上面的??? 将是.getOrElse(false)。然后你认识到你有.map(f).getOrElse(z) 并称之为.fold(z)(f)。然后你意识到(在Option.fold(false).exists.fold(true).forall

标签: scala


【解决方案1】:

因为你正在测试它是否包含一个值:

scala> Some(42) contains 42
res0: Boolean = true

不要忽视你的-Xlint

scala> Option(42).contains("")
res0: Boolean = false

scala> :replay -Xlint
Replaying: Option(42).contains("")
<console>:12: warning: a type was inferred to be `Any`; this may indicate a programming error.
       Option(42).contains("")
                           ^
res0: Boolean = false

那些内置的警告在普遍平等中没有那么有效:

scala> Option(42).exists("" == _)    // no warning
res1: Boolean = false

【讨论】:

  • 最后,我现在正在使用这两种解决方案。我希望我可以将它们都标记为答案。你有我的赞成票,但@sjrd 因为他的时间安排而获得了绿色支票。反正你不需要额外的代表;)
  • 我不知道为什么这些方法在 scaladoc 中是不可见的。
  • 如果您将Option 视为容器,恕我直言,此方法比现有方法更惯用。不错!
【解决方案2】:
intOption.exists(_ == 5)

The doc

【讨论】:

  • Option[T]视为0或1的序列T是正确的方法。
【解决方案3】:

为什么没有人建议:

intOption == Some(5)

【讨论】:

  • 通常你会尽量避免额外的分配,但其他答案至少在某些情况下会产生分配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-01
  • 2013-04-02
  • 2021-08-26
  • 2020-05-08
  • 1970-01-01
  • 2016-02-12
  • 2021-03-23
相关资源
最近更新 更多