Ваша первоначальная попытка очень близка, только небольшое изменение заставляет ее работать.Отмените вызовы withIndex()
и drop(N)
, поставив withIndex
первым.
Если вы не хотите скопировать коллекциюВы можете сначала преобразовать его в последовательность, используя asSequence()
.
for ((index, item) in inputData.asSequence().withIndex().drop(startFrom)) { ... }
Тестовый код:
val sampleData = listOf("a", "b", "c", "d", "e", "f")
val startFrom = sampleData.size / 2
for ((index, item) in sampleData.asSequence().withIndex().drop(startFrom)) {
println("[$index] => $item")
}
вывод:
[3] => d[4] => е[5] => f
Вот и все!Остальная часть этого ответа просто предоставляет вам альтернативы, в том числе более эффективное и Kotlinesque решение создания вашей собственной функции расширения в конце.
Если копия коллекции приемлема, вы можете сделать следующую более короткую версию.withIndex
не вызывает копию, но drop(N)
делает.
for ((index, item) in inputData.withIndex().drop(startFrom)) { ... }
Стремительная копия или последовательность может быть быстрее, это зависит от размера коллекции, среда выполнения и кэш-память ЦП.
Вы также можете использовать функциональный forEach
вместо цикла for
.
sampleData.asSequence().withIndex().drop(startFrom).forEach { (index, item) ->
println("[$index] => $item")
}
Какойзатем выводит лучший и наиболее эффективный вариант. Просто напишите функцию расширения при использовании Array
или List
, чтобы не было ленивых вычислений с использованием классов-оберток или какого-либо копирования.Просто цикл, вызывающий вашу лямбду с индексом и значением.Вот два новых расширения, которые добавляют новый вариант forEachIndexed
:
inline fun <T> Array<T>.forEachIndexed(startFrom: Int,
action: (index: Int, item: T)->Unit) {
for (i in startFrom until this.size) {
action(i, this[i])
}
}
inline fun <T> List<T>.forEachIndexed(startFrom: Int,
action: (index: Int, item: T)->Unit) {
for (i in startFrom until this.size) {
action(i, this[i])
}
}
И это можно назвать просто для любого не примитивного массива или списка:
sampleData.forEachIndexed(startFrom) { index, item ->
println("[$index] => $item")
}
Youможет сделать то же самое, если вы хотите метод стиля withIndex(startFrom)
.Вы всегда можете расширить Kotlin, чтобы получить то, что вы хотите!