如何找到两个Option [Int]的min()或max()

Gra*_*Lea 7 scala max min option

你怎么在minValue下面找到?我有自己的解决方案,但想看看别人会怎么做.

val i1: Option[Int] = ...
val i2: Option[Int] = ...
val defaultValue: Int = ...
val minValue = ?
Run Code Online (Sandbox Code Playgroud)

Tra*_*own 8

更新:我刚刚注意到我的解决方案和你的答案中的解决方案表现不同 - 我读到你的问题是当有两个值要求两个值中的最小值,但在你的答案中你有效地将其None视为包含一个比其他任何东西更大(min更小)或更小(max替代)的值.

更具体的:如果i1Some(1)i2None,我的解决方案将返回默认值,而你将返回1.

如果你想后者的行为,你可以使用半群实例的默认Option[A]热带半群Int.例如,在Scalaz 7中,你会写:

import scalaz._, Scalaz._

optionMonoid(Semigroup.minSemigroup[Int]).append(i1, i2) getOrElse defaultValue
Run Code Online (Sandbox Code Playgroud)

或者以下简写:

Tags.Min(i1) |+| Tags.Min(i2) getOrElse defaultValue
Run Code Online (Sandbox Code Playgroud)

它不像下面的applicative functor解决方案那么干净,但如果这是你的问题,那就是你的问题.


这是一种更惯用的方式,不涉及创建额外的列表:

(for { x <- i1; y <- i2 } yield math.min(x, y)) getOrElse defaultValue
Run Code Online (Sandbox Code Playgroud)

或者,等效地:

i1.flatMap(x => i2.map(math.min(x, _))) getOrElse defaultValue
Run Code Online (Sandbox Code Playgroud)

你正在做的是将一个两位函数(min)提升到一个applicative functor(Option)中.Scalaz通过其应用程序构建器语法简化了这一过程:

import scalaz._, Scalaz._

(i1 |@| i2)(math.min) getOrElse defaultValue
Run Code Online (Sandbox Code Playgroud)

在这种情况下,标准库解决方案并不是那么优雅,但这是一个有用的抽象知识.


Vla*_*kov 6

我使用以下方法解决了类似的问题。当两个选项都有值时,我们处理一种特殊情况,否则我们使用 API 方法Option.orElse

val a: Option[Int]  = Some(10)
val b: Option[Int] = Some(20)
val c: Option[Int] = (a, b) match {
  case (Some(x), Some(y)) => Some(x min y)
  case (x, y) => x orElse y
}
Run Code Online (Sandbox Code Playgroud)


Lui*_*hys 3

我想这就是你所追求的:

val minValue = List(i1, i2).flatten match {
  case Nil => defaultValue
  case xs => xs.min
}
Run Code Online (Sandbox Code Playgroud)

我会避免,sorted因为排序需要比简单地查找最大值或最小值更多的处理(尽管在这种情况下可能没有太大区别)。