Найти элемент из списка, используя вложенное ключевое слово find в kotlin - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть класс enum, который будет содержать различные состояния приложения.

enum class State {
    STATE_1, STATE_2, STATE_4, READY, UNKNOWN
}

У меня будет список, содержащий эти состояния в некотором случайном порядке. Я хочу написать алгоритм, который будет возвращать определенное состояние, если другие состояния не доступны. Например:

val list = listOf(READY, STATE_2, STATE_1)

возврат STATE_2

val list = listOf(READY, STATE_1)

возврат STATE_1

val list = listOf(STATE_2, STATE_1)

возврат STATE_2

val list = listOf(UNKNOWN, STATE_2)

return STATE_2

Я ищу что-то, что поможет мне сделать вложенные find над коллекцией в kotlin.

Это то, чего я достиг до сих пор:

private fun filter(states: List<State>): State {
    val currentStates = states.filter {
        it != State.UNKNOWN || it != State.READY
    }

    currentStates.find { it == State.STATE_4 }?.let {
        return it
    } ?: currentStates.find { it == State.STATE_2 }?.let {
        return it
    } ?: currentStates.find { it == State.STATE_1 }?.let {
        return it
    }
}

Ответы [ 2 ]

3 голосов
/ 16 апреля 2020

Если вы определяете свои перечисленные состояния в порядке, по которому «выигрывает» фильтр:

enum class State {
    READY, UNKNOWN, STATE_1, STATE_2, STATE_4
}

Тогда вы можете выбрать тот, у которого самый высокий порядковый номер:

fun filter(states: List<State>): State = 
    states.maxBy(State::ordinal) ?: error("Must have at least one state")

Это предполагает в представленном списке есть хотя бы одно государство. Если это неверное предположение, вы можете вернуть обнуляемое значение:

fun filter(states: List<State>): State? = states.maxBy(State::ordinal)

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

fun filter(states: List<State>): State {
    val order = linkedSetOf(State.READY, State.UNKNOWN, State.STATE_1, State.STATE_2, State.STATE_4)
    assert(order.size == State.values().size) // To ensure this function is updated if States are updated.
    return states.maxBy { order.indexOf(it) } ?: error("Must have at least one state")
}
1 голос
/ 16 апреля 2020

Я сомневаюсь, что вы многое можете оптимизировать. Я могу думать только об использовании l oop над заранее определенными приоритетами, такими как следующие:

private val PRIORITY = listOf(State.STATE_4, State.STATE_2, State.STATE_1)

private fun filter(states: List<State>): State? {
    val currentStates = states.filter {
        it != State.UNKNOWN || it != State.READY
    }
    PRIORITY.forEach { prio ->
        currentStates.find { it == prio }?.let {
            return it
        }
    }
    return null
}

Примечание : я использую nullable State? в качестве типа возврата вместо State для случаи, когда в коллекции не найдено ничего подходящего.

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