🔖

[Kotlin]Collection操作を8つの分類で解説②Filtering Collection

2024/03/20に公開

[Kotlin] Collection operations: コレクションの操作

前回から引き続き書いていきます!!!^^
以下8つに分けてその中身を書いていくということをしてますが、
今回は2回目ということで、Filteringするものたちです!
大きく、Filter, Partition,Test predicatesの内容を一つずつ書いていきます!

前回までの記事

< 分類表 >

collection operation 分類表

8つに分類したらこうなる!

collections operations 概要 関数
transformation
前回の記事はここです⭐️
既存のコレクションから新しいコレクションを構築 Map, Zip, Associate, Flatten, StringPresentation
それぞれのメソッドは詳細でまた別途記載
Filtering
→ 今回はここ書きます!
元のコレクションを変更せずに特定の条件で要素をフィルタリングし、新しいコレクションを返す filter() (filterIndexed()) ,filterNot(), filterNotNull(), partition(),any,all,none
Plus / Minus コレクションに要素を追加または削除するもの plus(), minus()
Grouping コレクションの要素を特定の基準でグループ化するもの groupBy(), eachCount(),fold(), reduce(),aggregate()
Retrieving collection parts コレクションの一部を取得するもの slice(),Chunked ,Windowed ,take()(takeLast(),takeLastWhile(),takeWhile()),drop()(dropLast(),dropLastWhile(),dropWhile()),
Retrieving Single Elements コレクションから単一の要素を取得するもの By position ( elementAt(), elementAtOrElse(), elementAtOrNull()), by condition(first(), firstOrNull(), last() , lastOrNull(),find() ),Check Element Existence(contains(), isEmpty(), isNotEmpty())
Ordering コレクションの要素を並べ替えるもの Natural order(sorted(), sortedDescending()), Custom orders( sortedBy(), sortedByDescending(), sortedWith() ),Reverse order( reversed()),Random order( shuffled())
Aggreregate Operation コレクションの要素を集計するもの reduce(), fold(), count(), sum(), average(), max(), min() etc

2. Filtering collections

Filtering is one of the most popular tasks in collection processing.
In Kotlin, filtering conditions are defined by predicates – lambda functions that
take a collection element and return a boolean value:
true means that the given element matches the predicate, false means the opposite.
The standard library contains a group of extension functions that let you filter collections in a single call. These functions leave the original collection unchanged, so they are available for both mutable and read-only collections. To operate the filtering result, you should assign it to a variable or chain the functions after filtering.

  • フィルタリング条件は述語によって定義され、これはコレクションの要素を取り、ブール値を返すラムダ関数。
  • 元のコレクションを変更せずに残すので、変更可能なコレクションと読み取り専用の両方で利用可能。
  • フィルタリング結果を操作するには...変数に割り当てるか、フィルタリング後に関数をチェーンさせる必要がある

< Filtering collections >

関数 説明
Filter filter() (filterIndexed()) 条件を満たす要素のみを含む新しいコレクションを作成
filterNot() 指定された条件を満たさない要素のみを含む新しいコレクションを作成
filterNotNull() nullでない要素のみを含む新しいコレクションを作成
partition() 条件に基づいてコレクションを2つのグループに分割(Pairをつくる)。一方は条件を満たし(true)、もう一方は満たさない要素(false)が含まれます。
any 条件を満たす要素が少なくとも1つ存在する場合にtrueを返す
all すべての要素が指定された条件を満たす場合にtrueを返す
none どの要素も指定された条件を満たさない場合にtrueを返す

Filter by predicate

filter() / filterNot() / filterNotNull()

  • コレクションのサブセットを作成可能!

  • 上記したように、元のコレクションを変更せずに、ラムダ内の処理を行いそれにマッチするコレクション要素を新しく作成し、返す

  • map()関数は、元のコレクションの各要素を変換して新しいコレクションを生成するが、
    変換後のコレクションのサイズは元のコレクションと同じ!

  • filter()関数は、条件を満たす要素のみを含む新しいコレクションを生成
    元のコレクションよりもサイズが小さくなることがある。
    条件を満たさない要素は除外されるため、
    結果のコレクションのサイズは元のコレクション以下になることもある。

    • 条件を満たすものを含まないとする = filterNot()
    • nullを含まないものとする = filterNotNull()
// filter()
fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T>

// filterNot() 
fun <T> Iterable<T>.filterNot(predicate: (T) -> Boolean): List<T>

単一のラムダ式をパラメータとして受け取る。
ラムダは、コレクション内の各アイテムを表す単一のパラメータを受け取り、Boolean 値を返す。

  • filter()ラムダ式の結果が true であれば、アイテムは新しいコレクションに含められ,
    false であれば、アイテムは新しいコレクションに含められない。

ex.

// Listの例
val numbers = listOf("one", "two", "three", "four")  

val longerThan3 = numbers.filter { it.length > 3 }
println(longerThan3) // 出力 [three, four]

val filteredNot = numbers.filterNot { it.length <= 3 }
println(filteredNot) // 出力 [three, four]

// Mapの例
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
val filteredMap = numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10}
println(filteredMap) // 出力 {key11=11}

Partition: partition()

  • ラムダ式で指定した条件で Pair を返すもの。

基本型

fun <T> Iterable<T>.partition(predicate: (T) -> Boolean): Pair<List<T>, List<T>>

// もう少し日本語で簡単にすると
// 対象のCollection.partition( 処理内容 ): Pair<trueのもの, falseのもの>

条件が true となった要素が first に、 false となった要素が second にセットされる。
使い方は...
ex.

val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9)

// 変数部分でPairでかえるので二つ記述するよ
val (evenNumbers, oddNumbers) = numbers.partition { it % 2 == 0 }

println("Even numbers: $evenNumbers") // 出力 [2, 4, 6, 8]
println("Odd numbers: $oddNumbers") // 出力  [1, 3, 5, 7, 9]

Test predicates

関数 説明
any() 少なくとも 1 つの要素が与えられた述語と一致する場合に true を返す。
none() 要素のいずれもが与えられた述語と一致しない場合に true を返す。
all() すべての要素が与えられた述語と一致する場合に true を返す。
注意all() は空のコレクションに対して有効な述語で呼び出された場合にも true を返す。
  • any()none()は記述なしで記述が可能。

ex.

val numbers = listOf("one", "two", "three", "four")

println(numbers.any { it.endsWith("e") })
println(numbers.none { it.endsWith("a") })
println(numbers.all { it.endsWith("e") })

println(emptyList<Int>().all { it > 5 })   // vacuous truth


と、いうことで
次回は、Plus / Minusと Groupingするものたちを書いていきます!!

個人的にこのような記事を書きながらアウトプットしつつ振り返って、
辞書としてるので、
いい感じに本にしようか検討中.....

Discussion