What is it, naokirin?

Kotlinのコレクション関数について今さらまとめておく

前回の記事で、スコープ関数をまとめました。

naokirin.hatenablog.com

今回はコレクションを操作する関数をまとめておきます。

今回紹介する関数はすべて、もとのオブジェクトを変更せずに、操作後の結果を別のオブジェクトとして返却するようになっています。

Transform(変換)

最初は変換に関する関数です。

map, flatMap

map は、コレクションの各要素を指定された関数を適用した結果を返します。

val result = listOf(1, 2, 3).map { it + 1 }
println(result)

// output:
//   [2, 3, 4]

flatMapmap に似ていますが、平坦化(深いネストしたコレクションを単一のコレクションの要素に変換)をします。処理の順序は関数を各要素に適用してから、平坦化をします。

val result = listOf(listOf(1, 2), listOf(3, 4)).flatMap { it + it }
println(result)

// output:
//   [1, 2, 1, 2, 3, 4, 3, 4]

flatten

flatten は平坦化のみを行います。 flatMap.map {...}.flatten() の結果と同一です。

val result = listOf(listOf(1, 2), listOf(3, 4)).flatten()
println(result)

// output:
//   [1, 2, 3, 4]

zip, unzip

zip は2つのコレクションの同じ位置にある要素をペアにします。

val result = listOf("I", "you", "they").zip(listOf("my", "your", "their"))
println(result)

// output:
//   [(I, my), (you, your), (they, their)]

ちなみにサイズが異なるコレクション同士の場合、小さい方に合わせられ、余った要素は切り捨てられます。

val result = listOf("I", "you", "they").zip(listOf("my", "your"))
println(result)

// output:
//   [(I, my), (you, your)]

また、 zip に変換の関数を渡すことができ、ペアになった要素に対する処理を書くこともできます。

val result = listOf("Hello", "Fizz").zip(listOf("World", "Buzz")) { a, b -> a + b }
println(result)

// output:
//   [HelloWorld, FizzBuzz]

unzipzip と逆の操作ができます。要素がペアになっているコレクションをそれぞれのコレクションに変換します。

val result = listOf(1 to 2, 3 to 4).unzip()
println(result)

// output:
//   ([1, 3], [2, 4])

associateWith, associateBy, associate

associateWithassociateByassociate はコレクションから、 Map を生成します。

val result = listOf("one", "two").associateWith { it.length }
println(result)

// output:
//   {one=3, two=3}
val result = listOf("one", "two").associateBy { it.first() }
println(result)

// output:
//   {o=one, t=two}
val result = listOf("red" to "rose", "white" to "bird").associate { it }
println(result)

// output:
//   {red=rose, white=bird}

filtering(フィルタ)

コレクションから、条件をもとにコレクションをフィルタリングする関数を紹介します。

filter, filterNot, filterNotNull, filterIsInstance

filter は、条件を満たす要素のみのコレクションを返します。 filterNot は条件を逆にします。

val result = listOf(1, 2, 3, 4).filter { it % 2 == 0 }
println(result)

// output:
//   [2, 4]

filterNotNullnull の要素を取り除きます。

val result = listOf(1, 2, null, 4).filterNotNull()
println(result)

// output:
//   [1, 2, 4]

filterIsInstance は 指定された型に一致する要素のみのコレクションを返します。

val result = listOf(1, "two", "three", 4).filterIsInstance<String>()
println(result)

// output:
//   [two, three]

partition

partition は、条件を満たす要素とそれ以外の要素の2つのコレクションに分解します。

val (match, rest) = listOf(1, 2, 3, 4).partition { it % 2 == 0 }
println(match)
println(rest)

// output:
//   [2, 4]
//   [1, 3]

test predicates(テスト)

コレクションが条件に合致するかテストする関数を紹介します。

any

any は要素が1つでも条件を満たしたら true を返します。

val result = listOf(1, 2, 3, 4).any { it > 3 }
println(result)

// output:
//   true

all

all は要素が1つでも条件を満たしたら true を返します。

val result = listOf(1, 2, 3, 4).all { it > 3 }
println(result)

// output:
//   false

none

none は要素が1つでも条件を満たしたら true を返します。

val result = listOf(1, 2, 3, 4).none { it > 4 }
println(result)

// output:
//   true

grouping(グルーピング)

コレクションを特定の規則に従ってグルーピングする関数を紹介します。

groupBy

groupBy は指定された関数が返す結果に基づいてグルーピングした結果を返します。

val result = listOf(1, 2, 3, 4, 5, 6).groupBy { it % 3 }
println(result)

// output:
//   {1=[1, 4], 2=[2, 5], 0=[3, 6]}

ordering(順序)

コレクションを特定の規則に従って、並べ替えた結果を返す関数を紹介します。

sorted, sortedDescending

sorted , sortedDescending は要素の型のもともとの並べ替え方法を利用して並べ替えを行います。

val sorted = listOf(3, 1, 4, 2).sorted()
val sortedDescending = listOf(3, 1, 4, 2).sortedDescending()
println(sorted)
println(sortedDescending)

// output:
//   [1, 2, 3, 4]
//   [4, 3, 2, 1]

sortedBy, sortedByDescending

sortedBy , sortedByDescending はコレクションを指定された関数で返される結果をもとに並べ替えます。

val sorted = listOf("one", "two", "three", "four").sortedBy { it.length }
val sortedDescending = listOf("one", "two", "three", "four").sortedByDescending { it.length }
println(sorted)
println(sortedDescending)

// output:
//   [one, two, four, three]
//   [three, four, one, two]

reversed

reversed はコレクションの順序を反転します。

val result = listOf(1, 2, 3).reversed()
println(result)

// output:
//   [3, 2, 1]

shuffled

shuffled はコレクションをシャッフルします。

val result = listOf(1, 2, 3).shuffled()
println(result)

// output:
//   [2, 1, 3] <- 結果は実行ごとに変わります

aggregation(集約)

コレクションの要素同士を集約した結果を返します。

fold, foldRight

fold はコレクションに対して、畳み込みと呼ばれる操作を行います。そのときに渡された初期値からスタートして処理をします。

val result = listOf(1, 2, 3).fold(4) { sum, el -> sum + el }
println(result)

// output:
//   10

foldRight は畳み込みを右から行っていきます。

val result = listOf(1, 2, 3).foldRight(0) { el, res -> res + el * 2 }
println(result)

// output:
//   12

reduce, reduceRight

reducefold と異なり、初期値を与えずに畳み込みを行います。

val result = listOf(1, 2, 3).reduce { res, el -> res + el }
println(result)

// output:
//   6

まとめ

ざっとコレクション関数をまとめてみました。

他にも様々な関数が存在しますが、こうした関数を活用することでコレクションに対する操作を簡単に実行することができるので、活用して、Kotlinらしいコードを書いていきたいですね。