Transforming Kotlin Collections - Functions with Examples
Published: 2022-10-13 07:07:23

Knowing about the standard library functions in Kotlin saves a lot of time while working on complex data structures. Whether you are mapping the API response model into your business model or you are sorting, filtering, and manipulating data; knowing  these operation on Kotlin collections come really handy.

In this post, we are gonna go through some collection transformation operations that I use frequently.
<h2>Kotlin Collections - Transformation Operations</h2>
<h2>1. Mapping</h2>
<img class="alignnone wp-image-3717 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Mapping1-1-1030x515.png" alt="" width="1030" height="515" />

Mapping means to modify each item in a collection by applying a transformation lambda which results in the creation of another collection.

If you are working on lists of data that you need to transform from one model into another or if you want to convert the API response model into a domain layer model you should use mapping operations in Kotlin.
<h3>.map()</h3>
<img class="alignnone wp-image-3705 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Mapping2-1030x515.png" alt="" width="1030" height="515" />
Using the <code>.map()</code> function is the most common way to convert a collection of items into another. It applies the given transform lambda to each of the items of the receiver collection and yields them into a newly created list.
<h3>.mapIndexed()</h3>
<img class="alignnone wp-image-3704 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Mapping3-1030x515.png" alt="" width="1030" height="515" />

If you also need the index of each item when transforming them, you can use the <code>.mapIndexed()</code> function. It will feed the index of each item to the transform lambda so that you can utilize the order of the items.
<h3>.mapNotNull()</h3>
<img class="alignnone wp-image-3709 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Mapping4-1030x515.png" alt="" width="1030" height="515" />

Another convenient mapping function is <code>.mapNotNull()</code>. You can use it if you want to filter out null items after the conversion.

For example, if you have a list of objects which may or may not have text property, you can use <code>.mapNotNull()</code> to get a list of texts without any nulls being in it.

--

Kotlin's standard library also has <code>.mapIndexedNotNull()</code> method which combines <code>.mapIndexed()</code> and <code>.mapNotNull()</code>.

Also you can find <code>.mapKeys()</code> and <code>.mapValues()</code> methods which are defined on <code>Map</code>s.

Please check out the <a href="https://kotlinlang.org/docs/collection-transformations.html#map">official documentation</a> if you need more information on the topic.
<h2>2. Zipping</h2>
<img class="alignnone wp-image-3718 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Zipping1-1-1030x515.png" alt="" width="1030" height="515" />

When you have two lists of the same size and you want to merge each item from the first list with the corresponding item coming from the second list you want zipping.

Kotlin standard library has convenient functions to zip and unzip collections including <code>List</code>s, <code>Array</code>s, and <code>Sequence</code>s.

Let's take a look at what we have:
<h3>.zip()</h3>
<img class="alignnone wp-image-3711 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Zipping2-1030x515.png" alt="" width="1030" height="515" />

You can use <code>.zip()</code> without any transformation to create a list of pairs. The pairs have their first item from the receiver list and the second from the argument. If you want to combine two different data sources into one and if the sources has the same number of items, the function <code>.zip()</code> is really useful.
<h3>.zip() with transform lambda</h3>
<img class="alignnone wp-image-3712 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Zipping3-1030x515.png" alt="" width="1030" height="515" />

If you don't need pairs but you want to define your own zipping logic, good news: <code>.zip()</code> can also take a transform lambda as an argument. So you don't need to chain a <code>.zip()</code> command with a <code>.map()</code>. Instead, pass a lambda and combine two items coming from two data sources in a way you would prefer.
<h3>.unzip()</h3>
<img class="alignnone wp-image-3710 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Zipping4-1030x515.png" alt="" width="1030" height="515" />

Another great function in Kotlin is the <code>.unzip()</code>. The name gives it all away: it does the opposite of <code>.zip()</code>. If you have a list of pairs and want to create two lists that contain the firsts and seconds of each item, then just <code>.unzip()</code> it!

--

If you want to see some examples please check out the <a href="https://kotlinlang.org/docs/collection-transformations.html#zip">official documentation</a>.

Now let's check out another group of transformation operations:
<h2>3. Association</h2>
<img class="alignnone wp-image-3715 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Association1-1-1030x515.png" alt="" width="1030" height="515" />

Association is when you want to traverse a <code>List</code> and convert it into a <code>Map</code> by associating each item with one of its properties. Understanding association operations is easier to show than tell, so let's take a look at what sort of functions we have in the standard library:
<h3>.associateWith()</h3>
<img class="alignnone wp-image-3698 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Association2-1030x515.png" alt="" width="1030" height="515" />

The <code>.associateWith()</code> function, structures the items of the List as keys of a <code>Map</code>. The values for each key are computed by running the given lambda on the item. Please note that maps cannot have duplicate keys, so if the receiver collection has repetitive items, only the last one will remain in the map.
<h3>.associateBy()</h3>
<img class="alignnone wp-image-3699 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Association3-1030x515.png" alt="" width="1030" height="515" />

Kotlin also has <code>.associateBy()</code>, which functions almost the same. The difference is items of the receiver collections are not used as keys but values.

That means if the lambda returns the same values for different items, only the last one will be present in the resulting map.
<h3>.associate()</h3>
<img class="alignnone wp-image-3700 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Association4-1030x515.png" alt="" width="1030" height="515" />

The last associating function in the standard library is <code>.associate()</code>.

Using this function, you can define the logic of building the map. You need to pass a lambda that returns <code>Pair</code>s and a <code>Map</code> will be built for you using these <code>Pair</code>s.

Please note that this function has some performance implications since it generates <code>Pair</code>s as an intermediate step.

--

If you want to learn more on association you can take a look at the <a href="https://kotlinlang.org/docs/collection-transformations.html#associate">official documentation</a>.

Now, let's see how we can flatten collections:
<h2>4. Flattening</h2>
<img class="alignnone wp-image-3714 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Flattening1-1-1030x515.png" alt="" width="1030" height="515" />

Flattening in general is removing the nestedness in a collection. Consider you are given a list of lists. If you want to remove all child lists and get their elements into one single-level list, you need to flatten that list.

Let's begin with:
<h3>.flatten()</h3>
<img class="alignnone wp-image-3694 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Flattening2-1030x515.png" alt="" width="1030" height="515" />

This is the most simple way of flattening a list of lists into just list. Just call <code>.flatten()</code> on the receiver collection to have a flat list.
<h3>.flatMap()</h3>
<img class="alignnone wp-image-3695 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Flattening3-1030x515.png" alt="" width="1030" height="515" />

Or, if you want to apply some kind of transformation whilst flattening, you can use <code>.flatMap()</code>.

Please note that <code>.flatMap()</code> is just a shorter form of <code>.map().flatten()</code> chain.

<img class="alignnone wp-image-3693 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/Flattening4-1030x515.png" alt="" width="1030" height="515" />

--

If you want to see some code examples, you may check the <a href="https://kotlinlang.org/docs/collection-transformations.html#flatten">official documentation</a> on flattening.

Now let's check out last chapter:
<h2>5. String Representation</h2>
<img class="alignnone wp-image-3716 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/String1-1-1030x515.png" alt="" width="1030" height="515" />

If you are generating user-visible text out of Kotlin collections or trying to log an internal state you will need to represent collections as strings. I really liked when I learned that Kotlin standard library has a function just for this reason:
<h3>.joinToString()</h3>
<img class="alignnone wp-image-3703 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/String2-1030x515.png" alt="" width="1030" height="515" />

If don't pass any parameters to <code>.joinToString()</code>, string representations of each items will be concatenated in a string and separated by commas with spaces by default.
<h3>Customizing the separator, prefix and postfix strings</h3>
<img class="alignnone wp-image-3706 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/String3-1030x515.png" alt="" width="1030" height="515" />

However, if you need to change the separator strings or add some more useful information to the start or to the end you can pass some arguments for <code>separator</code>, <code>prefix</code> and <code>postfix</code> parameters.
<h3>The limit and truncated arguments</h3>
<img class="alignnone wp-image-3708 size-large" src="https://ac.appcircle.io/wp-content/uploads/2022/10/String4-1030x515.png" alt="" width="1030" height="515" />

<code>.joinToString()</code> also support limiting and truncating the list. If you have a long list and don't want to print everything and make a mess, you can limit how many elements you want in the resulting string and what string to use in the place of an ellipsis.

--

Finally, it also supports passing a transform lambda if you also want to define how each item will be converted into a string.

You can study the <a href="https://kotlinlang.org/docs/collection-transformations.html#string-representation">official documentation</a> to learn more about the topic.

---

That was it! Now you have learned how to transform Kotlin collections using a handful of convenience functions.

If you like the article please share in your social media and if you want to learn more on Kotlin's standard library functions, let us know!