【问题标题】:Kotlin replace isEmpty()&last() with lastOrNull() within a CollectionKotlin 在 Collection 中用 lastOrNull() 替换 isEmpty()&last()
【发布时间】:2017-12-16 18:19:21
【问题描述】:

我想使用类似(下面的代码)的东西,但我认为必须有一个更好的解决方案,使用 lastOrNull() 而不是使用 isEmptylast()

data class Entry(val x: Float, val y: Float)

var entries: MutableList<Entry> = ArrayList()
if(some) {
  entries.add(Entry(100f, 200f)
}
val foo = (if (entries.isEmpty()) 0f else entries.last().y) + 100f

还有像entries.lastOrNull()?.y if null 0f这样更好的方法吗?

【问题讨论】:

    标签: list arraylist collections kotlin


    【解决方案1】:

    您可以使用 Kotlin elvis operator ?:,例如:

    //   if the expression `entries.lastOrNull()?.y` is null then return `0f` 
    //                                  v              
    val lastY = entries.lastOrNull()?.y ?: 0f
    

    对于您上面代码中的表达式,您可以使用safe-call ?.let/?.run 使您的代码更清晰,例如:

    //val foo = if (entries.isEmpty()) 0f else entries.last().y + 100f else 100f
    
    //             if no Entry in List return `0F`  ---v
    val foo = entries.lastOrNull()?.run { y + 100 } ?: 0F 
    //                            ^--- otherwise make the last.y + 100  
    

    【讨论】:

    • 我问你为什么使用 run 而不是 let there?
    • @ligi hi, run 取一个receiver, let 取接收器作为参数。所以如果你使用let,你必须将代码更改为?.let{it.y + 100}it 是参数的隐式变量。你可以选择你喜欢的。
    • 谢谢 - 类似情况有这么多选项 ;-) run/let/with/apply - 仍然在纠结何时使用 which - 想想 let 读起来更好/更自然 - 感谢您的反馈
    • @ligi 是的。但它们适用于不同的情况。 apply 将返回 receiver 而不是 lambda 正文中的结果。 with 不适合这里。
    • 是的 - 这里的问题只是在 run 和 let 之间 - 我想我仍然更喜欢 let - 因为它读起来更自然“让它成为这个” - run 在这里并没有真正和我说话- 但仍在尝试找出最佳做法
    【解决方案2】:

    如果我能正确理解您的意思,就可以了:

    val foo = if (entries.isEmpty()) 0f else entries.lastOrNull()?.y ?: 0f + 100f
    

    【讨论】:

    • entries.isEmpty() 表达式是不必要的。如果它不是空的,它总是返回last.y + 100,否则返回0f。而List 包含Entry 而不是Entry?,这里不需要使用last?.y
    • 好话。我错过了列表包含不可为空的条目的事实。谢谢。
    • 对不起,我的网络不好,我来晚了。一点也不。我只想让你知道。
    猜你喜欢
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    相关资源
    最近更新 更多