Duplicates values in Map: Kotlin

Viewed 2368

I have a scenario whereby I need a map containing duplicate keys and values. I have created a list first and then I used associatedBy to convert them to a map, however the duplicates issue is not taken into account. Here is my implementation:

class State(private val startStatus: Status, private val expectedStatus: Status) {
  
  companion object StatusList {
    val listStatuses = listOf(
      State(Status.A, Status.B),
      State(Status.B, Status.A),
      State(Status.B, Status.C),
      State(Status.C, Status.B),
      State(Status.C, Status.E),
      State(Status.C, Status.D),
      State(Status.D, Status.B),
      State(Status.E, Status.C),
      State(Status.E, Status.B)
    )
  
    open fun mapStatuses(): Map<Status, Collection<Status>> {
      return listStatuses.associateBy(
        keySelector = { key -> key.expectedStatus },
        valueTransform = State::startStatus)
    }
  }
}

I am struggling to find a Multimap in Kotlin that would allow me to deal with duplicates. Can you help?

Thanks

1 Answers

In short, there is no multimap in Kotlin.

A multimap would allow multiple, equivalent keys with different values - this can be implemented with unique keys and a collection of values associated with given key, instead of having a view over collection of key-value pairs with equivalent keys.

Thus, you can use groupBy():

data class Record(val id: Int, val name: String)

fun main() {
    val records = listOf(
            Record(1, "hello"),
            Record(1, "there"),
            Record(2, "general"),
            Record(2, "kenobi")
    )

    val mapped = records.groupBy({ it.id }, { it.name })

    for (entry in mapped) {
        println("${entry.key} -> ${entry.value.joinToString()}")
    }
}

Here I am using groupBy with a projection of key (which is Record's id) and a projection of value (which is Record's name). Quite similar to your States and Statuses.

Related