Kotlin開発中にふと気になったことを備忘録的にまとめる
はじめに
Map型の値に対して、以下のような変形が必要な場面がありました
// 最初のMap
mapOf(
1 to listOf("a", "b"),
2 to listOf("c"),
3 to listOf("d", "e", "f"),
...
)
// 最終的なMap
mapOf(
1 to (1 to listOf("a", "b")),
2 to (2 to listOf("c")),
3 to (3 to listOf("d", "e", "f")),
...
)
簡潔に言うと「内部のKeyを外づけしつつ、元のMapはそのまま維持する」という実装です
こういった変形をするにあたって、使えそうな関数として associate と mapValue の2つが候補に上がりましたが、これらをどう使い分けるのかよくわかっていなかったので調べました
associate
associateは元のコレクションの値を変換して、新しい値の組み合わせを生成する関数です
これを使って目標を達成する場合、以下のような実装になります
mapOf(
1 to listOf("a", "b"),
2 to listOf("c"),
3 to listOf("d", "e", "f"),
...
).associate { (key, value) ->
key to mapOf(key to value)
}
実際にはMap部分は変数に入っていると思います
このように実装して動かすことで、最初の目標を達成できます
mapValue
mapValueは元のMapのKeyを維持したまま、値を変換することができます
これを使って目標を達成する場合、以下のような実装になります
mapOf(
1 to listOf("a", "b"),
2 to listOf("c"),
3 to listOf("d", "e", "f"),
...
).mapValues { (key, value) ->
mapOf(key to value)
}
このように実装して動かすことで、最初の目標を達成できます
それぞれの相違点
最終的には associate と mapValue で同じ結果を出力することができます
ではどこで差別化するかというと
associate { (key, value) ->
key to mapOf(key to value)
}
mapValues { (key, value) ->
mapOf(key to value)
}
この部分です
associateは元の値も変換することができます
よって細かく変換が必要な場合はこちらを選ぶのがいいでしょう
mapValueは元の値は変更できず、Keyのみ新しく付け替えることができます
今回の目標のようにシンプルな変換でいい場合はこちらを選ぶのがいいでしょう
まとめ
似たような挙動をする2つの関数ですが、最終的に欲しい値から逆算して使うべき関数を決定することができます