代码之家  ›  专栏  ›  技术社区  ›  sagar suri

使用kotlin中的嵌套Find关键字从列表中查找项目

  •  0
  • sagar suri  · 技术社区  · 4 年前

    我有一个枚举类,它将保存应用程序的不同状态。

    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)
    

    返回 状态_2

    val list = listOf(UNKNOWN, STATE_2)
    

    返回 状态_2

    我正在寻找一些能帮助我做嵌套的东西 find 在科特林的一个收藏。

    这就是我迄今为止所取得的成就:

    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
        }
    }
    
    0 回复  |  直到 4 年前
        1
  •  3
  •   Tenfour04    4 年前

    如果你按照“赢得”过滤器的顺序定义枚举状态:

    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")
    

    这假设所提供的列表中至少有一个国家。如果这不是一个安全的假设,你可以返回一个可以为null的:

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

    如果出于某种原因,你不能按照一定的顺序定义它们,你可以在这个函数中以列表(或链接的Set)的形式提供顺序:

    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")
    }
    
        2
  •  1
  •   Nikolai Shevchenko    4 年前

    我怀疑你有很多可以优化的地方。我只能想到在预定义的优先级上使用循环,如下所示

    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
    }
    

    注: :我使用可以为null的 State? 作为返回类型而不是 State 对于在集合中找不到合适的情况。