FilterIndex provides a Traversal that can focus into a structure S and get, set or modify 0 to N foci whose index I satisfies a predicate.

If for a structure S the foci A can be indexed by I then a Traversal can be created by FilterIndex that is filtered by a predicate on I.

FilterIndex can easily be created given a Traverse instance and an indexing function.

import arrow.core.*
import arrow.optics.*
import arrow.optics.typeclasses.*

val filterIndexStringByIndex = FilterIndex.fromTraverse<ForListK, String>({ list ->
    list.fix().map {
        it toT it.length
}, ListK.traverse())

Given a FilterIndex instance we can create a Traversal that filters out the foci that do not match the predicate.

val filter: Traversal<ListKOf<String>, String> = filterIndexStringByIndex.filter { length -> length > 3 }

filter.getAll(listOf("H", "He", "Hel", "Hell", "Hello").k())
// ListK(list=[Hell, Hello])

Arrow provides FilterIndex instances for some common datatypes both in Arrow and the Kotlin stdlib that can be filtered by index, like ListK and MapK. You can look them up by calling FilterIndex.filterIndex().

FilterIndex.filterIndex<ListKOf<Int>, Int, Int> { index -> index % 2 == 0 }
            .getAll(listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).k())
// ListK(list=[0, 2, 4, 6, 8])


The following datatypes in Arrow provide instances that adhere to the FilterIndex typeclass.