在集合类型中获得当前极值的最佳方法

fly*_*eep 6 scala max min option

我现在有点累了所以我可能会错过这个显而易见的事情.

我有一个var _minVal: Option[Double],它将保存Doubles 集合中包含的最小值(如果集合为空,则为None)

在向集合添加新项目时,我也检查是否_minVal为None或大于新项目(=新mimimum的候​​选项).

我已经离开了

_minVal = Some(_minVal match {
    case Some(oldMin) => if (candidate < oldMin) candidate
                         else                    oldMin
    case None         =>                         candidate
})
Run Code Online (Sandbox Code Playgroud)

(不是很干)来

_minVal = Some(min(_minVal getOrElse candidate, candidate))
Run Code Online (Sandbox Code Playgroud)

但仍然认为我可能会遗漏一些东西......

Dan*_*ral 10

没有Scalaz,你将支付一些RY.但我会把它写成:

_minVal = _minVal map (candidate min) orElse Some(candidate)
Run Code Online (Sandbox Code Playgroud)

编辑

埃里克Torreborre规格/Specs2名气,还跟追求Scalaz已经躲避我的解决方案.作为一个测试框架的人,他以测试格式编写答案,而不是命令性的副作用原文.:-)

这里的版本使用_minVal,Double而不是Int,副作用,而现在我的一些波折,埃里克所做的辛勤工作.

// From the question (candidate provided for testing purposes)
var _minVal: Option[Double] = None
def candidate = scala.util.Random.nextDouble

// A function "min"
def min = (_: Double) min (_: Double)

// A function "orElse"
def orElse = (_: Option[Double]) orElse (_: Option[Double])

// Extract function to decrease noise
def updateMin = _minVal map min.curried(_: Double)

// This is the Scalaz vesion for the above -- type inference is not kind to it
// def updateMin = (_minVal map min.curried).sequence[({type lambda[a] = (Double => a)})#lambda, Double]

// Say the magic words
import scalaz._
import Scalaz._   

def orElseSome = (Option(_: Double)) andThen orElse.flip.curried
def updateMinOrSome = updateMin <*> orElseSome

// TAH-DAH!
 _minVal = updateMinOrSome(candidate)
Run Code Online (Sandbox Code Playgroud)

  • 如果您发布非重复的scalaz版本,请+1! (3认同)
  • 或者`_minVal = _minVal map(候选min)orElse Some(候选人)`,是的. (2认同)
  • 嗯,@ huynhjl,我把它贴在了你的上方.另外,我是第二个Luigi对scalaz版本的请求.我主要是不使用它,因为我认为它会导致"也许我现在可以修改我的整个代码库"综合症;) (2认同)

Eri*_*ric 7

以下是使用Scalaz对Daniel的回答的更新:

这是一个咖喱'min'功能:

def min = (i: Int) => (j: Int) => if (i < j) i else j 
Run Code Online (Sandbox Code Playgroud)

和2个变量:

// the last minimum value
def lastMin: Option[Int] = None

// the new value
def current = 1
Run Code Online (Sandbox Code Playgroud)

现在让我们定义2个新功能

// this one does the minimum update
def updateMin = (i: Int) => lastMin map (min(i))

// this one provides a default value if the option o2 is not defined
def orElse = (o1: Int) => (o2: Option[Int]) => o2 orElse Some(o1)
Run Code Online (Sandbox Code Playgroud)

然后使用@dibblego关于为什么Function1 [T,_]是一个应用函子的优秀解释,我们可以避免重复'current'变量:

(updateMin <*> orElse).apply(current) === Some(current)
Run Code Online (Sandbox Code Playgroud)