Как эффективно фильтровать необязательные параметры в Kotlin? - PullRequest
0 голосов
/ 21 июня 2019

Я работаю над Kotlin списком filter. Допустим, у меня есть список Worker экземпляров, и я хочу разработать функцию, которая фильтрует список по условию для startAge и maxSalary обнуляемых параметров.

Класс данных

data class Worker(name:String?, age: Int?, salary: Int?){

}

Функция FilterList ()

fun filterList(original: List<Worker>, startAge: Int?, maxSalary: Int?): List<Student>{
    val list = original.filter{
        it.age >= startAge && it.salary <= maxSalary
    }
    return list
}

В этот момент я хочу сконструировать функцию filterList таким образом, если любой параметр передается как null, это условие не должно быть пропущено. Как я могу это сделать? Например, позвонив с

val list = filterList(original, null, 100) должен возвращать список работников, чья максимальная зарплата составляет 100, но не имеет значения возраст.

Моя мысль

В этой конкретной задаче я могу выбрать значения по умолчанию startAge = Int.MAX_VALUE и maxSalary = Int.MIN_VALUE, когда null передается в параметрах. Но я думаю, что внутри фильтра может быть много условных проверок (например, сравнивать даты, проверять равенство строк, оценивать выражения и т. Д.), Которые не всегда можно покрыть значением default. Как мне избавиться от этого глюка?

Ответы [ 2 ]

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

Вы можете создать вспомогательную функцию isNullOr для проверки null или вызвать предикат в противном случае:

inline infix fun <T> T?.isNullOr(predicate: (T) -> Boolean): Boolean = if (this != null) predicate(this) else true

С этой функцией ваш оператор фильтра будет выглядеть так:

fun filterList(original: List<Worker>, startAge: Int?, maxSalary: Int?): List<Worker> {
    val list = original.filter { worker ->
        startAge isNullOr { worker.age >= it } && maxSalary isNullOr { worker.salary <= it }
    }
    return list
}
1 голос
/ 21 июня 2019

Вы можете использовать оператор Элвиса ?:, чтобы оценить возраст или зарплату до смешного значения (Int.MIN_VALUE или Int.MAX_VALUE), если параметр равен нулю.

it.age >= (startAge ?: Int.MIN_VALUE) && it.salary <= (maxSalary ?: Int.MAX_VALUE)

Если, скажем, startAge равно нулю, тогда it.age будет сравниваться с Int.MIN_VALUE, что всегда будет верным.То же самое касается maxSalary.

Но вы также должны решить, что произойдет, когда it.age или it.salary будет нулевым, чего вы не упомянули в вопросе.

Редактировать:

Если у вас нет значений по умолчанию, вы можете использовать ?.let, чтобы преобразовать необязательные параметры в необязательные логические значения, а затем используйте ?:, чтобы установить их по умолчанию true:

fun filterList(original: List<Worker>, startAge: Int?, maxSalary: Int?): List<Worker>{
    val list = original.filter{
        (startAge?.let { x -> it.age >= x } ?: true) && (maxSalary?.let { x -> it.salary <= x } ?: true)
    }
    return list
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...