【问题标题】:How to filter a list in-place with Kotlin?如何使用 Kotlin 就地过滤列表?
【发布时间】:2017-11-24 06:22:01
【问题描述】:

在 Java 中,我可以使用以下代码从列表中删除项目:

private void filterList(List<Item> items) {
    Iterator<Item> iterator = items.iterator();
    while (iterator.hasNext()) {
        if (checkItem(iterator.next())) {
            iterator.remove();
        }
    }
}

如何在 Kotlin 中做同样的事情(即删除 List 中的一些项目而不重新创建)?

【问题讨论】:

  • 只需将此代码复制到kotlin文件,IDE会自动为您完成。

标签: list kotlin filtering


【解决方案1】:

只需使用都接受谓词的.retainAll { ... }.removeAll { ... } 就地过滤它:

items.retainAll { shouldRetain(it) }

items.removeAll { shouldRemove(it) }

请注意,items 应该是 MutableList&lt;T&gt;,而不仅仅是 List&lt;T&gt;,它是 Kotlin 中的只读列表,因此不会公开任何变异函数(请参阅语言参考中的 Collections )。

顺便说一句,对于支持随机访问的列表,这两个函数是有效实现的:那么在删除每个项目后列表不会被压缩(O(n2) 时间最坏情况),而是在处理列表时在列表中移动项目,给了 O(n) 时间。


如果您不想修改原始列表,您可以使用.filter { ... }.filterNot { ... } 生成一个单独的集合,其中仅包含您想要保留的项目,这将适用于只读List&lt;T&gt; 为好吧:

val filtered = items.filter { shouldRetain(it) }

val filtered = items.filterNot { shouldRemove(it) }

【讨论】:

  • 如果没有这个功能,我会惊呆的。标准库很棒。
  • 您的意思是removeAll?因为在问题中,当谓词通过时删除了一个项目。
  • @Ilya,谢谢,这只是checkItem 的名字让我很困惑。固定。
【解决方案2】:

Kotlin 有很多简洁的内置函数。你可以在这里尝试使用filter

val filteredItems = items.filter { checkItem(it) }  

不幸的是,它将重新创建列表。此 API 旨在避免额外的可变性。

但如果您仍想继续使用 MutableList,请使用 retainAll 方法

items.retainAll { checkItem(it) }

【讨论】:

    【解决方案3】:

    这将从列表 1-9 中删除偶数,并打印 [1, 3, 5, 7, 9]

    var myLists = mutableListOf(1,2,3,4,5,6,7,8,9)
    myLists.removeAll{ it % 2 == 0 }
    println(myLists)
    

    这将保留偶数并从列表 1-9 中删除其他数字,并打印 [2, 4, 6, 8]

    myLists = mutableListOf(1,2,3,4,5,6,7,8,9)
    myLists.retainAll{ it % 2 == 0 }
    println(myLists)
    

    https://play.kotlinlang.org/试试他们

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      • 1970-01-01
      • 2016-08-05
      • 2021-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多