отфильтровать список до определенного размера в Kotlin / Java - PullRequest
0 голосов
/ 07 июня 2019

Я ищу наиболее эффективный способ в Kotlin / Java для фильтрации List по определенному количеству и с удалением отфильтрованных элементов, применяемых ко всей коллекции в унифицированном виде (т. Е. равномерно убрал промежуток по всей коллекции);

Например

  • отфильтровать следующее до 5 [0,1,2,3,4,5,6,7,8,9] = [0,2,4,6,8]

  • отфильтровать следующее до 2 [1 100 000 000 100] = [1 1000]

Я придумал следующую функцию расширения Kotlin, но она не работает должным образом (ее возвращение превышает запрошенное число - например, начальный размер = 2593, newcount = 125 - список = 130)

fun <T> List<T>.filterDownByToCount(newCount: Int): List<T> {
    if (newCount < 0 || newCount >= this.size)
        throw IllegalArgumentException("prop ($newCount) must be between 1 and $newCount")
    val ratio = size / newCount
    val list = this.filterIndexed { index, _ -> index % ratio == 0 }
    return list
}

в идеале эта функция может обрабатывать что угодно, от 0 до list.size-1, и я хотел бы использовать библиотеку для этого (если это возможно), но, похоже, не могу найти такую, которая подходит для моего варианта использования.

Ответы [ 2 ]

1 голос
/ 07 июня 2019

Проблема в том, что отношение на самом деле является дробным числом, но вы выполняете целочисленную арифметику.

fun <T> List<T>.filterDownByToCount(newCount: Int): List<T> {
    if (newCount < 0 || newCount >= this.size)
        throw IllegalArgumentException("prop ($newCount) must be between 1 and $newCount")
    val ratio = size.toDouble() / newCount
    var accu = 0.0
    val list = this.filter { _ ->
        (accu <= 0).also { if (accu <= 0) accu += ratio; accu-- }
    }
    return list
}

Вы можете изменить соотношение на Double - для вашего примера это возвращаетрезультат 125 элементов.

1 голос
/ 07 июня 2019

Проблема в том, что size / newCount - это этаж отношения, поэтому отношение слишком мало, и, следовательно, вы получаете больше элементов, чем ожидаете.

Вместо этого используйте потолок:

val ratio = (size + newCount - 1) / newCount

Для вашего примера это список размером 124.

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