Функция forEach, поддерживающая пошаговое выполнение

#kotlin

Вопрос:

В Kotlin я хочу просмотреть список элементов с шагом 2. Это было бы сделано так:

 for (i in 0..users.lastIndex step 2) {
   val user = users[i]
}
 

Это нормально, но было бы лучше, если бы было что-то еще более простое, такое как forEach. Но forEach не обеспечивает пошагового выполнения. Существует ли API, который позволяет вам выполнять пошаговые действия в режиме forEach? Что-то вроде этого:

 users.forEach(step = 2) { user ->
   
}
 

Комментарии:

1. for (i in users.indices step 2) { }

Ответ №1:

Насколько я знаю, в стандартной библиотеке Котлина такой функции нет. Тем не менее, создать собственную функцию расширения не слишком сложно:

 inline fun <T> List<T>.forEachStep(step: Int = 1, action: (T) -> Unit) {
    /*
     * May want to have an iterator-based solution as well for lists that
     * don't support random access. You could choose which solution to
     * use based on 'if (this is RandomAccess)'.
     */
    for (i in indices step step) {
        action(get(i))
    }
}
 

Который вы затем можете использовать на любом List .

 val users: List<User> = ...
users.forEachStep(step = 2) { user ->
    // do something...
}
 

Ответ №2:

Использование forEach для замены цикла for противоречит соглашениям о кодировании Kotlin, которые также содержат напоминание о необходимости учитывать соображения производительности при цепочке функций более высокого порядка. Стоит иметь в виду, прежде чем вы начнете сходить с ума от функций расширения 🙂

Предпочитайте циклам функции более высокого порядка ( filter и map т. Д.). Исключение: forEach (вместо этого предпочтите использовать обычный for цикл, если только приемник forEach не может быть обнулен или forEach не используется как часть более длинной цепочки вызовов).

Делая выбор между сложным выражением, использующим несколько функций более высокого порядка, и циклом, поймите стоимость выполняемых операций в каждом конкретном случае и учитывайте соображения производительности.