Below is code I use to filter over a sliding window of list data and each of the elements of data match a predicate then the data is filtered :
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)
prints :
(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)))
this works as expected but is there a more idiomatic way to declare and call the function f ?
The threshold value is set outside the function f which seems like a bad coding practice as threshold declared outside the f but I'm not sure if any alternatives exist. Also I may want to introduce more complicated filter logic such as :
val upperThreshold = 0
val lowerThreshold = -5
def f(percentChange : Double) = {
percentChange > lowerThreshold and percentChange <= upperThreshold
}
But again, there are perhaps better ways to achieve this.
Scastie : https://scastie.scala-lang.org/PQLodmTPTvihEiYGgWAAvg