1. Introduction

In Kotlin, a Map is a collection of key-value pairs, where each key is unique. We can access the value associated with a key by using the key as an index. Certainly, we may encounter a situation where we need to create a map from two arrays. Simply put, we use the values from one array as the keys and the values of the other array as values for the map.

In this tutorial, we’ll explore various approaches to creating a map from two arrays in Kotlin.

2. Assumptions

To effectively create a map from two arrays, it’s imperative to highlight some assumptions and edge cases that will guide the solutions we’ll be looking at shortly:

  • We should expect that the two arrays in question are of the same length.
  • The first array contains keys and the second array contains the corresponding values.
  • The array that constitutes the keys for the map contains unique elements. In case of duplicate elements, the latest key overrides the previous entry with the same key in the map.

3. Using a for() Loop

A for() loop is a straightforward way to create a map from two arrays. We can do this by creating a helper method that takes in the two arrays as parameters and returns a Map:

fun createMap(keys: Array<String>, values: Array<Int>): Map<String, Int> {
    val map = mutableMapOf<String, Int>()
    for (i in keys.indices) {
        map[keys[i]] = values[i]
    }
    return map
}

In the code above, we create an empty MutableMap using the mutableMapOf() method. Next, we use a for() loop to iterate over the indices of both arrays and add each key-value pair to the map.

It’s always good practice to test our code to ensure it works correctly:

@Test
fun `creates a map from two arrays using a custom approach`() {
    val keys = arrayOf("a", "b", "c")
    val values = arrayOf(1, 2, 3)

    val map = createMap(keys, values)
    val expected = mapOf("a" to 1, "b" to 2, "c" to 3)

    assertEquals(3, map.size)
    assertEquals(expected, map)
}

From this unit test, we see that we’re constructing a Map with String keys and Int values.

4. Using the zip() Method

The built-in zip() method provides another simple solution to our problem. It operates on an Array, accepts another Array as an argument, and returns a list of pairs, which can be converted into a Map using the toMap() method:

@Test
fun `creates a map from two arrays using zip() method`() {
    val keys = arrayOf("a", "b", "c")
    val values = arrayOf(1, 2, 3)

    val map = keys.zip(values).toMap()
    val expected = mapOf("a" to 1, "b" to 2, "c" to 3)

    assertEquals(3, map.size)
    assertEquals(expected, map)
}

As explained earlier, we use the zip() method with two arrays in conjunction with the toMap() method to obtain our map. Note the assert statements that show us the expected values for each key in our map.

5. Using the associateWith() Method

Thirdly, we can leverage the associateWith() method to create a map from two arrays. This method creates a map by associating each key from the key array with a corresponding value in the values array by index:

@Test
fun `creates a map from two arrays using the associateWith() method`() {
    val keys = arrayOf("a", "b", "c")
    val values = arrayOf(1, 2, 3)

    val map = keys.associateWith { key -> values[keys.indexOf(key)] }
    val expected = mapOf("a" to 1, "b" to 2, "c" to 3)

    assertEquals(3, map.size)
    assertEquals(expected, map)
}

In this unit test, we use the associateWith() method to create a map by associating each key from the key array with a corresponding value in the second array. Lastly, we use assert statements to ensure that the right value is mapped to a particular key from the first array.

In contrast to the other approaches, this method deals with duplicate keys differently. Instead of replacing the existing map entry when a duplicate key is encountered, it preserves the first map entry. This is because it utilizes the indexOf() method, which always returns the first index for each key.

6. Using the mapIndexed() Method

We can also create a map from two arrays using the mapIndexed() method. This method accepts a lambda function, which it then applies to each element of the original array. Finally, it returns the list of key-value pairs:

@Test
fun `creates a map from two arrays using the mapIndexed() method`() {
    val keys = arrayOf("a", "b", "c")
    val values = arrayOf(1, 2, 3)

    val pairs = keys.mapIndexed { index, key -> key to values[index] }

    val map = pairs.toMap()
    val expected = mapOf("a" to 1, "b" to 2, "c" to 3)

    assertEquals(3, map.size)
    assertEquals(expected, map)
}

This code snippet shows how we obtain a list of pairs by calling the mapIndexed() method on the first array. Furthermore, we supply this method with a lambda function that maps a key to a corresponding value from the second array using their indices. Finally, we use the toMap() method to convert the list of pairs to a map.

7. Conclusion

In this article, we’ve explored various ways to create a map from two arrays in Kotlin. While the loop-based approach is more flexible, other methods offer simplicity and elegance.

For instance, the zip() method is quite simple, while the associateWith() and mapIndex() methods are concise. Therefore, it’s important to choose the one that best fits our project’s use case. Depending on the complexity of the project, one method may be more suitable than another.

As always, the code used in this article is available over on GitHub.