avatarGabriel Shanahan

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

3957

Abstract

gt;, List<T>></pre></div><p id="f5c4">The <code>partition</code> method is, in a sense, a simpler version of <code>groupBy</code>, which allows you to split a collection into a pair of collections — one which satisfies a given predicate, and one which doesn’t.</p> <figure id="82ec"> <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%2FE90DIvmjr&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2FE90DIvmjr&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figure></iframe></div></div></figure><h1 id="f5b9">Groupings</h1><h2 id="7029">groupingBy</h2><div id="936f"><pre><span class="hljs-keyword">inline</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-type"><T, K></span> Iterable<span class="hljs-type"><T></span>.<span class="hljs-title">groupingBy</span><span class="hljs-params">( <span class="hljs-keyword">crossinline</span> keySelector: (<span class="hljs-type">T</span>) -> <span class="hljs-type">K</span> )</span></span>: Grouping<T, K></pre></div><p id="a6b7">A more general version of <code>groupBy</code>, <code>groupingBy</code> returns an instance of <code>Grouping</code>, which defines its own methods that can be used to implement more general calculations.</p><h2 id="0a04">eachCount</h2><div id="307a"><pre><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-type"><T, K></span> Grouping<span class="hljs-type"><T, K></span>.<span class="hljs-title">eachCount</span><span class="hljs-params">()</span></span>: Map<K, <span class="hljs-built_in">Int</span>></pre></div><p id="fbac">Returns a map with the count of each group, i.e. for each <code>key: K</code> the map contains the number of elements that were grouped under that key.</p><p id="9a09">The <code>eachCount</code> method also has a <code>*To</code> variant.</p><h2 id="300d">fold, reduce</h2><div id="703f"><pre><span class="hljs-keyword">inline</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-type"><T, K, R></span> Grouping<span class="hljs-type"><T, K></span>.<span class="hljs-title">fold</span><span class="hljs-params">( initialValueSelector: (<span class="hljs-type">key</span>: <span class="hljs-type">K</span>, <span class="hljs-type">element</span>: <span class="hljs-type">T</span>) -> <span class="hljs-type">R</span>, operation: (<span class="hljs-type">key</span>: <span class="hljs-type">K</span>, <span class="hljs-type">accumulator</span>: <span class="hljs-type">R</span>, <span class="hljs-type">element</span>: <span class="hljs-type">T</span>) -> <span class="hljs-type">R</span> )</span></span>: Map<K, R></pre></div><div id="9a19"><pre><span class="hljs-keyword">inline</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-type"><S, T : S, K></span> Grouping<span class="hljs-type"><T, K></span>.<span class="hljs-title">reduce</span><span class="hljs-params">( operation: (<span class="hljs-type">key</span>: <span class="hljs-type">K</span>, <span class="hljs-type">accumulator</span>: <span class="hljs-type">S</span>, <span class="hljs-type">element</span>: <span class="hljs-type">T</span>) -> <span class="hljs-type">S</span> )</span></span>: Map<K, S></pre></div><p id="d5a0">Essentially applies <code>fold</code>/<code>reduce</code> to each group. The meaning of the parameters is as follows:</p><p id="e82c"><code><b>initialValueSelector</b></code> — a function that provides an initial value of accumulator for each group. It’s invoked with par

Options

ameters:</p><ul><li><i>key</i>: the key of the group</li><li><i>element</i>: the first element being encountered in that group</li></ul><p id="7c0b"><code><b>operation</b></code> — a function that is invoked on each element with the following parameters:</p><ul><li><i>key</i>: the key of the group this element belongs to</li><li><i>accumulator</i>: the current value of the accumulator of the group</li><li><i>element</i>: the element from the source being accumulated</li></ul><p id="4f58"><b>Example</b></p> <figure id="0624"> <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%2FIL1C6wTsQ&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2FIL1C6wTsQ&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="e9c6">There is also a variant of <code>fold </code>where the initial value for <code>fold</code> is the same for each group:</p><div id="07b9"><pre><span class="hljs-keyword">inline</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-type"><T, K, R></span> Grouping<span class="hljs-type"><T, K></span>.<span class="hljs-title">fold</span><span class="hljs-params">( initialValue: <span class="hljs-type">R</span>, operation: (<span class="hljs-type">accumulator</span>: <span class="hljs-type">R</span>, <span class="hljs-type">element</span>: <span class="hljs-type">T</span>) -> <span class="hljs-type">R</span> )</span></span>: Map<K, R></pre></div><p id="46da">All the above also have <code>*To</code> variants.</p><h2 id="8829">Grouping<T, K>.aggregate</h2><div id="5385"><pre><span class="hljs-keyword">inline</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-type"><T, K, R></span> Grouping<span class="hljs-type"><T, K></span>.<span class="hljs-title">aggregate</span><span class="hljs-params">( operation: ( <span class="hljs-type">key</span>: <span class="hljs-type">K</span>, <span class="hljs-type">accumulator</span>: <span class="hljs-type">R</span>?, <span class="hljs-type">element</span>: <span class="hljs-type">T</span>, <span class="hljs-type">first</span>: <span class="hljs-type">Boolean</span> ) -> <span class="hljs-type">R</span> )</span></span>: Map<K, R></pre></div><p id="77bc">A slightly different version of <code>fold</code> — instead of specifying the initial value with a function, the information is passed directly into the <code>operation</code> via a parameter.</p><p id="9978"><code><b>operation</b></code> — is invoked on each element with the following parameters:</p><ul><li><i>key</i>: the key of the group this element belongs to</li><li><i>accumulator</i>: the current value of the accumulator of the group, can be null if it’s the first element encountered in the group</li><li><i>element</i>: the element from the source being aggregated</li><li><i>first</i>: indicates whether it’s the first element encountered in the group</li></ul><p id="6a90">The <code>aggregate</code> method also has a <code>*To</code> variant.</p><p id="8e74">Go back to <a href="https://readmedium.com/collection-operations-aggregators-304aa23cceed">Collection Operations: Aggregations</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/sequences-why-we-need-them-45b320e8922">Sequences: Why We Need Them</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: Grouping

An introduction to the most important functions for grouping: groupBy, partition, groupingBy, fold, reduce, aggregate and their variants.

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

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.

groupBy

inline fun <T, K> Iterable<T>.groupBy(
    keySelector: (T) -> K
): Map<K, List<T>>

The groupBy function is the most common function used for grouping. It allows you to group elements of a collection in a map, under keys given by keySelector.

Example

There is also a variant which allows you to transform the value:

Both also have *To variants.

partition

inline fun <T> Iterable<T>.partition(
    predicate: (T) -> Boolean
): Pair<List<T>, List<T>>

The partition method is, in a sense, a simpler version of groupBy, which allows you to split a collection into a pair of collections — one which satisfies a given predicate, and one which doesn’t.

Groupings

groupingBy

inline fun <T, K> Iterable<T>.groupingBy(
    crossinline keySelector: (T) -> K
): Grouping<T, K>

A more general version of groupBy, groupingBy returns an instance of Grouping, which defines its own methods that can be used to implement more general calculations.

eachCount

fun <T, K> Grouping<T, K>.eachCount(): Map<K, Int>

Returns a map with the count of each group, i.e. for each key: K the map contains the number of elements that were grouped under that key.

The eachCount method also has a *To variant.

fold, reduce

inline fun <T, K, R> Grouping<T, K>.fold(
    initialValueSelector: (key: K, element: T) -> R,
    operation: (key: K, accumulator: R, element: T) -> R
): Map<K, R>
inline fun <S, T : S, K> Grouping<T, K>.reduce(
    operation: (key: K, accumulator: S, element: T) -> S
): Map<K, S>

Essentially applies fold/reduce to each group. The meaning of the parameters is as follows:

initialValueSelector — a function that provides an initial value of accumulator for each group. It’s invoked with parameters:

  • key: the key of the group
  • element: the first element being encountered in that group

operation — a function that is invoked on each element with the following parameters:

  • key: the key of the group this element belongs to
  • accumulator: the current value of the accumulator of the group
  • element: the element from the source being accumulated

Example

There is also a variant of fold where the initial value for fold is the same for each group:

inline fun <T, K, R> Grouping<T, K>.fold(
    initialValue: R,
    operation: (accumulator: R, element: T) -> R
): Map<K, R>

All the above also have *To variants.

Grouping<T, K>.aggregate

inline fun <T, K, R> Grouping<T, K>.aggregate(
    operation: (
        key: K, 
        accumulator: R?, 
        element: T, 
        first: Boolean
    ) -> R
): Map<K, R>

A slightly different version of fold — instead of specifying the initial value with a function, the information is passed directly into the operation via a parameter.

operation — is invoked on each element with the following parameters:

  • key: the key of the group this element belongs to
  • accumulator: the current value of the accumulator of the group, can be null if it’s the first element encountered in the group
  • element: the element from the source being aggregated
  • first: indicates whether it’s the first element encountered in the group

The aggregate method also has a *To variant.

Go back to Collection Operations: Aggregations, jump to the Table of Contents, or continue to Sequences: Why We Need Them.

Kotlin
Java
Programming
Functional Programming
Collection
Recommended from ReadMedium