The provided content offers an in-depth exploration of collection transformation functions in Kotlin, including map, flatMap, flatten, set operations like union, intersect, and subtract, order transformations such as sorted, and other utilities like associate, zip, and unzip.
Abstract
The web content serves as a comprehensive guide to collection transformations in Kotlin, emphasizing the importance of these operations in everyday coding. It introduces the map function and its variants, such as mapNotNull and mapIndexed, which are essential for element-wise transformations. The guide also covers flatMap and its role in flattening nested collections, alongside the flatten function that collapses a hierarchy of collections into a single list. Set-related transformations like union, intersect, and subtract are explained, showcasing their use in manipulating sets. For ordering collections, the content discusses sorted and its derivatives, including sortedBy and sortedWith, which allow for custom sorting criteria. Additionally, the reverse function is presented for inverting collection order. The miscellaneous section delves into functions like associate for creating maps from collections, as well as zip and unzip for pairing and separating collection elements, respectively. The article is part of the "Kotlin Primer" series, aimed at facilitating Kotlin adoption in Java-centric organizations, and includes interactive examples using the Kotlin Playground.
Opinions
The author considers map as the most fundamental and ubiquitous collection transformation, suggesting its widespread use in programming.
The flatMap function is highlighted as more powerful than map due to its ability to handle transformations that result in collections, which are then merged.
The use of flatten is presented as a foundational operation that complements flatMap by reducing nested collections into a single dimension.
Set operations are described as straightforward and intuitive, with the functions union, intersect, and subtract being infix functions that read naturally in code.
The stability of the sorted function is noted as an important characteristic for predictable sorting behavior.
The associate function and its variants are recommended for transforming collections into maps, with the caveat that duplicate keys will result in the last key-value pair being used.
The zip and unzip functions are portrayed as convenient for working with pairs of collections, with zip being particularly useful for transforming elements from two lists simultaneously.
The article encourages readers to engage with interactive examples provided via Kotlin Playground links, reinforcing the practical application of the concepts discussed.
The content is positioned as part of a larger educational resource, the "Kotlin Primer," indicating a structured approach to learning Kotlin's collection operations.
Collection Operations: Transformations
An introduction to the most important collection transformations — map, flatMap, flatten, intersection, union, subtract, sorted, reverse, associate, zip, unzip, and their variants.
— — — — — — — — — — — — — — —
THE CURRENT VERSION OF THIS ARTICLE IS PUBLISHED HERE.
This article is part of the Kotlin Primer, an opinionated guide to the Kotlin language, which is indented to help facilitate Kotlin adoption inside Java-centric organizations. It was originally written as an organizational learning resource for Etnetera a.s. and I would like to express my sincere gratitude for their support.
The most fundamental collection transformation, and the most often used, is map, which accepts a lambda and applies it to every element of a collection.
Example
This use-case is so ubiquitous that you would be hard pressed to find any piece of code where map is not used.
There are a few useful variants of map:
One is mapNotNull, which also applies a transformation, but only includes the result if it’s non-null.
All the above have *To variants, which perform the same operation, but insert the result into a passed-in mutable collection:
flatMap
A related function to map is flatMap, which also performs a transformation of each element, but expects the transformation to produce collections of elements, which then get “flattened” (flatMap) or “merged” into a single List.
To get a feel for the relationship between map and flatMap, it can be useful to realize that you can define map in terms of flatMap:
However, you cannot do the opposite without using an additional function — flatten, which we’ll talk about in a sec.
This means that flatMap is more general, more “powerful”, than a simple map. That actually makes sense, because flatMap literally means mapping-and-then-flattening.
As with map, you have the *Indexed and *To variants, and their combination. However, there is no flatMapNotNull — that doesn’t make sense, because the transformation always needs to return an instance of List.
flatten
flatten is the function we need to be able to define flatMap in terms of map. It takes e.g. a List<List<T> and “flattens” it to a List<T>.
Defined only on collections of Comparable elements, sorted returns a newList, which is sorted in an ascending order according to the implementation of Comparable. The sorting does not happen in place, and is stable.
There are a few sorting variants.
One is sortedBy, which allows one to specify a transformation to the elements. They will then be sorted according to the result of the transformation, which means that the result of the transformation needs to be Comparable.
Transforms a collection of elements to a collections of Pairs, and creates a map out of them.
Example
This could be implemented in terms of map:
When duplicate keys are encountered, the last one is used.
As always, there are useful variants — associateBy allows one to specify a transformation which generates only the key of the resulting Map, while associateWith generates only the value. This is best understood by implementing both in terms of associate:
There is also a two-parameter variant of associateBy, which allows one to specify a transformation for the value as well:
As always, *To variants are also included for all of the above.
zip, unzip
zip“zips” together two collections, to create a single List of Pairs. The returned list is as long as the shortest collection.
There is a really useful variant of zip that allows you to transform the resulting pair — in effect, it’s like applying map to the elements of two lists at once.