avatarGabriel Shanahan

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

3833

Abstract

e>filterIndexed</code>, <code>filterIsInstance</code>, <code>orEmpty</code>, <code>slice</code>, <code>take</code>, <code>takeWhile</code>, <code>takeLast</code>, <code>takeLastWhile</code></p><h2 id="f8ce">Single element access</h2><p id="e0de"><code>elementAt</code>, <code>elementAtOrElse</code>, <code>elementAtOrNull</code>, <code>find</code>, <code>findLast</code>, <code>first</code>, <code>firstOrNull</code>, <code>get</code>, <code>getOrElse</code>, <code>indexOf</code>, <code>indexOfFirst</code>, <code>indexOfLast</code>, <code>last</code>, <code>lastIndexOf</code>, <code>lastOrNull</code>, <code>single</code>, <code>singleOrNull</code></p><h2 id="0eaf">Predicates</h2><p id="aecc"><code>all</code>, <code>any</code>, <code>contains</code>, <code>containsAll</code>, <code>none</code>, <code>isEmpty</code>, <code>isNotEmpty</code></p><h2 id="764a">Aggregators</h2><p id="0d75"><code>fold</code>, <code>foldIndexed</code>, <code>foldRight</code>, <code>foldRightIndexed</code>, <code>reduce</code>, <code>reduceIndexed</code>, <code>reduceRight</code>, <code>reduceRightIndexed</code>, <code>average</code>, <code>count</code>, <code>max</code>, <code>maxBy</code>, <code>maxOf</code>, <code>maxWith</code>, <code>min</code>, <code>minBy</code>,<code>minOf</code>, <code>minWith</code>, <code>sum</code>, <code>sumOf</code></p><h2 id="d25e">Grouping</h2><p id="278a"><code>groupBy</code>, <code>groupByTo</code>, <code>groupingBy</code>, <code>partition</code></p><h1 id="a8ba">Naming patterns</h1><p id="755a">There are a few patterns in the way collection operations are named that are useful to be aware of. For a operation <code>{o}</code> (e.g. <code>map</code>), usually at least some of the following are defined:</p><p id="e2ec"><code><b>{o}To</b></code><b> (e.g. <code>mapTo</code>)</b></p><p id="3107">Always accepts a mutable collection as one of its parameters. Instead of returning a new collection, as the result of the transformation, instead inserts the result into the mutable collection that was passed.</p> <figure id="7b32"> <div> <div> <img class="ratio" src="http://placehold.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2FMTKhH8GMM&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2FMTKhH8GMM&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figure></iframe></div></div></figure><p id="5ce5"><code><b>{o}By</b></code><b> (e.g. max<code>By</code>)</b></p><p id="96e7">Instead of applying the operation to the collection directly, it first applies a transformation to each element. For example, <code>max</code> finds the maximum value in a collection, and therefore naturally requires the collection to contain comparable elements. Given that, think about how you would go about finding the oldest person in a collection of people. You would have to extract the ages, construct some mapping between them and the person they correspond to, find the maximum age, and then extract the corresponding person. What a mess. This is exactly what the <code>{o}By</code> variants are for:</p> <figure id="4d3d"> <div> <div> <img class="ratio" src="http://placehold.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2F4dscMCWpH&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2F4dscMCWpH&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figu

Options

re></iframe></div></div></figure><p id="e663">From time to time, you will also encounter <code>{o}With</code> variants. They are similar to <code>{o}By</code> in that they allow you to give additional instructions on how the operation should be performed, but differently — e.g. <code>maxWith</code> allows you to pass in a <code>Comparator</code> that will be used to find the maximum.</p><p id="cfb4">The only exception to this rule I’m aware of is <code>associate</code>, where <code>associateBy</code> and <code>associateWith</code> don’t conform to this pattern (and instead carry a much more natural meaning). We’ll talk about them in the chapter on <a href="https://readmedium.com/collections-transformations-8b5e1efdf3d8">transformations</a>.</p><p id="4275"><code><b>{o}Indexed</b></code><b> (e.g. <code>mapIndexed</code>)</b></p><p id="5111">Passes an additional parameter to the operation containing the index of the element that is being operated on:</p> <figure id="0bdf"> <div> <div> <img class="ratio" src="http://placehold.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2FBHtn1RpGi&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2FBHtn1RpGi&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figure></iframe></div></div></figure><p id="0656"><code><b>{o}orNull</b></code><b> (e.g. <code>firstOrNull</code>)</b></p><p id="01c6">Used with operations that might not have a defined result — e.g. for <code>first</code>, there is no sensible result when the list is empty. The regular variant throws an exception, while the <code>{o}orNull</code> variant returns <code>null</code> instead.</p> <figure id="9787"> <div> <div> <img class="ratio" src="http://placehold.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2Fp1U4Z2Dmc&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2Fp1U4Z2Dmc&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figure></iframe></div></div></figure><h2 id="b142">Imperative verbs vs. adjectives</h2><p id="b6ca">Most operations are defined on immutable collections, and therefore do not modify the original collection and return a new collection — e.g. <code>filter</code> doesn’t not remove elements from the collection it is run on.</p><p id="f4b8">However, with mutable collections, there are certain operations that can also be performed in-place, e.g. sorting. To differentiate between the two, the form of an imperative verb (e.g. <code>sort</code>) is used for the variant that modifies the collection in place, while the form of an adjective (e.g. <code>sorted</code>) is used for the variant that returns a new collection.</p><p id="4812">More information can be found in <a href="https://kotlinlang.org/docs/collection-operations.html">the docs</a>.</p><p id="a594">Go back to <a href="https://readmedium.com/functional-vs-object-oriented-programming-3979e3f5d0ba">Functional vs.? Object Oriented Programming</a>, jump to the <a href="https://readmedium.com/table-of-contents-c52573cfa291">Table of Contents</a>, or continue to <a href="https://readmedium.com/collection-operations-transformations-8b5e1efdf3d8">Collections Operations: Transformations</a>.</p><figure id="8ecd"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*biBSB579iezsNvEQ_NMLBg.png"><figcaption></figcaption></figure></article></body>

Collection Operations: Overview

A list of the collection transformations you should definitely know about, and an overview of patterns in the names of operations that you will encounter.

— — — — — — — — — — — — — — —

THE CURRENT VERSION OF THIS ARTICLE IS PUBLISHED HERE.

— — — — — — — — — — — — — — —

Tags: #FYI++

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.

It is recommended to read the Introduction before moving on. Check out the Table of Contents for all articles.

In the previous article, we talked about the usefulness of both the object-oriented and functional styles, and explained when you should use which:

Structure your programs using OOP, and implement behaviors using FP.

Of course, to be able to do implement behaviors using FP, you have to learn the names and purposes of the FP building blocks, in the same way you learned OOP patterns — builders, factories etc. The Kotlin Standard Library is chock-full with them, and it is the purpose of the following set of articles to give you a passing familiarity with those that are used most often.

However, unless you’re already familiar with this style of thinking, it will probably be more that you can memorize, so instead, I recommend this: focus on designing behaviors in the same way you design programs. Think before you write, decompose your behaviors into atomic pieces, and then search the internet to see if the standard library already contains something similar. Over time, you’ll absorb the contents of the standard library and learn to get a feeling for which patterns are “core” and almost certainly implemented vs. which ones aren’t, and need to be implemented locally.

Collection operations

To give you an idea of the breadth covered by the standard library, here is a (partial) list of available functions. We will be covering a large part of them in the following articles. All of them are defined as extension functions.

See if you can figure out what they do just based on the name.

Transformers

associate, flatten, flatMap, intersect, map, mapNotNull, mapIndexed, mapIndexedNotNull, reversed, sorted, sortedByDescending, sortedWith, union, unzip, zip

Filtering

binarySearch, distinct, distinctBy, drop, dropWhile, dropLast, dropLastWhile, filter, filterIndexed, filterIsInstance, orEmpty, slice, take, takeWhile, takeLast, takeLastWhile

Single element access

elementAt, elementAtOrElse, elementAtOrNull, find, findLast, first, firstOrNull, get, getOrElse, indexOf, indexOfFirst, indexOfLast, last, lastIndexOf, lastOrNull, single, singleOrNull

Predicates

all, any, contains, containsAll, none, isEmpty, isNotEmpty

Aggregators

fold, foldIndexed, foldRight, foldRightIndexed, reduce, reduceIndexed, reduceRight, reduceRightIndexed, average, count, max, maxBy, maxOf, maxWith, min, minBy,minOf, minWith, sum, sumOf

Grouping

groupBy, groupByTo, groupingBy, partition

Naming patterns

There are a few patterns in the way collection operations are named that are useful to be aware of. For a operation {o} (e.g. map), usually at least some of the following are defined:

{o}To (e.g. mapTo)

Always accepts a mutable collection as one of its parameters. Instead of returning a new collection, as the result of the transformation, instead inserts the result into the mutable collection that was passed.

{o}By (e.g. maxBy)

Instead of applying the operation to the collection directly, it first applies a transformation to each element. For example, max finds the maximum value in a collection, and therefore naturally requires the collection to contain comparable elements. Given that, think about how you would go about finding the oldest person in a collection of people. You would have to extract the ages, construct some mapping between them and the person they correspond to, find the maximum age, and then extract the corresponding person. What a mess. This is exactly what the {o}By variants are for:

From time to time, you will also encounter {o}With variants. They are similar to {o}By in that they allow you to give additional instructions on how the operation should be performed, but differently — e.g. maxWith allows you to pass in a Comparator that will be used to find the maximum.

The only exception to this rule I’m aware of is associate, where associateBy and associateWith don’t conform to this pattern (and instead carry a much more natural meaning). We’ll talk about them in the chapter on transformations.

{o}Indexed (e.g. mapIndexed)

Passes an additional parameter to the operation containing the index of the element that is being operated on:

{o}orNull (e.g. firstOrNull)

Used with operations that might not have a defined result — e.g. for first, there is no sensible result when the list is empty. The regular variant throws an exception, while the {o}orNull variant returns null instead.

Imperative verbs vs. adjectives

Most operations are defined on immutable collections, and therefore do not modify the original collection and return a new collection — e.g. filter doesn’t not remove elements from the collection it is run on.

However, with mutable collections, there are certain operations that can also be performed in-place, e.g. sorting. To differentiate between the two, the form of an imperative verb (e.g. sort) is used for the variant that modifies the collection in place, while the form of an adjective (e.g. sorted) is used for the variant that returns a new collection.

More information can be found in the docs.

Go back to Functional vs.? Object Oriented Programming, jump to the Table of Contents, or continue to Collections Operations: Transformations.

Kotlin
Java
Programming
Functional Programming
Collection
Recommended from ReadMedium