(Kotlin newbie here)
I have a long array of Booleans and I want to extract from it the index positions of TRUE followed by FALSE patterns. For example, this array
arrayOf(true, false, true, false, true, false)
should produce
[0, 2, 4]
but this one
arrayOf(true, false, false, false, true, false)
should produce
[0, 4]
Here's a fun for that except, of course, the 3rd example will crash Java:
fun main() {
println(dontCrash(arrayOf(true, false, true, false, true, false)))
println(dontCrash(arrayOf(true, false, false, false, true, false)))
println(dontCrash(arrayOf(true, false, false, false, true, true)))
}
fun dontCrash(a: Array<Boolean>): List<Int> {
val goodGuys = mutableListOf<Int>()
for ((ind, element) in a.withIndex())
if (element && !a[ind 1]) goodGuys.add(ind)
return goodGuys
}
[0, 2, 4]
[0, 4]
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 6 out of bounds for length 6
My question: Does Kotlin have some cute trick to deal this (step??) or do I need to add a .size() check?
Thank you!
CodePudding user response:
windowed(2)
or zipWithNext()
lets you slide along pairs of adjacent values without going past the bounds, but it's only available for Iterables and Sequences, not arrays:
fun dontCrash(a: Array<Boolean>): List<Int> {
a.asSequence()
.zipWithNext()
.mapIndexedNotNull { i, (a, b) -> i.takeIf { a && !b } }
.toList()
}