web-dev-qa-db-ja.com

Kotlinを使用してリストをその場でフィルタリングする方法は?

In Javaこのコードを使用してリストから項目を削除できます。

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

Kotlinで同じようにする(つまり、再作成せずにList内のいくつかのアイテムを削除する)方法は?

19
BArtWell

.retainAll { ... } または .removeAll { ... } を使用して、両方とも述語を受け入れ、その場でフィルタリングします。

items.retainAll { shouldRetain(it) }
items.removeAll { shouldRemove(it) }

itemsMutableList<T>である必要があり、List<T>である必要があります。これはKotlinの読み取り専用リストであり、変更関数を公開しません(参照: Collections 言語リファレンス).

ところで、これらの2つの関数は、ランダムアクセスをサポートするリストに対して効率的に実装されます。各アイテムが削除された後、リストは圧縮されません(O(n2time worst-case)、代わりに、アイテムは処理中にリスト内で移動され、O(n)時間。


元のリストを変更したくない場合は、 .filter { ... } または .filterNot { ... }を使用して、保持するアイテムのみを含む別のコレクションを作成できます。 、これは読み取り専用List<T>でも機能します:

val filtered = items.filter { shouldRetain(it) }
val filtered = items.filterNot { shouldRemove(it) }
43
hotkey

Kotlinにはたくさんのきちんとした組み込み関数があります。ここでfilterを使用してみることができます。

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

残念ながら、リストが再作成されます。このAPIは、余分な可変性を避けるために意図的に設計されました。

ただし、MutableListを引き続き使用する場合は、retainAllメソッドを使用します

items.retainAll { checkItem(it) }

これにより、リスト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/ で試してください

0
s-hunter