Я ищу в Котлине метод, который возвращает мне из списка новый список с определенным количеством элементов (например, 10). Каким бы ни был размер списка, метод всегда будет возвращать одно и то же количество элементов.
Например, предположим, что список из 3000 элементов вернет мне список из 10 элементов с индексами 0, 300, 600, 900, 1200,...
Есть ли функция расширения для этого?





Вот идея:
Воспользуйтесь преимуществами метода chunked(size: Int), который пытается разделить данную коллекцию на подколлекции заданного размера.
Это не совсем то, что вам нужно, но вы можете использовать его для реализации пользовательской функции расширения, которая делает то, что вы хотите, например. как это:
fun List<Int>.departInto(subListCount: Int) : List<List<Int>> {
// calculate the chunk size based on the desired amount of sublists
val chunkSize = this.size / subListCount
// then apply that value to the chunked method and return the result
return this.chunked(chunkSize)
}
Использование этого может выглядеть следующим образом:
fun main() {
// define some example list (of 30 elements in this case)
val someList: List<Int> = List(30, {it})
// use the extension function
val tenSubLists = someList.departInto(10)
// print the result(s)
println(tenSubLists)
}
Результатом этого кода будет 10 подсписков из 3 элементов (ваш пример из 3000 элементов приведет к 10 подспискам по 300 элементов в каждом):
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14], [15, 16, 17], [18, 19, 20], [21, 22, 23], [24, 25, 26], [27, 28, 29]]
Это своего рода специализированная вещь, поэтому в стандартной библиотеке нет ничего (о чем я знаю), но вы можете легко создать свою собственную функцию расширения:
fun <T: Any> List<T>.sample2(count: Int): List<T> {
// this allows for a fractional step, so we get a more accurate distribution of indices
// with smaller lists (where count doesn't divide into the list size evenly)
val step = size / count.toFloat()
return List(count) { i -> elementAt((i * step).toInt()) }
}
Вы получите повторы, если ваш список слишком мал, чтобы предоставить count уникальные индексы (например, в вашем списке 9 элементов, а вы хотите 10), поэтому вам придется справиться с этим, если вы хотите другое поведение, но я думаю, что это самый простой способ сделать это
Не могли бы вы уточнить вопрос, пожалуйста? Из текста видно, что вы можете просто взять первые n элементов (например, используя существующую функцию
take()), но из примера видно, что вы хотите взять элементы равномерно распределить по всему входного списка. (Кроме того, вы не указываете, что должно произойти, если во входном списке меньше элементов, чем вам нужно.)