Reputation: 53916
Below I've defined a function that splits a List into windows and applies a function to each sub list of size 4:
def getValue(windowSize : Int, stepSize : Int, values: List[Double] , multiplier : Double) = {
values.sliding(windowSize, stepSize).map({
case List(v1, v2, v3, v4) =>
(List(v1,v2,v3,v4) , (v2 >= (v1 * multiplier) && v3 >= (v2 * multiplier)), v4 > v3)
}).toList
}
val data = List(5.0, 15.0, 45.0, 8.0, 5.0, 15.0, 45.0, 60.0)
getValue(4,4,data , 2).foreach(println)
I want to be able to vary the size of the window of the List, for example, if I define a sliding window of size 5 and step size 5 then it should match as follows:
case List(v1, v2, v3, v4, v5) =>
(List(v1,v2,v3,v4,v5) , (v2 >= (v1 * multiplier) && v3 >= (v2 * multiplier) && v4 >= (v3 * multiplier)), v5 > v4)
I could explicitly add a new case statement like:
def getValue(windowSize : Int, stepSize : Int, values: List[Double] , multiplier : Double) = {
if windowSize == 4 && stepSize == 4 {
values.sliding(windowSize, stepSize).map({
case List(v1, v2, v3, v4) =>
(List(v1,v2,v3,v4) , (v2 >= (v1 * multiplier) && v3 >= (v2 * multiplier)), v4 > v3)
}).toList
}
if windowSise == 5 && stepSize == 5 {
values.sliding(windowSize, stepSize).map({
case List(v1, v2, v3, v4, v5) =>
(List(v1,v2,v3,v4,v5) , (v2 >= (v1 * multiplier) && v3 >= (v2 * multiplier) && v4 >= (v3 * multiplier)), v5 > v4)
}).toList
}
But then I need to add a new case each time I wish to vary the window size. Is there a more generic way to define this method using Scala, where I don't need a custom case
pattern matching on the size of the list?
Upvotes: 1
Views: 135
Reputation: 51271
Not terribly efficient but I think this does what you ask.
def getValue(groupSize: Int, values: List[Double], multiplier: Double) =
values.grouped(groupSize).collect{
case lst if lst.lengthIs == groupSize =>
( lst
, lst.sliding(2).toList.init
.forall{case List(a,b) => b >= (a*multiplier)}
, lst.last > lst(groupSize-2)
)
}.toList
Upvotes: 3