Kotlin におけるリスト操作

2020年5月4日 engineering

こんにちは、 @kz_morita です。

今回は、Kotlin で List, Map, Set などのコレクション操作する際によく使うものをまとめてみます。 要素のフィルタリングや、map、ソートや重複を削除する方法などを載せていきます。

Initialize

初期化系の処理をまとめます。

List の初期化
listOf(1,2,3,4) // => [1,2,3,4]
Map の初期化
mapOf(1 to "one", 2 to "two", 3 to "three") // => {1=one, 2=two, 3=three}
Set の初期化
setOf(1,2,3,3) // => [1,2,3]
mutable な Collection

基本的に、上記の listOf , mapOf , setOf は Immutable な Collection なので、後から変更したい場合は、ImmutableXXXOf() を使用します。

val mutableList = mutableListOf(1,2,3,4)
mutableList.add(5) // => [1, 2, 3, 4, 5]

val mutableMap = mutableMapOf(1 to "one", 2 to "two", 3 to "three")
mutableMap[1] = "いち" // {1=いち, 2=two, 3=three}

val mutableSet = mutableSetOf(1,2,3)
mutableSet.remove(1) // [2, 3]

filter

値のフィルタリングを行います。

listOf(1,2,3,4,5).filter { it > 2 } // => [3,4,5]

Null の値を除外したい場合は以下のように行います。

listOf(1,2,null,4,5,null).filterNotNull() // => [1,2,4,5]

map

リストの各要素を変換した新しいリストにマッピングします。

// 各要素を2倍
listOf(1,2,3,4,5).map { it * 2} // => [2, 4, 6, 8, 10]

// 2 より大きければ 2 倍し、それ以外なら null にする
listOf(1,2,3,4,5).map { if (it > 2) { it * 2 } else { null } } // => [null, null, 6, 8, 10]

// null 値を除外しつつ map する
listOf(1,2,3,4,5).mapNotNull { if (it > 2) { it * 2 } else { null } } // => [6, 8, 10]

// index 付きで map を行う (index to i は Pair 型をつくるシンタックスシュガー)
listOf(1,2,3,4,5).mapIndexed { index, i -> index to i } // => [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]

reduce

リストの要素を順番に演算していきます。acc はアキュムレータで演算の結果が保持されます。

// リストの左から、演算を行います。
listOf(1,2,3,4,5).reduce { acc, i -> acc - i } // => -13
// 1
// (1) - 2
// (1 - 2) - 3
// (1 - 2 - 3) - 4
// (1 - 2 - 3 - 4) - 5 = -13

// リストの右から、演算を行います。
listOf(1,2,3,4,5).reduceRight { acc, i -> acc - i } // => 3
// 1
// 2 - (1)
// 3 - (2 - 1)
// 4 - (3 - (2 - 1))
// 5 - (4 - (3 - (2 - 1))) = 3

sort

// 昇順ソート
listOf(1,3,5,2,6,7).sorted() // => [1, 2, 3, 5, 6, 7]

// 降順ソート
listOf(1,3,5,2,6,7).sortedDescending() // => [7, 6, 5, 3, 2, 1]

// 偶数 => 奇数 の順番にソート
listOf(1,2,3,4,5).sortedBy { it % 2 } // => [2, 4, 1, 3, 5]

// 奇数 => 偶数 の順番にソート
listOf(1,2,3,4,5).sortedByDescending { it % 2 } // => [1, 3, 5, 2, 4]

重複を削除

listOf(1,1,2,3,4,4).distinct() // => [1, 2, 3, 4]

// 3で割ったあまりの数で重複判定をする
listOf(1,2,3,4,5,6,7,8,9,10).distinctBy { it % 3 } // => [1, 2, 3]

変換

List → Set, Set → List

// List → Set
// 重複も削除される
listOf(1,2,3,4,4,5).toSet() // [1,2,3,4,5]

// Set → List
setOf(1,2,3,4,5).toList() // [1,2,3,4,5]

List → Map

// Pair を作ってから Map へ
listOf(1,2,3,4,5).map { it - 1 to it }.toMap()   // => {0=1, 1=2, 2=3, 3=4, 4=5}

// 直接 Map へ
listOf(1,2,3,4,5).associateBy({ it - 1 }, { it } // => {0=1, 1=2, 2=3, 3=4, 4=5}

Map → List

val map = mapOf(1 to "one", 2 to "two", 3 to "three")

// 値のみの List
map.values // => ["one", "two", "three"]: Collection<String>
map.values.toList() // => ["one", "two", "three"]: List<String>

// キーのみの List
map.keys  // => [1, 2, 3]: Set<Int>
map.keys.toList()  // => [1, 2, 3]: List<Int>

// Pair の List
map.toList() // => [(1, "one"), (2, "two"), (3, "three")]: List<Pair<Int, String>>

まとめ

Kotlin での Collection の操作周りについてまとめました。最近の言語っぽく一通りの便利なメソッドはそろっているので、Collection の操作で困ることはあまりない印象です。

Collection の操作をマスターするとグッとコードを書くスピードが上がるので、ここらへんが気持ちよく書ける Kotlin はなかなか開発しやすいと思いました。

この記事をシェア