scala - 高阶滤波函数
问题描述
下面是我用来过滤列表数据的滑动窗口的代码,并且数据的每个元素都匹配一个谓词,然后过滤数据:
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
}
但同样,也许有更好的方法来实现这一点。
解决方案
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)
推荐阅读
- c# - Mac 上的 Visual Studio 2019 在 asp.net 核心项目运行时崩溃
- spring - Spring MVC - 无法登录
- php - 如何修复警告:非法字符串偏移“描述”
- python - “with”语句是否支持类型提示?
- python - PySpark - 如何使用 jdbc 连接更新 Kudu 表?
- python - FFMPEG - 为什么我不能录制超过 10 秒的视频?
- bash - 为什么使用 += 在 bash 中存储命令的退出状态?
- java - 如何使用 Mockito 通过注解注入模拟集合
- active-directory - 将 Microsoft Bot v4 与 ServiceNow 集成
- ietf-netmod-yang - 不可读 - YANG