Kotlinでリストをマップに変換する
1前書き
このクイックチュートリアルでは、
List
を
Map
i
_n
_
Kotlinに変換する方法を説明します。
2実装
Kotlinは便利なhttps://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/to-map.html[
toMap
]メソッドを提供します。これは複雑なオブジェクトのリストを与えられて、私たちの中に要素を持つことを可能にします。私たちが提供する値でマップされたリスト:
val user1 = User("John", 18, listOf("Hiking"))
val user2 = User("Sara", 25, listOf("Chess"))
val user3 = User("Dave", 34, listOf("Games"))
@Test
fun givenList__whenConvertToMap__thenResult() {
val myList = listOf(user1, user2, user3)
val myMap = myList.map { it.name to it.age }.toMap()
assertTrue(myMap.get("John") == 18)
}
“ to”
キーワードは、名前と年齢のペアを作成するためにここで使用されていることに注意してください。このメソッドは、配列内の要素の入力順序を保持したマップを返します。
{John=18, Sara=25, Dave=34}
String
の小さい配列をマップしたときも同じことが起こります。
@Test
fun givenStringList__whenConvertToMap__thenResult() {
val myList = listOf("a", "b", "c")
val myMap = myList.map { it to it }.toMap()
assertTrue(myMap.get("a") == "a")
}
唯一の違いは
it
の値は指定されていないことです。
次に、
List
を
Map
に変換する2番目の方法として、
associatedBy
メソッドを使用する方法があります。
@Test
fun givenList__whenAssociatedBy__thenResult() {
val myList = listOf(user1, user2, user3)
val myMap = myList.associateBy({ it.name }, { it.hobbies })
assertTrue(myMap.get("John")!!.contains("Hiking"))
}
値として配列を使用するようにテストを変更しました。
{
John=[Hiking, Swimming],
Sara=[Chess, Board Games],
Dave=[Games, Racing sports]}
3どちらを使うべきですか?
両方の方法が本質的に同じ機能を達成する場合、どちらを使用すればよいですか?
実装に関しては、
toMap
がより直感的です。ただし、このメソッドを使用するには、最初に
Array
を
Pairs
に変換する必要があります。これは後で
Map
に変換する必要があります。
他のタイプのコレクションの場合は、
associate
APIが最良の選択です。
4
associate
メソッド** を使ったマッピング
前の例では、
associateBy
メソッドを使用しましたが、Kotlin
collections
パッケージには、使用例ごとにバージョンが異なります。
4.1.
associate()
メソッド
まず
associate
メソッドを使用します。これは、配列の要素に対して変換関数を使用して
Map
を返すだけです。
@Test
fun givenStringList__whenAssociate__thenResult() {
val myList = listOf("a", "b", "c", "d")
val myMap = myList.associate{ it to it }
assertTrue(myMap.get("a") == "a")
}
4.2.
associateTo
メソッド
この方法を使うと、既存のマップに要素を集めることができます。
@Test
fun givenStringList__whenAssociateTo__thenResult() {
val myList = listOf("a", "b", "c", "c", "b")
val myMap = mutableMapOf<String, String>()
myList.associateTo(myMap) {it to it}
assertTrue(myMap.get("a") == "a")
}
変更可能な__Mapを使用することを忘れないでください – この例は不変のものでは動作しません。
4.3.
associateByTo
メソッド
associateByTo
は、3つの中で最も柔軟性があります。移入されるマップである
keySelector
関数を渡すことができるからです。指定された各キーについて、関連付けられた値は、キーが次の場所から抽出されたオブジェクトになります。
@Test
fun givenStringList__whenAssociateByToUser__thenResult() {
val myList = listOf(user1, user2, user3, user4)
val myMap = mutableMapOf<String, User>()
myList.associateByTo(myMap) {it.name}
assertTrue(myMap.get("Dave")!!.age == 34)
}
あるいは、
valueTransform
関数を使うこともできます。
@Test
fun givenStringList__whenAssociateByTo__thenResult() {
val myList = listOf(user1, user2, user3, user4)
val myMap = mutableMapOf<String, Int>()
myList.associateByTo(myMap, {it.name}, {it.age})
assertTrue(myMap.get("Dave") == 34)
}
-
キーの衝突が発生した場合、最後に追加された値のみが保持されることを覚えておくことが重要です。**
5結論
この記事では、Kotlinで
List
を
Map
に変換するさまざまな方法を調べました。
いつものように、これらすべての例とスニペットの実装はhttps://github.com/eugenp/tutorials/tree/master/core-kotlin[GitHubで動く]にあります。これはMavenベースのプロジェクトなので、インポートして実行するのは簡単なはずです。