Kotlin で List をマージして差分更新するメモ。
Collections の groupingBy + reduce で解決
data class Person(val id: Int, val name: String, val age: Int)
val listA = listOf(
Person(0, "foo", 10),
Person(1, "bar", 20),
Person(2, "baz", 30)
)
val listB = listOf(
Person(0, "FOO", 15),
Person(2, "BAZ", 35)
)
(listA + listB).groupingBy { it.id }
.reduce { _, _, element -> element }
.flatMap { listOf(it.value) }
.forEach { println(it) }
// Person(id=0, name=FOO, age=15)
// Person(id=1, name=bar, age=20)
// Person(id=2, name=BAZ, age=35)
解説
groupingBy
If you want to group elements and then apply an operation to all groups at one time, use the function groupingBy(). It returns an instance of the Grouping type.
関数オブジェクトでグループ化し Grouping<T, K> を返す。これ自体はインタフェースを提供しているだけなので、実際の処理は後述の拡張関数が担う。
reduce
fold() and reduce() perform fold and reduce operations on each group as a separate collection and return the results.
各グループの要素に対して順次関数オブジェクトで処理し、その結果を Map<K, S> へと格納する。fold() が初期値を指定できるのに対し、reduce() は 1 番目の要素を初期値に取る。これにより戻り値の型が必然的に要素と同一になる。
| function | initial value | return type |
|---|---|---|
| fold | O | O |
| reduce | X | X |
他にも eachCount() や aggregate() があるが、内容については 面倒なので解説しない 是非自分たちで調べて欲しい。