【问题标题】:Higher order filter function高阶滤波函数
【发布时间】:2021-03-02 13:59:46
【问题描述】:

下面是我用来过滤列表数据的滑动窗口的代码,并且数据的每个元素都匹配一个谓词,然后过滤数据:

val data  : Map[String, List[Double]] = Map(
  "a" -> List(0.086, -0.398, -0.398, -0.312, 0.312, 0.312, 0.312, 0.312, 0.312, 0.312),
  "b" -> List(-0.119, -0.119, 1.007, 1.201, 1.201, 1.201, -1.201, 1.201, -1.201, -1.201)
)

def getChanges(f : Double => Boolean, data : Map[String, List[Double]], windowSize : Int) = {

  val result = data.map {
    case (key, value) => key -> value.sliding(windowSize).filter(_.forall(f)).toList
  }.filter {
    case (_, values) => values.nonEmpty
  }
   result
}


val threshold = 0
def f(percentChange : Double) = {
    percentChange > threshold
}

getChanges(f , data , 2).foreach(println)

打印:

(a,List(List(0.312, 0.312), List(0.312, 0.312), List(0.312, 0.312), List(0.312, 0.312), List(0.312, 0.312)))
(b,List(List(1.007, 1.201), List(1.201, 1.201), List(1.201, 1.201)))

这按预期工作,但有没有更惯用的方式来声明和调用函数 f ? 阈值设置在函数f 之外,这似乎是一种不好的编码习惯,因为在f 之外声明了阈值,但我不确定是否存在任何替代方案。另外我可能想介绍更复杂的过滤器逻辑,例如:

val upperThreshold = 0
val lowerThreshold = -5
def f(percentChange : Double) = {
    percentChange > lowerThreshold and percentChange <= upperThreshold
}

但同样,也许有更好的方法来实现这一点。

斯卡斯蒂:https://scastie.scala-lang.org/PQLodmTPTvihEiYGgWAAvg

【问题讨论】:

  • 我不确定问题是什么?如果不想在函数内部定义阈值,那就去做吧,有什么问题?
  • 这个问题和你的previous有什么不同?

标签: scala


【解决方案1】:

如果你用第二个参数列表定义getChange会更好:

def getChanges(data: Map[String, List[Double]], windowSize: Int)(f: Double => Boolean) = ???

现在,您可以将过滤器定义为 lambda(好吧,公平地说,您也可以使用原始方法将其设为 lambda,只是看起来不那么漂亮),并摆脱阈值定义:

   getChanges(data , 2) { p => p >= -5 && p <= 0 }
     .foreach(println)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    相关资源
    最近更新 更多