How to convert List to Map in Kotlin?

DictionaryKotlin

Dictionary Problem Overview


For example I have a list of strings like:

val list = listOf("a", "b", "c", "d")

and I want to convert it to a map, where the strings are the keys.

I know I should use the .toMap() function, but I don't know how, and I haven't seen any examples of it.

Dictionary Solutions


Solution 1 - Dictionary

You have two choices:

The first and most performant is to use associateBy function that takes two lambdas for generating the key and value, and inlines the creation of the map:

val map = friends.associateBy({it.facebookId}, {it.points})

The second, less performant, is to use the standard map function to create a list of Pair which can be used by toMap to generate the final map:

val map = friends.map { it.facebookId to it.points }.toMap()

Solution 2 - Dictionary

From List to Map with associate function

With Kotlin 1.3, List has a function called associate. associate has the following declaration:

fun <T, K, V> Iterable<T>.associate(transform: (T) -> Pair<K, V>): Map<K, V>

>Returns a Map containing key-value pairs provided by transform function applied to elements of the given collection.

Usage:

class Person(val name: String, val id: Int)

fun main() {
    val friends = listOf(Person("Sue Helen", 1), Person("JR", 2), Person("Pamela", 3))
	val map = friends.associate({ Pair(it.id, it.name) })
    //val map = friends.associate({ it.id to it.name }) // also works

    println(map) // prints: {1=Sue Helen, 2=JR, 3=Pamela}
}    

From List to Map with associateBy function

With Kotlin, List has a function called associateBy . associateBy has the following declaration:

fun <T, K, V> Iterable<T>.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map<K, V>

>Returns a Map containing the values provided by valueTransform and indexed by keySelector functions applied to elements of the given collection.

Usage:

class Person(val name: String, val id: Int)

fun main() {
    val friends = listOf(Person("Sue Helen", 1), Person("JR", 2), Person("Pamela", 3))
    val map = friends.associateBy(keySelector = { person -> person.id }, valueTransform = { person -> person.name })
    //val map = friends.associateBy({ it.id }, { it.name }) // also works

    println(map) // prints: {1=Sue Helen, 2=JR, 3=Pamela}
}

Solution 3 - Dictionary

If you have duplicates in your list that you don't want to lose, you can do this using groupBy.

Otherwise, like everyone else said, use associate/By/With (which in the case of duplicates, I believe, will only return the last value with that key).

An example grouping a list of people by age:

class Person(val name: String, val age: Int)

fun main() {
    val people = listOf(Person("Sue Helen", 31), Person("JR", 25), Person("Pamela", 31))

    val duplicatesKept = people.groupBy { it.age }
    val duplicatesLost = people.associateBy({ it.age }, { it })

    println(duplicatesKept)
    println(duplicatesLost)
}

Results:

{31=[Person@41629346, Person@4eec7777], 25=[Person@3b07d329]}
{31=Person@4eec7777, 25=Person@3b07d329}

Solution 4 - Dictionary

  • Convert a Iteratable Sequence Elements to a Map in kotlin ,
  • associate vs associateBy vs associateWith:

*Reference:Kotlin Documentation

1- associate (to set both Keys & Values): Build a map that can set key & value elements :

IterableSequenceElements.associate { newKey to newValue } //Output => Map {newKey : newValue ,...}

> If any of two pairs would have the same key the last one gets added to the map. > > The returned map preserves the entry iteration order of the original array.

2- associateBy (just set Keys by calculation): Build a map that we can set new Keys, analogous elements will be set for values

IterableSequenceElements.associateBy { newKey } //Result: => Map {newKey : 'Values will be set  from analogous IterableSequenceElements' ,...}

3- associateWith (just set Values by calculation): Build a map that we can set new Values, analogous elements will be set for Keys

IterableSequenceElements.associateWith { newValue }  //Result => Map { 'Keys will be set from analogous IterableSequenceElements' : newValue , ...}

Example from Kotlin tips : enter image description here

Solution 5 - Dictionary

You can use associate for this task:

val list = listOf("a", "b", "c", "d")
val m: Map<String, Int> = list.associate { it to it.length }

In this example, the strings from list become the keys and their corresponding lengths (as an example) become the values inside the map.

Solution 6 - Dictionary

That have changed on the RC version.

I am using val map = list.groupByTo(destinationMap, {it.facebookId}, { it -> it.point })

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLordSconeView Question on Stackoverflow
Solution 1 - DictionaryvoddanView Answer on Stackoverflow
Solution 2 - DictionaryImanou PetitView Answer on Stackoverflow
Solution 3 - Dictionarycs_pupilView Answer on Stackoverflow
Solution 4 - DictionaryHamed JalilianiView Answer on Stackoverflow
Solution 5 - Dictionarys1m0nw1View Answer on Stackoverflow
Solution 6 - DictionarylagosView Answer on Stackoverflow