When using a sliding
function on an Array
in scala, what is a correct way to track the index of the sliding subarray in terms of the original array?
// Initialize some data
val bigArray = List(2, 3, 4, 2, 3, 6, 8, 4, 5).toArray
val n:Int = 5
// Slide through the big array
for (smallArray <- bigArray.sliding(n)) {
val thirdValue:Int = smallArray(3)
val k = (bigArray zip smallArray) lastIndexWhere { case (x, y) => x < y }
if (bigArray(k+1) >= thirdValue) {
println(bigArray.toList.toString +
" has "
+ bigArray(k+1)
+ " >= "
+ thirdValue
+ " in "
+ smallArray.toList.toString
+ " at index "
+ k+1)
}
Now I know that
val k = (bigArray zip smallArray) lastIndexWhere { case (x, y) => x < y }
is incorrect. What is the correct way to track where the smallArray
is in terms of the original bigArray
?
What I'm getting is
List(2, 3, 4, 2, 3, 6, 8, 4, 5) has 2 >= 2 in List(2, 3, 4, 2, 3) at index -11
List(2, 3, 4, 2, 3, 6, 8, 4, 5) has 6 >= 3 in List(3, 4, 2, 3, 6) at index 41
List(2, 3, 4, 2, 3, 6, 8, 4, 5) has 6 >= 6 in List(4, 2, 3, 6, 8) at index 41
List(2, 3, 4, 2, 3, 6, 8, 4, 5) has 6 >= 4 in List(3, 6, 8, 4, 5) at index 41
and I need
List(2, 3, 4, 2, 3, 6, 8, 4, 5) has 6 >= 2 in List(2, 3, 4, 2, 3) at index 5
List(2, 3, 4, 2, 3, 6, 8, 4, 5) has 8 >= 3 in List(3, 4, 2, 3, 6) at index 6
Update
I couldn't get map
to work with the tuple2(Int, Int)
that came from head
in the accepted answer, but the mention of zipWithIndex
got me there, so I accepted the helpful answer. This is what I ended up with:
for (zipArray <- bigArray.slice(0, bigArray.length - 1).zipWithIndex.sliding(n)) {
val j = zipArray.head._2
val k = zipArray.last._2
val smallArray = bigArray.slice(j, k)
val thirdValue:Int = smallArray(3)
if (bigArray(k+1) >= thirdValue) {
println(bigArray.toList.toString +
" has "
+ bigArray(k+1)
+ " >= "
+ thirdValue
+ " in "
+ smallArray.toList.toString
+ " at index "
+ (k+1) )
}
}
which yields:
List(2, 3, 4, 2, 3, 6, 8, 4, 5) has 6 >= 2 in List(2, 3, 4, 2) at index 5
List(2, 3, 4, 2, 3, 6, 8, 4, 5) has 8 >= 3 in List(3, 4, 2, 3) at index 6
You can use zipWithIndex
before sliding
:
for (smallArrayWithIndex <- bigArray.zipWithIndex.sliding(n)) {
val startingIndex = smallArrayWithIndex.head.map { case (_, index) => index }
val smallArray = smallArrayWithIndex.map { case (e, _) => e }
println("smallArray starts at index " + index + " and contains " + smallArray)
}