<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kotlin</title>
    <description>The latest articles on DEV Community by Kotlin (@kotlin).</description>
    <link>https://dev.to/kotlin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F2485%2F80d41bc3-7f05-444c-a32e-ceb190e486b1.png</url>
      <title>DEV Community: Kotlin</title>
      <link>https://dev.to/kotlin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kotlin"/>
    <language>en</language>
    <item>
      <title>Idiomatic Kotlin: Solving Advent of Code Puzzles, Binary Boarding</title>
      <dc:creator>Svetlana Isakova</dc:creator>
      <pubDate>Fri, 10 Sep 2021 08:50:58 +0000</pubDate>
      <link>https://dev.to/kotlin/idiomatic-kotlin-solving-advent-of-code-puzzles-binary-boarding-513e</link>
      <guid>https://dev.to/kotlin/idiomatic-kotlin-solving-advent-of-code-puzzles-binary-boarding-513e</guid>
      <description>&lt;p&gt;Let’s continue our journey of understanding what “idiomatic Kotlin” means and solve one more puzzle from the Advent of Code challenge. The puzzles are independent of each other, so you don’t need to check any of the previous ones we’ve already covered. Simply read through the following solution or watch the video. We hope you learn something new!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/XEFna3xyxeY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 5. Binary Boarding
&lt;/h2&gt;

&lt;p&gt;We’re boarding the plane! We need to analyze the list of boarding passes and find the seat with the highest seat ID. Then we need to find the one seat missing from the list, which is ours. You can find the full task description at &lt;a href="https://adventofcode.com/2020/day/5"&gt;https://adventofcode.com/2020/day/5&lt;/a&gt;.*&lt;/p&gt;

&lt;p&gt;A seat is specified as, for example, &lt;code&gt;FBFBBFFRLR&lt;/code&gt;, where &lt;code&gt;F&lt;/code&gt; means "front", &lt;code&gt;B&lt;/code&gt; means "back", &lt;code&gt;L&lt;/code&gt; means "left", and &lt;code&gt;R&lt;/code&gt; means "right". The first 7 characters are either &lt;code&gt;F&lt;/code&gt; or &lt;code&gt;B&lt;/code&gt; and they specify exactly one of the 128 rows on the plane (numbered 0 through 127). The last three characters are either &lt;code&gt;L&lt;/code&gt; or &lt;code&gt;R&lt;/code&gt;; these specify exactly one of the 8 columns of seats on the plane (numbered 0 through 7). A more detailed encoding description is given on the &lt;a href="https://adventofcode.com/2020/day/5"&gt;puzzle page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Every seat has a unique seat ID, calculated by multiplying the row by 8 and then adding the column.&lt;/p&gt;

&lt;p&gt;The puzzle input is the list of boarding passes. The first task is to find the boarding pass in this list with the highest seat ID.&lt;/p&gt;

&lt;p&gt;The second task is to find the missing boarding pass in the list. The flight is completely full, there’s only one missing boarding pass, and that’s our seat. However, some of the seats at the very front and back of the plane don't exist on this aircraft, so they are missing from the list as well.&lt;/p&gt;

&lt;p&gt;As usual, we suggest that you try to solve the task on your own before reading the solution. Here’s how you can &lt;a href="https://blog.jetbrains.com/kotlin/2021/07/advent-of-code-in-idiomatic-kotlin/#how-to-solve"&gt;set up Kotlin&lt;/a&gt; for this purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Let’s first discuss the encoding of the boarding passes. Note how it is a nicely “hidden” binary representation of natural numbers! Let’s take a closer look.&lt;/p&gt;

&lt;h3&gt;
  
  
  Boarding pass: binary representation
&lt;/h3&gt;

&lt;p&gt;First, let’s look at the rows. There are 128 rows on the plane, which are encoded with 7 “bits”. These bits are called F and B in the puzzle, but they carry the same meaning as 0 and 1 do in the binary representation. To extend the analogy, the way to identify the exact row based on the boarding pass is reminiscent of the algorithm used to convert a binary representation of the number to a decimal.&lt;/p&gt;

&lt;p&gt;Let’s consider the provided example – the first seven characters of &lt;code&gt;FBFBBFFRLR&lt;/code&gt; that decode the “row”. &lt;code&gt;F&lt;/code&gt; means to take the “front”, or the lower half, while &lt;code&gt;B&lt;/code&gt; is to take the “back”, or the upper half on each iteration. Taking the lower half is equivalent to not adding the corresponding power of two to the result (or multiplying it by zero), while taking the upper half is equivalent to adding it to the result (or multiplying it by one).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;F = 0; B = 1
FB notation  F  B  F  B  B  F  F
Bit          0  1  0  1  1  0  0
Index        6  5  4  3  2  1  0
2^Index      64 32 16 8  4  2  1

Decimal:
0 * 2^6 + 1 * 2^5 + 0 * 2^4 + 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 0 * 2^0 =
32 + 8 + 4 = 
44
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this conversion is clear to you, you can skip the remaining explanations in this section and go directly to the Kotlin implementation. If not, please read the description of the conversion strategy on the task page and the following explanations carefully.&lt;/p&gt;

&lt;p&gt;We start by considering the whole range, rows &lt;code&gt;0&lt;/code&gt; through &lt;code&gt;127&lt;/code&gt;. The maximum value that can be decoded via 7 bits is &lt;code&gt;1111111&lt;/code&gt;, or &lt;code&gt;127&lt;/code&gt; if converted to the decimal form: &lt;code&gt;2&lt;sup&gt;7&lt;/sup&gt; - 1 = 2&lt;sup&gt;6&lt;/sup&gt; + 2&lt;sup&gt;5&lt;/sup&gt; + 2&lt;sup&gt;4&lt;/sup&gt; + 2&lt;sup&gt;3&lt;/sup&gt; + 2&lt;sup&gt;2&lt;/sup&gt; + 2&lt;sup&gt;1&lt;/sup&gt; + 2&lt;sup&gt;0&lt;/sup&gt; = 127&lt;/code&gt;. Each bit is responsible for its part of the range: if it’s &lt;code&gt;1&lt;/code&gt;, we add the corresponding power of two to the result; if it’s &lt;code&gt;0&lt;/code&gt;, we skip it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Bit&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Bit index&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Description of the task&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Reworded in ‘binary representation’ terms&lt;/strong&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;F = 0&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;6&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;F&lt;/code&gt; means to take the lower half, keeping rows 0 through 63.
   &lt;/td&gt;
   &lt;td&gt;We don’t add &lt;code&gt;2&lt;sup&gt;6&lt;/sup&gt;=64&lt;/code&gt; to the result.
&lt;p&gt;
That keeps the result in the &lt;code&gt;0..(127-64)&lt;/code&gt; range, or &lt;code&gt;0..63&lt;/code&gt;.
   &lt;/p&gt;
&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;B = 1&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;5&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;B&lt;/code&gt; means to take the upper half, keeping rows 32 through 63.
   &lt;/td&gt;
   &lt;td&gt;We add &lt;code&gt;2&lt;sup&gt;5&lt;/sup&gt;=32&lt;/code&gt; to the result. That keeps the result in the range &lt;code&gt;32..63&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;F = 0&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;4&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;F&lt;/code&gt; means to take the lower half, keeping rows 32 through 47.
   &lt;/td&gt;
   &lt;td&gt;We don’t add &lt;code&gt;2&lt;sup&gt;4&lt;/sup&gt;=16&lt;/code&gt; to the result. That makes the possible range &lt;code&gt;32..(63-16)&lt;/code&gt;, or &lt;code&gt;32..47&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;B = 1&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;3&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;B&lt;/code&gt; means to take the upper half, keeping rows 40 through 47.
   &lt;/td&gt;
   &lt;td&gt;We add &lt;code&gt;2&lt;sup&gt;3&lt;/sup&gt;=8&lt;/code&gt; to the result. That keeps the result in the range &lt;code&gt;(32+8)..47&lt;/code&gt;, or &lt;code&gt;40..47&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;B = 1&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;2&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;B&lt;/code&gt; keeps rows 44 through 47.
   &lt;/td&gt;
   &lt;td&gt;We add &lt;code&gt;2&lt;sup&gt;2&lt;/sup&gt;=4&lt;/code&gt; to the result. That keeps the result in the range &lt;code&gt;(40+4)..47&lt;/code&gt;, or &lt;code&gt;44..47&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;F = 0&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;1&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;F&lt;/code&gt; keeps rows 44 through 45.
   &lt;/td&gt;
   &lt;td&gt;We don’t add &lt;code&gt;2&lt;sup&gt;1&lt;/sup&gt;=2&lt;/code&gt;. That makes the possible range &lt;code&gt;44..(47-2)&lt;/code&gt;, or &lt;code&gt;44..45&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;F = 0&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;0&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;The final &lt;code&gt;F&lt;/code&gt; keeps the lower of the two, row 44.
   &lt;/td&gt;
   &lt;td&gt;We don’t add &lt;code&gt;2&lt;sup&gt;0&lt;/sup&gt;=1&lt;/code&gt;. That makes the result &lt;code&gt;44..(45-1)&lt;/code&gt;, or simply &lt;code&gt;44&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Decoding column
&lt;/h4&gt;

&lt;p&gt;Decoding the column follows the same logic, but now &lt;code&gt;R&lt;/code&gt; takes the upper half and corresponds to bit &lt;code&gt;1&lt;/code&gt;, while &lt;code&gt;L&lt;/code&gt; takes the lower half and corresponds to bit &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's now consider the last 3 characters of &lt;code&gt;FBFBBFFRLR&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;L = 0; R = 1
RL notation  R  L  R
Bit          1  0  1
Index        2  1  0
2^Index      4  2  1

Decimal:
1 * 2^2 + 0 * 2^1 + 1 * 2^0 =
4 + 1 = 
5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The whole range represents columns 0 through 7. It’s the maximum value that can be encoded via three bits: &lt;code&gt;2&lt;sup&gt;2&lt;/sup&gt; + 2&lt;sup&gt;1&lt;/sup&gt; + 2&lt;sup&gt;0&lt;/sup&gt; = 7&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;R&lt;/code&gt; means to take the upper half, keeping columns 4 through 7. In other words, take &lt;code&gt;2&lt;sup&gt;2&lt;/sup&gt;=4&lt;/code&gt; with the multiplier &lt;code&gt;"1"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;L&lt;/code&gt; means to take the lower half, keeping columns 4 through 5. In other words, take &lt;code&gt;2&lt;sup&gt;1&lt;/sup&gt;=2&lt;/code&gt; with the multiplier &lt;code&gt;"0"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The final &lt;code&gt;R&lt;/code&gt; keeps the upper of the two, column 5. In other words, take &lt;code&gt;2&lt;sup&gt;0&lt;/sup&gt;=1&lt;/code&gt; with the multiplier &lt;code&gt;"1",&lt;/code&gt; making the result &lt;code&gt;4+1=5&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last part is converting the row and the column numbers to the seat ID by using the formula: multiply the row by 8 and then add the column. For the sample boarding pass, the row is &lt;code&gt;44&lt;/code&gt; and the column is &lt;code&gt;5&lt;/code&gt;, so this calculation gives the seat ID as &lt;code&gt;44 * 8 + 5 = 357&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Combining row and column
&lt;/h4&gt;

&lt;p&gt;But if we look closer at this formula, we’ll notice that we don’t need to find the row and column separately! We can simply add all the row bits with indexes increased by three to the result (note that &lt;code&gt;8 = 2&lt;sup&gt;3&lt;/sup&gt;&lt;/code&gt;). This bit operation is formally called “left-shift”.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FBRL notation  F  B  F  B  B  F  F  R  L  R
Bit            0  1  0  1  1  0  0  1  0  1
Index          9  8  7  6  5  4  3  2  1  0

Decimal:
[0 * 2^9 + 1 * 2^8 + 0 * 2^7 + 1 * 2^6 + 1 * 2^5 + 0 * 2^4 + 0 * 2^3] + [1 * 2^2 + 0 * 2^1 + 1 * 2^0] =
2^3 * [0 * 2^6 + 1 * 2^5 + 0 * 2^4 + 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 0 * 2^0] + [1 * 2^2 + 0 * 2^1 + 1 * 2^0] =
8 * 44 + 5 = 
357
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a little bit of math, a Kotlin solution can almost fit on a single line! Let’s see how.&lt;/p&gt;

&lt;h3&gt;
  
  
  Converting boarding pass to seat ID
&lt;/h3&gt;

&lt;p&gt;We only need to replace &lt;code&gt;B/F&lt;/code&gt; and &lt;code&gt;R/L&lt;/code&gt; with &lt;code&gt;1/0&lt;/code&gt; notation, and then convert the resulting binary representation to an integer. Each of these operations is one function call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toSeatID&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'B'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'F'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'R'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'L'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;radix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0101100101"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;radix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// 357&lt;/span&gt;
   &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FBFBBFFRLR"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toSeatID&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;       &lt;span class="c1"&gt;// 357&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;String.replace(oldChar: Char, newChar: Char)&lt;/code&gt; function replaces all occurrences of the old character with the new character. There are two more similar functions. If you need to replace each substring with a new string, pass the strings as arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oldValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to replace each substring that matches the given regular expression, use another function taking &lt;code&gt;Regex&lt;/code&gt; as an argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;String.toInt(radix: Int)&lt;/code&gt; function parses the string receiver as an integer in the specified radix. In our case, we specify that the radix is two, so it parses the binary representation of the number.&lt;/p&gt;

&lt;p&gt;There’s no need to reimplement the conversion algorithm from scratch when you can use the library functions – unless you specifically want to practice that, of course, but that’s not the goal of this puzzle.&lt;/p&gt;

&lt;p&gt;We’ve got the seat ID from the boarding pass now and we can continue with the task.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding the maximum seat ID
&lt;/h3&gt;

&lt;p&gt;As usual, we need to read the input first. After implementing the conversion function, it’s quite straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;seatIDs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"src/day05/input.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readLines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toSeatID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The seatIDs list is a list of integers, and the only thing left is finding the maximum in this list. There’s no need to implement it from scratch; we simply use the &lt;code&gt;maxOrNull()&lt;/code&gt; library function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;seatIDs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;maxID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seatIDs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;maxOrNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Max seat ID: $maxID"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ve found the seat with the maximum seat ID.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding the vacant seat ID
&lt;/h3&gt;

&lt;p&gt;The second part of the task is finding the vacant seat that is missing from the list. There’s guaranteed to be only one. However, we remember that some of the seats at the very front and back of the plane don't exist on this aircraft, so they are missing as well. And so, we can’t simply iterate through the range from &lt;code&gt;1&lt;/code&gt; to &lt;code&gt;maxID&lt;/code&gt; and check for missing seats, as we would also “find” those at the very front and back.&lt;/p&gt;

&lt;p&gt;Note, however, that our required vacant seat is not on the edge. This means it’s the only missing seat whose neighbors are both present in the list. So, we can check for this condition: that the seat itself must be missing (in other words, not occupied), but both its neighbors must be occupied.&lt;/p&gt;

&lt;p&gt;First, to make our code more expressive, let’s add a function that checks whether a given seat is occupied. It checks that the given seat index belongs to the list of seat IDs provided as the input for our challenge. To make this check quickly, we convert the given list to a set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;seatIDs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;occupiedSeatsSet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seatIDs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toSet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seat&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;occupiedSeatsSet&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin allows us to create local functions, that is, functions inside other functions. That’s really convenient for the kind of short and simple function we need to write here: the &lt;code&gt;isOccupied()&lt;/code&gt; function will capture the outer variable, &lt;code&gt;occupiedSeatsSet&lt;/code&gt;, and we don’t need to pass it explicitly as a parameter.&lt;/p&gt;

&lt;p&gt;Now the only thing left to do is find the desired seat index, when the seat is not occupied but the neighboring seats (with indices &lt;code&gt;-1&lt;/code&gt; and &lt;code&gt;+1&lt;/code&gt;) are both occupied:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;mySeat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;maxID&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"My seat ID: $mySeat"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it! &lt;/p&gt;

&lt;p&gt;The whole main function that solves both parts of the task looks as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;seatIDs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"src/day05/input.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readLines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toSeatID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;maxID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seatIDs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;maxOrNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;
   &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Max seat ID: $maxID"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;occupiedSeatsSet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seatIDs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toSet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seat&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;occupiedSeatsSet&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;mySeat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;maxID&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
       &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"My seat ID: $mySeat"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that in order to use &lt;code&gt;maxID&lt;/code&gt; as the upper bound of the range, we call &lt;code&gt;!!&lt;/code&gt;, since the &lt;code&gt;maxOrNull()&lt;/code&gt; function returns a nullable value. Specifically, it returns &lt;code&gt;null&lt;/code&gt; if the list is empty. &lt;/p&gt;

&lt;p&gt;Following the Kotlin philosophy, you might expect to find the &lt;code&gt;max()&lt;/code&gt; function, throwing an exception if the list is empty. And you’d be right! However, in Kotlin 1.5 the &lt;code&gt;max()&lt;/code&gt; function is deprecated, and in future versions it will be totally removed and replaced with a function throwing an exception. The &lt;code&gt;max()&lt;/code&gt; function was present in the standard library starting with Kotlin 1.0 but returned a nullable value, and now the Kotlin team is slowly fixing this small discrepancy. Until the &lt;code&gt;max()&lt;/code&gt; function reappears in the standard library, it’s fine to write &lt;code&gt;maxOrNull()!!&lt;/code&gt; to explicitly highlight that you need the non-null value as a result, and you prefer an exception if the list is empty. Alternatively, to avoid using &lt;code&gt;!!&lt;/code&gt;, you can use &lt;code&gt;maxOf { it }&lt;/code&gt; for now.&lt;/p&gt;

&lt;p&gt;That’s it! We outlined the strategy for solving the puzzle, recognized the binary encoding for the numbers, discussed how it works, and presented the solution in Kotlin, which is quite simple thanks to the Kotlin standard library functions.&lt;/p&gt;




&lt;p&gt;*Used with the permission of &lt;a href="https://adventofcode.com/"&gt;Advent of Code&lt;/a&gt; (&lt;a href="https://twitter.com/ericwastl"&gt;Eric Wastl&lt;/a&gt;). &lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>adventofcode</category>
      <category>codenewbie</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Idiomatic Kotlin: Solving Advent of Code Puzzles, Passport Validation</title>
      <dc:creator>Sebastian Aigner</dc:creator>
      <pubDate>Wed, 01 Sep 2021 14:52:59 +0000</pubDate>
      <link>https://dev.to/kotlin/idiomatic-kotlin-solving-advent-of-code-puzzles-passport-validation-1425</link>
      <guid>https://dev.to/kotlin/idiomatic-kotlin-solving-advent-of-code-puzzles-passport-validation-1425</guid>
      <description>&lt;p&gt;Today in “Idiomatic Kotlin”, we’re looking at &lt;a href="https://adventofcode.com/2020/day/4"&gt;day 4 of the Advent of Code 2020 challenges&lt;/a&gt;, in which we tackle a problem that feels as old as programming itself: input sanitization and validation.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/-kltG4Ztv1s"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 4. Passport processing
&lt;/h2&gt;

&lt;p&gt;We need to build a passport scanner that, given a batch of input text, can count how many passports are &lt;em&gt;valid.&lt;/em&gt; You can find the complete task description at &lt;a href="https://adventofcode.com/2020/day/4*"&gt;https://adventofcode.com/2020/day/4&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Like many challenges, we first inspect our input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
byr:1937 iyr:2017 cid:147 hgt:183cm

iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884
hcl:#cfa07d byr:1929

hcl:#ae17e1 iyr:2013
eyr:2024
ecl:brn pid:760753108 byr:1931
hgt:179cm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The input is a batch of travel documents in a text file, separated by blank lines. Each &lt;em&gt;passport&lt;/em&gt; is represented as a sequence of key-colon-value pairs separated by spaces or newlines. &lt;em&gt;Our&lt;/em&gt; challenge is finding out how many passports are valid. For part one, “valid” means that they need to have all the required fields outlined by the security personnel: &lt;code&gt;byr&lt;/code&gt;, &lt;code&gt;iyr&lt;/code&gt;, &lt;code&gt;eyr&lt;/code&gt;, &lt;code&gt;hgt&lt;/code&gt;, &lt;code&gt;hcl&lt;/code&gt;, &lt;code&gt;ecl&lt;/code&gt; and &lt;code&gt;pid&lt;/code&gt; (we conveniently ignore their request to validate the &lt;code&gt;cid&lt;/code&gt; field).&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving Day 4, Part 1
&lt;/h2&gt;

&lt;p&gt;Like many challenges, we start by reading our puzzle input as text and trim off any extraneous whitespace at the beginning and the end of the file. As per the description, passports are always separated by blank lines. A blank line is just two “returns”, or newlines, in a row, so we’ll use this to split our input string into the individual passports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;passports&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"src/day04/input.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\n\n"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"\r\n\r\n"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note that depending on your operating system, the line separator in text files is different: On Windows, it is &lt;code&gt;\r\n&lt;/code&gt;, on Linux and macOS, it’s &lt;code&gt;\n&lt;/code&gt;. Kotlin’s &lt;code&gt;split&lt;/code&gt; method takes an arbitrary number of delimiters, allowing us to cover both cases directly.)&lt;/p&gt;

&lt;p&gt;We now have a list of passport strings. However, working with lists of raw strings can quickly get confusing. Let’s use Kotlin’s expressive type system to improve the situation and encapsulate the string in a very basic &lt;code&gt;Passport&lt;/code&gt; class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Passport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then just map the results of our split-up input to &lt;code&gt;Passport&lt;/code&gt; objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// . . .&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;Passport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the problem description, we remember that key-value pairs are either separated by spaces or newlines within a single passport. Therefore, to get the individual pairs, we once again split our input. The delimiters, in this case, are either a space or one of the newline sequences.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;hasAllRequiredFields&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fieldsWithValues&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"\n"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"\r\n"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then extract the key from each passport entry. We can do so by mapping our combined &lt;code&gt;fieldsWithValues&lt;/code&gt; to &lt;em&gt;only&lt;/em&gt; the substring that comes before the colon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;hasAllRequiredFields&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fieldsWithValues&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"\n"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"\r\n"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fieldNames&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fieldsWithValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substringBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fieldNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;containsAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requiredFields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result of our function will be whether the &lt;code&gt;fieldNames&lt;/code&gt; we extracted contain all required fields. The &lt;code&gt;requiredFields&lt;/code&gt; collection can be taken directly from the problem statement and translated into a list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;requiredFields&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"byr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"iyr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"eyr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hgt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hcl"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"ecl"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"pid"&lt;/span&gt; &lt;span class="cm"&gt;/*"cid"*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To calculate our final number, and get our first gold star for the challenge, we need to count the passports for which our function &lt;code&gt;hasAllRequiredFields&lt;/code&gt; returns true:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Passport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;hasAllRequiredFields&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that, we have successfully solved the first part of the challenge and can set our sights on the next star in our journey.&lt;/p&gt;

&lt;p&gt;Find the full code for the first part of the challenge on &lt;a href="https://github.com/kotlin-hands-on/advent-of-code-2020/blob/master/src/day04/day4_1.kt"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving Day 4, Part 2
&lt;/h2&gt;

&lt;p&gt;In part two of the challenge, we also need to ensure that each field on the passport contains a valid value. We are given an additional list of rules to accomplish this task, which you can again find in the &lt;a href="https://adventofcode.com/2020/day/4"&gt;problem description&lt;/a&gt;. Years need to fall into specific ranges, as does a person's height depending on the unit of measurement. Colors need to come from a prespecified list or follow certain patterns, and numbers must be correctly formatted.&lt;/p&gt;

&lt;h3&gt;
  
  
  A refactoring excursion
&lt;/h3&gt;

&lt;p&gt;Before we start building the solution for part 2, let’s briefly reflect on our code and find possible changes that will make adding this functionality easier for us. At this point in the challenge, we &lt;em&gt;know&lt;/em&gt; that our &lt;code&gt;Passport&lt;/code&gt; class will need access to the different field names and their associated values. The classical data structure to store such kind of associative-dictionary information is a map. Let’s refactor our code to store passport information in a map instead of a string.&lt;/p&gt;

&lt;p&gt;Because turning an input string into a map is still a process that’s associated with the &lt;code&gt;Passport&lt;/code&gt;, I like encapsulating such logic in a companion object “factory” function. In this case, we can aptly call it &lt;code&gt;fromString&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;companion&lt;/span&gt; &lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;fromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Passport&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation for &lt;code&gt;fromString&lt;/code&gt; partially reuses the normalization logic we had previously used in the first part of this challenge and expands it to create a map directly via Kotlin’s &lt;code&gt;&lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/associate.html"&gt;associate&lt;/a&gt;&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;fromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Passport&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fieldsAndValues&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"\n"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"\r\n"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;map&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fieldsAndValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;associate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="py"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Passport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;Passport&lt;/code&gt; object now encapsulates a map of string keys and string values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Passport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;map&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interestingly enough, this change makes the implementation of the first part of our challenge trivial. We can simply check that the key set of our map contains all required fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;hasAllRequiredFields&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;containsAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requiredFields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Returning to solving part 2
&lt;/h3&gt;

&lt;p&gt;For the second part of the challenge, we consider a passport valid if it contains all the required fields and has values that correspond to the official rules.&lt;/p&gt;

&lt;p&gt;To ensure that all fields have valid values, we can use the &lt;code&gt;all&lt;/code&gt; function to assert that a predicate holds true for every single key-value pair in our map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;hasValidValues&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can distinguish the different types of fields using a &lt;code&gt;when&lt;/code&gt; expression. In this first step, we distinguish the different cases based on the keys in our map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each key we know gets a branch in this when statement. They all need to return a boolean value – &lt;code&gt;true&lt;/code&gt; if the field is okay, &lt;code&gt;false&lt;/code&gt; if the field violates the rules. The surrounding &lt;code&gt;all&lt;/code&gt; predicate will then use those results to determine whether the passport as a whole is valid.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;byr&lt;/code&gt; (Birth Year), &lt;code&gt;iyr&lt;/code&gt; (Issue Year), and &lt;code&gt;eyr&lt;/code&gt; (Expiration Year) fields all require their value to be a 4-digit number falling into a particular range:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"byr"&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toIntOrNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;1920&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;2002&lt;/span&gt;
&lt;span class="s"&gt;"iyr"&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toIntOrNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;
&lt;span class="s"&gt;"eyr"&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toIntOrNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;2030&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that our combined use of &lt;code&gt;toIntOrNull&lt;/code&gt; together with the infix function &lt;code&gt;in&lt;/code&gt; allows us to discard any non-numeric values, and ensure that they fall in the correct range.&lt;/p&gt;

&lt;p&gt;We can apply a very similar rule to the &lt;code&gt;pid&lt;/code&gt; (Passport ID) field. We ensure that the length of the value is correct and ensure that all characters belong to the set of digits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"pid"&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Char&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;isDigit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validating &lt;code&gt;ecl&lt;/code&gt; (eye color) just requires us to check whether the input is in a certain set of values, similar to the first part of our challenge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"ecl"&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;setOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"amb"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"blu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"brn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"gry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"grn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hzl"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"oth"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, we have two more fields to validate: &lt;code&gt;hgt&lt;/code&gt; (Height) and &lt;code&gt;hcl&lt;/code&gt; (Hair Color). Both of them are a bit more tricky. Let’s look at the &lt;code&gt;hgt&lt;/code&gt; field first.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;hgt&lt;/code&gt; (Height) field can contain a measurement either in centimeters or inches. Depending on the unit used, different values are allowed. Thankfully, both “cm” and “in” are two-character suffixes. This means we can again use Kotlin’s &lt;code&gt;when&lt;/code&gt; function, grab the last two characters in the field value and differentiate the validation logic for centimeters and inches. Like our other number-validation logic, we parse the integer and check whether it belongs to a specific range. To do so, we also remove the unit suffix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"hgt"&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;takeLast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"cm"&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeSuffix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cm"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toIntOrNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;193&lt;/span&gt;
    &lt;span class="s"&gt;"in"&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeSuffix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"in"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toIntOrNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;59&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;76&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last field to validate is &lt;code&gt;hcl&lt;/code&gt; (Hair Color), which expects a &lt;code&gt;#&lt;/code&gt; followed by exactly six hexadecimal digits – digits from &lt;code&gt;0&lt;/code&gt; through &lt;code&gt;9&lt;/code&gt;, and &lt;code&gt;a&lt;/code&gt; through &lt;code&gt;f&lt;/code&gt;. While Kotlin can parse base-16 numbers, we can use this case to show off the sledgehammer method for validating patterns – regular expressions. Those can be defined as Kotlin strings and converted using the &lt;code&gt;toRegex&lt;/code&gt; function. Triple-quoted strings can help with escape characters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"hcl"&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="s"&gt;"""#[0-9a-f]{6}"""&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toRegex&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our hand-crafted pattern matches exactly one hashtag, then six characters from the group of &lt;code&gt;0&lt;/code&gt; through &lt;code&gt;9&lt;/code&gt;, &lt;code&gt;a&lt;/code&gt; through &lt;code&gt;f&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As a short aside for performance enthusiasts: &lt;code&gt;toRegex&lt;/code&gt; is a relatively expensive function, so it may be worth moving this function call into a constant. The same also applies to the set used in the validation for &lt;code&gt;ecl&lt;/code&gt; – currently, it is initialized on each test.&lt;/p&gt;

&lt;p&gt;Because the whole &lt;code&gt;when&lt;/code&gt;-block is used as an expression, we need to ensure that all possible branches are covered. In our case, that just means adding an &lt;code&gt;else&lt;/code&gt; branch, which simply returns &lt;code&gt;true&lt;/code&gt; – just because a passport has a field we don’t know about doesn’t mean it can’t still be valid.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that, we have covered every rule outlined to us by the problem statement. To get our reward, we can now just count the passports that contain all required fields and have valid values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;partTwo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasAllRequiredFields&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasValidValues&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We end up with a resulting number, which we can exchange for the second star. We’re clear for boarding our virtual flight. Though this was probably not the last challenge that awaits us…&lt;/p&gt;

&lt;p&gt;Find the complete solution for the second part of the challenge on &lt;a href="https://github.com/kotlin-hands-on/advent-of-code-2020/blob/master/src/day04/day4.kt"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;For today’s challenge, we came up with an elegant solution to validate specific string information, which we extracted using utility functions offered by the Kotlin standard library. As the challenge continued, we reflected on our code, identified more fitting data structures, and changed our logic to accommodate it. Using Kotlin’s &lt;code&gt;when&lt;/code&gt; statement, we were able to keep the validation logic concise and all in one place. We saw multiple different ways of how to validate input – working with ranges, checking set membership, or matching a particular regular expression, for example.&lt;/p&gt;

&lt;p&gt;Many real-world applications have similar requirements for input validation. Hopefully, some of the tips and tricks you’ve seen in the context of this little challenge will also be helpful when you need to write some validation logic on your own.&lt;/p&gt;

&lt;p&gt;To continue puzzling yourself, check out &lt;a href="https://adventofcode.com/"&gt;adventofcode.com&lt;/a&gt;, whose organizers kindly permitted us to use their problem statements for this series.&lt;/p&gt;

&lt;p&gt;If you want to see more solutions for Advent of Code challenges in the form of videos, subscribe to our &lt;a href="https://www.youtube.com/kotlin"&gt;YouTube channel&lt;/a&gt; and hit the bell to get notified when we continue our idiomatic journey. More puzzle solutions are coming your way!&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>adventofcode</category>
      <category>codenewbie</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Idiomatic Kotlin: Solving Advent of Code Puzzles, Day 2</title>
      <dc:creator>Svetlana Isakova</dc:creator>
      <pubDate>Wed, 21 Jul 2021 16:25:30 +0000</pubDate>
      <link>https://dev.to/kotlin/idiomatic-kotlin-solving-advent-of-code-puzzles-day-2-pe2</link>
      <guid>https://dev.to/kotlin/idiomatic-kotlin-solving-advent-of-code-puzzles-day-2-pe2</guid>
      <description>&lt;h2&gt;
  
  
  Idiomatic Kotlin: Solving Advent of Code Puzzles, Day 2
&lt;/h2&gt;

&lt;p&gt;Let’s &lt;a href="https://dev.to/kotlin/solving-advent-of-code-puzzles-in-idiomatic-kotlin-1m62"&gt;continue&lt;/a&gt; learning how to write idiomatic Kotlin code by solving the &lt;a href="https://adventofcode.com/"&gt;AdventOfCode&lt;/a&gt; tasks! Today, we’re discussing the solution for the day 2 task.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/MyvJ7G6aErQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 2. Password philosophy
&lt;/h2&gt;

&lt;p&gt;We need to confirm that passwords meet the corporate policy. Find the full task description at &lt;a href="https://adventofcode.com/2020/day/2"&gt;https://adventofcode.com/2020/day/2&lt;/a&gt;*.&lt;/p&gt;

&lt;p&gt;First, we need to read the input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1-3 a: abcde
1-3 b: cdefg
2-9 c: ccccccccc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each line contains the password policy and the password. Our task is to check that the password is valid and conforms to the given policy. The policies are different in the first and the second parts of the task.&lt;/p&gt;

&lt;p&gt;In the first part, the password policy indicates the lowest and highest number of times a given letter must appear for the password to be valid. For example, &lt;code&gt;1-3 a&lt;/code&gt; means that the password must contain &lt;code&gt;a&lt;/code&gt; at least once and at most 3 times. In the example, two passwords, the first and the third ones, are valid. The first contains one &lt;code&gt;a&lt;/code&gt;, and the third contains nine &lt;code&gt;c&lt;/code&gt;s, both within the limits of their respective policies. The second password, &lt;code&gt;cdefg&lt;/code&gt;, is invalid, as it contains no instances of &lt;code&gt;b&lt;/code&gt; but needs at least 1.&lt;/p&gt;

&lt;p&gt;In the second part, the policy describes two positions in the password, where 1 means the first character, 2 means the second character, and so on (indexing starts at 1, not 0). Exactly one of these positions must contain the given letter. Other occurrences of the letter are irrelevant. Given the same example list from above:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;1-3 a: abcde&lt;/code&gt; is valid: position 1 contains &lt;code&gt;a&lt;/code&gt; and position 3 does not.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1-3 b: cdefg&lt;/code&gt; is invalid: neither position 1 nor position 3 contains &lt;code&gt;b&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2-9 c: ccccccccc&lt;/code&gt; is invalid: both positions 2 and position 9 contain &lt;code&gt;c&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We should count the number of passwords from the given input that are valid according to the interpretations of the policies.&lt;/p&gt;

&lt;p&gt;As usual, if you haven’t done it, please solve the task yourself first. Here’s how you can &lt;a href="https://blog.jetbrains.com/kotlin/2021/07/advent-of-code-in-idiomatic-kotlin/#how-to-solve"&gt;set up Kotlin&lt;/a&gt; for this purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;First, we should read and parse the input. Let’s create a &lt;code&gt;data&lt;/code&gt; class for storing a given password together with its policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;IntRange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Char&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each policy specifies an integer range and a letter that we store in the &lt;code&gt;IntRange&lt;/code&gt; and &lt;code&gt;Char&lt;/code&gt; types, accordingly. The modifier &lt;code&gt;data&lt;/code&gt; instructs the compiler to generate some useful methods for this class, including the constructor, &lt;code&gt;equals&lt;/code&gt;, &lt;code&gt;hashCode&lt;/code&gt;, and &lt;code&gt;toString&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parsing input
&lt;/h3&gt;

&lt;p&gt;Let’s write a function that parses one input line into this class. Since it’s a function that creates an instance, let’s put it into a companion object in our data class. Then we can call it by the class name: &lt;code&gt;PasswordWithPolicy.parse()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;companion&lt;/span&gt; &lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
           &lt;span class="nc"&gt;TODO&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While developing, you can put the &lt;code&gt;TODO()&lt;/code&gt; call that throws the &lt;code&gt;NotImplementedError&lt;/code&gt;exception. Because it returns the &lt;code&gt;Nothing&lt;/code&gt; type, which is a subtype of any other type, the compiler won’t complain. The function is supposed to return &lt;code&gt;PasswordWithPolicy&lt;/code&gt;, but throwing an exception inside is totally valid from the compiler’s point of view.&lt;/p&gt;

&lt;p&gt;There are two ways to parse the input: by using utility functions on Strings or by using regular expressions. Let’s discuss both of these ways.&lt;/p&gt;

&lt;p&gt;The Kotlin standard library contains many useful functions on &lt;code&gt;String&lt;/code&gt;s, including &lt;code&gt;substringAfter()&lt;/code&gt; and &lt;code&gt;substringBefore()&lt;/code&gt; which perfectly solve the task in our case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1-3 a: abcde&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substringAfter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;": "&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substringAfter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;substringBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;single&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
   &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substringBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="py"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We provide the parameter names explicitly while calling the &lt;code&gt;PasswordWithPolicy&lt;/code&gt; constructor. The input format convention requires that: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;password&lt;/code&gt; be the string that goes right after the colon&lt;/li&gt;
&lt;li&gt;the letter go between the whitespace and the colon, and&lt;/li&gt;
&lt;li&gt;the range go before the whitespace and consist of two numbers split by “-”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To build a range, we first take the substring before the whitespace and split it with the “-” delimiter. We then use only the first two parts (&lt;code&gt;start&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt;), and build a range using the “..” operator converting both lines to &lt;code&gt;Int&lt;/code&gt;s. We use &lt;code&gt;let&lt;/code&gt; to convert the result of &lt;code&gt;substringBefore()&lt;/code&gt; to the desired range.&lt;/p&gt;

&lt;p&gt;In this code, we assume that all the input lines follow the rules. In a real-world scenario, we should check that the input is correct. &lt;code&gt;substringAfter()&lt;/code&gt; and similar functions take a second argument default to the string itself that should be returned in the event the given delimiter is not found. &lt;code&gt;toInt()&lt;/code&gt; and &lt;code&gt;single()&lt;/code&gt; have &lt;code&gt;toIntOrNull()&lt;/code&gt; and &lt;code&gt;singleOrNull()&lt;/code&gt; counterparts returning &lt;code&gt;null&lt;/code&gt; if the string can’t be converted to an integer number or consists of more than one character.&lt;/p&gt;

&lt;p&gt;Let’s now implement the same logic using regular expressions. Here is a regular expression describing the input format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(\d+)-(\d+) ([a-z]): ([a-z]+)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First are two numbers split by -, then a letter and a password.&lt;/p&gt;

&lt;p&gt;Our new &lt;code&gt;parse&lt;/code&gt; function matches the line against a regular expression and then builds &lt;code&gt;PasswordWithPolicy&lt;/code&gt; on the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;regex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"""(\d+)-(\d+) ([a-z]): ([a-z]+)"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;parseUsingRegex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
   &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchEntire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;destructured&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
           &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;single&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Kotlin, you use the &lt;code&gt;Regex&lt;/code&gt; class to define a regular expression. Note how we put it inside a triple-quoted string, so you don’t need to escape “&lt;code&gt;\&lt;/code&gt;”. For regular strings, escaping is done in the conventional way, with a backslash, so if you need a backslash character in the string, you repeat it: &lt;code&gt;"(\\d+)-(\\d+)".&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We assume that our input is correct, which is why we use “&lt;code&gt;!!&lt;/code&gt;” to throw an NPE if the input doesn’t correspond to the regular expression. An alternative is to use the safe access “&lt;code&gt;?.&lt;/code&gt;” here and return &lt;code&gt;null&lt;/code&gt; as the result.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;destructured&lt;/code&gt; property provides components for a destructuring assignment for groups defined in the regular expression. We use its result together with &lt;code&gt;let&lt;/code&gt; and destruct it inside the lambda expression, defining &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt;, &lt;code&gt;letter&lt;/code&gt;, and &lt;code&gt;password&lt;/code&gt; as parameters. As before, we need to convert strings to &lt;code&gt;Int&lt;/code&gt;s and &lt;code&gt;Char&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Password validation
&lt;/h3&gt;

&lt;p&gt;After we read the input, we need to validate whether the passwords comply with the given policy.&lt;/p&gt;

&lt;p&gt;In the first part, we need to ensure that the number of occurrences of a given letter is in a range. It’s one line in Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;IntRange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Char&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;validatePartOne&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
       &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt;
       &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We count the occurrences of &lt;code&gt;letter&lt;/code&gt; in the &lt;code&gt;password&lt;/code&gt; string, and check that the result is in &lt;code&gt;range&lt;/code&gt;. &lt;code&gt;in&lt;/code&gt; checks that the given element belongs to a range. For numbers and other comparable elements, &lt;code&gt;x in range&lt;/code&gt; is the same as writing explicitly &lt;code&gt;range.first &amp;amp;lt;= x &amp;amp;&amp;amp; x &amp;amp;lt;= range.last&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The second part isn’t difficult. We need to check that exactly one of the positions (stored in the range) contains the given letter. We use the boolean &lt;code&gt;xor&lt;/code&gt; operator for that, which returns &lt;code&gt;true&lt;/code&gt; if the operands are different. That’s exactly what we need here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;validatePartTwo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;xor&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to subtract 1 from &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;last&lt;/code&gt; because they imply indexing from one, but string indexation starts from zero.&lt;/p&gt;

&lt;p&gt;Added all together, this gives us our &lt;code&gt;main&lt;/code&gt; function that finds the result for both parts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;passwords&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"src/day2/input.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readLines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passwords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validatePartOne&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
   &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passwords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validatePartTwo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note how we pass a member reference &lt;code&gt;PasswordWithPolicy::parse&lt;/code&gt; to the &lt;code&gt;map&lt;/code&gt; function to convert the strings to passwords.&lt;/p&gt;

&lt;p&gt;That’s it! We discussed how to solve this problem, and along the way, looked at string utility functions, regular expressions, operations on collections, and how &lt;code&gt;let&lt;/code&gt; helps transform the expression nicely to the form you need.&lt;/p&gt;

&lt;p&gt;Please let us know if you find this format useful and would like us to provide solutions for more difficult tasks!&lt;/p&gt;




&lt;p&gt;*Used with the permission of &lt;a href="https://adventofcode.com/"&gt;Advent of Code&lt;/a&gt; (&lt;a href="https://twitter.com/ericwastl"&gt;Eric Wastl&lt;/a&gt;). &lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>adventofcode</category>
      <category>codenewbie</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Solving Advent of Code Puzzles in Idiomatic Kotlin</title>
      <dc:creator>Svetlana Isakova</dc:creator>
      <pubDate>Thu, 15 Jul 2021 12:41:37 +0000</pubDate>
      <link>https://dev.to/kotlin/solving-advent-of-code-puzzles-in-idiomatic-kotlin-1m62</link>
      <guid>https://dev.to/kotlin/solving-advent-of-code-puzzles-in-idiomatic-kotlin-1m62</guid>
      <description>&lt;p&gt;What’s the best way to learn a language other than writing some code with it? Solving fun and short tasks like the ones from &lt;a href="https://adventofcode.com/"&gt;Advent of Code&lt;/a&gt; might be a great opportunity to practice your language skills, and you can learn a lot if you compare your solutions with how others have solved the same problem.&lt;/p&gt;

&lt;p&gt;Lots of developers from around the world, including some from the Kotlin team, take part in the Advent of Code challenges created by &lt;a href="https://twitter.com/ericwastl"&gt;Eric Wastl&lt;/a&gt;. Advent of Code is a series of tasks published every December, which you solve and compete with others. Many would agree that it’s the best advent calendar to celebrate Christmas and New Year!&lt;/p&gt;

&lt;p&gt;To help the community learn idiomatic Kotlin, and motivate more developers to solve Advent of Code tasks in Kotlin in the future, we decided to prepare solutions for the tasks from Advent of Code 2020. It doesn’t matter if you solved it back in December, you’re ready to solve it now, or you just want to check the solutions – we hope you’ll find something useful in these materials. Of course, it works best if you try to solve the same task first yourself!&lt;/p&gt;

&lt;p&gt;Below is the solution and video for the first task. If you find this format useful and want us to cover more tasks in a similar fashion, please share in the comments!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/o4emra1xm88"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 1. Report Repair
&lt;/h2&gt;

&lt;p&gt;We’re fixing an expense report! Find the full task description at &lt;a href="https://adventofcode.com/2020/day/1"&gt;https://adventofcode.com/2020/day/1&lt;/a&gt;*.&lt;/p&gt;

&lt;p&gt;You need to find the two (and in the second part, three) entries from the list of numbers that sum to 2020 and then multiply those two (or three) numbers together.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to solve the task
&lt;/h3&gt;

&lt;p&gt;Register at &lt;a href="https://adventofcode.com/"&gt;https://adventofcode.com/&lt;/a&gt;, open the task at &lt;a href="https://adventofcode.com/2020/day/1"&gt;https://adventofcode.com/2020/day/1&lt;/a&gt;, write your solution in Kotlin, and check the result on the site. You can either write Kotlin code &lt;a href="https://play.kotlinlang.org/"&gt;online&lt;/a&gt; or using an IDE:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;download the  free Community Edition of &lt;a href="https://www.jetbrains.com/idea/download/"&gt;IntelliJ IDEA&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;create &lt;a href="https://kotlinlang.org/docs/jvm-get-started.html"&gt;a Kotlin project&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;write your solution there&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, compare your solution with the solution below.&lt;/p&gt;

&lt;p&gt;We &lt;a href="https://github.com/svtk/advent-of-code-2020/blob/master/build.gradle.kts"&gt;marked&lt;/a&gt; the &lt;code&gt;src&lt;/code&gt; folder as a source set to put the code directly there. We copied input files, like &lt;code&gt;src/day1/input.txt&lt;/code&gt;,  to the source folder for convenience. You can find the solutions in &lt;a href="https://github.com/Kotlin-hands-on/advent-of-code-2020"&gt;this project&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Here’s the sample input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1721
979
366
299
675
1456
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we need to read and parse the input. We can use the Kotlin &lt;code&gt;readLines()&lt;/code&gt; function for reading a list of lines from a given file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"src/day1/input.txt"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;readLines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;readLines()&lt;/code&gt; returns a list of Strings, and we convert it to a list of numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.File&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;numbers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"src/day1/input.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readLines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You put this code inside the &lt;code&gt;main&lt;/code&gt; function, the entry point for your program. When you start typing, IntelliJ IDEA imports the &lt;code&gt;java.io.File&lt;/code&gt; automatically.&lt;/p&gt;

&lt;p&gt;Now we can simply iterate through the list, and then for each number repeat the iteration and check the sum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="k"&gt;return&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You put this code inside &lt;code&gt;main&lt;/code&gt;, so &lt;code&gt;return&lt;/code&gt; returns from &lt;code&gt;main&lt;/code&gt; when the required numbers are found.&lt;/p&gt;

&lt;p&gt;In a similar way, you check the sum of three numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;third&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;third&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;third&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="k"&gt;return&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can run it and get the result for a given input. That’s it! The first task is really a simple one.&lt;/p&gt;

&lt;p&gt;However, we iterate over the same list again and again for each of the elements. Having two nested loops for finding two numbers makes it N&lt;sup&gt;2&lt;/sup&gt; operations, where N is the number of elements. When we need to find three numbers, that’s three nested loops, and N&lt;sup&gt;3&lt;/sup&gt; operations. If the list of numbers is large, that’s not the most efficient way to solve this type of problem. Surely there is a better way, right?&lt;/p&gt;

&lt;p&gt;There definitely is and the Kotlin standard library can help us express that concisely. As often happens, we can replace the long calculation with some kind of smart storage used to find the result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solving the task for two numbers
&lt;/h3&gt;

&lt;p&gt;First, let’s build a map for number “complements” – numbers that together with the given number sum up to 2020:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;complements&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;associateBy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use the Kotlin &lt;code&gt;associateBy&lt;/code&gt; function to build the map. Its lambda argument returns a key in this map, by which the list element is getting stored. For the sample input it’ll be the following map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1721&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;979&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;299&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;675&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1456&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;complements&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;299&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1721&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1041&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;979&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1654&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1721&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;299&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1345&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;675&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;564&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1456&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this procedure, you can clearly see the answer! The very first number &lt;code&gt;1721&lt;/code&gt; from the list is present in the &lt;code&gt;complements&lt;/code&gt; map as a key: &lt;code&gt;1721=299&lt;/code&gt;, which means it’s the complement for the number &lt;code&gt;299&lt;/code&gt;, and they sum to &lt;code&gt;2020&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Having stored this information in a map, we can check if any number from the list has a complement in this map. The following code finds the first number with an existing complement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;pair&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mapNotNull&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;complement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;complements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;complement&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;complement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;firstOrNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We transform each number into a pair consisting of the number and its complement (if the complement exists) and then find the first non-null result.&lt;/p&gt;

&lt;p&gt;We use &lt;code&gt;mapNotNull&lt;/code&gt;, which transforms each element in a list and filters out all the resulting &lt;code&gt;null&lt;/code&gt;s. It’s shorthand for calling first &lt;code&gt;map&lt;/code&gt;, and then &lt;code&gt;filterNotNull&lt;/code&gt; on the result.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;firstOrNull&lt;/code&gt; returns the first element in the list or &lt;code&gt;null&lt;/code&gt; if the list is empty. Kotlin standard library often uses the &lt;code&gt;OrNull&lt;/code&gt; suffix to mark functions returning &lt;code&gt;null&lt;/code&gt; on failure rather than throwing an exception (like &lt;code&gt;elementAtOrNull&lt;/code&gt;, &lt;code&gt;singleOrNull&lt;/code&gt;, or &lt;code&gt;maxOrNull&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Starting with Kotlin 1.5.0, you can also replace the two consequent operations &lt;code&gt;mapNotNull&lt;/code&gt; and &lt;code&gt;first(OrNull)&lt;/code&gt; with one function call: &lt;code&gt;firstNotNullOf(OrNull)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After building the auxiliary structure, we managed to find the resulting two numbers in N operations, not in N&lt;sup&gt;2&lt;/sup&gt; as before!&lt;/p&gt;

&lt;p&gt;We need a multiplication of these numbers, so here’s the last step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;pair&lt;/code&gt; variable contains a nullable &lt;code&gt;Pair&lt;/code&gt; of two numbers and is &lt;code&gt;null&lt;/code&gt; if the initial list contains no numbers that sum up to 2020. We use safe access &lt;code&gt;?.&lt;/code&gt; together with the &lt;code&gt;let&lt;/code&gt; function and destructuring in a lambda syntax to display the result in case &lt;code&gt;pair&lt;/code&gt; is not &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solving the task for three numbers
&lt;/h3&gt;

&lt;p&gt;The next step is solving this problem for three numbers. Let’s reuse what we’ve done so far and extract the logic of finding a pair of numbers summing up to a given number into a separate function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="nf"&gt;findPairOfSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// Map: sum - x -&amp;gt; x&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;complements&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;associateBy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;firstNotNullOfOrNull&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
       &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;complement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;complements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;complement&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;complement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also used the &lt;code&gt;firstNotNullOfOrNull&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Now, we use &lt;code&gt;findPairOfSum&lt;/code&gt; to build a helper map that stores the complement &lt;em&gt;pair of values&lt;/em&gt; for each number which together with this number sums up to 2020:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Map: x -&amp;gt; (y, z) where y + z = 2020 - x&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;complementPairs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
   &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;associateWith&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findPairOfSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the same initial input, here’s the complement pairs map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1721&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;979&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;299&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;675&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1456&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;complement&lt;/span&gt; &lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1721&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;979&lt;/span&gt;&lt;span class="p"&gt;=(&lt;/span&gt;&lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;675&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;=(&lt;/span&gt;&lt;span class="mi"&gt;979&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;675&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;299&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;675&lt;/span&gt;&lt;span class="p"&gt;=(&lt;/span&gt;&lt;span class="mi"&gt;979&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1456&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As before, you already can see the answer! It’s the number that corresponds to a non-null pair in a map.&lt;/p&gt;

&lt;p&gt;However, we don’t really need to build the whole map — we only need to find the first number that corresponds to a non-null pair! Let’s find it using the already familiar &lt;code&gt;firstNotNullOfOrNull&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="nf"&gt;findTripleOfSum&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Triple&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
   &lt;span class="nf"&gt;firstNotNullOfOrNull&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
       &lt;span class="nf"&gt;findPairOfSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
           &lt;span class="nc"&gt;Triple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note Kotlin’s concise syntax – the function can return an expression directly.&lt;/p&gt;

&lt;p&gt;The final step is to find the multiplication if the resulting triple is non-null, similar to how we did it before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;triple&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s all!&lt;/p&gt;

&lt;p&gt;In the next part, we’ll discuss how to solve the second task. Please let us know if you find this content useful and would like us to provide solutions for more tasks!&lt;/p&gt;




&lt;p&gt;*Used with the permission of &lt;a href="https://adventofcode.com/"&gt;Advent of Code&lt;/a&gt; (&lt;a href="https://twitter.com/ericwastl"&gt;Eric Wastl&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>adventofcode</category>
      <category>codenewbie</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Exploring Kotlin Lists in 2021</title>
      <dc:creator>Sebastian Aigner</dc:creator>
      <pubDate>Thu, 08 Jul 2021 14:46:58 +0000</pubDate>
      <link>https://dev.to/kotlin/exploring-kotlin-lists-in-2021-2gi</link>
      <guid>https://dev.to/kotlin/exploring-kotlin-lists-in-2021-2gi</guid>
      <description>&lt;p&gt;This blog post accompanies a video from our &lt;strong&gt;YouTube series&lt;/strong&gt; which you can find on our &lt;a href="https://kotl.in/video" rel="noopener noreferrer"&gt;Kotlin YouTube channel&lt;/a&gt;, or &lt;strong&gt;watch here&lt;/strong&gt; directly!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/CDWy16UDeLQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Today, we're talking all about lists!&lt;/strong&gt; Lists are the most popular collection type in Kotlin for a good reason, and we’ll find out why together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lists
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What’s a list?
&lt;/h3&gt;

&lt;p&gt;If you've written Kotlin code before, you've definitely seen a list – they're collections of ordered elements, where each element is accessible via an index. As such, they're one of the basic building blocks for a lot of Kotlin code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating lists
&lt;/h3&gt;

&lt;p&gt;If you’re creating lists on your own, you’re most likely using the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/list-of.html" rel="noopener noreferrer"&gt;&lt;code&gt;listOf&lt;/code&gt;&lt;/a&gt; function, which takes a variable number of arguments, and those become the elements of your list. Even in this blog post series, we've created a list like that about a hundred times:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 2, 3, 4, 5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A little lesser known is the ability to create lists via the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list.html" rel="noopener noreferrer"&gt;&lt;code&gt;List&lt;/code&gt;&lt;/a&gt; constructor function. Here, we pass two parameters – the &lt;code&gt;size&lt;/code&gt; of the list, and an &lt;code&gt;init&lt;/code&gt; function that creates each of the elements in our list. That function we pass gets the element index as its parameter, which we can use to adjust the item content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"No. $idx"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// [No. 0, No. 1, No. 2, No. 3, No. 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, lists can come from other places as well: types like collections, iterables, and others often feature a &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/to-list.html" rel="noopener noreferrer"&gt;&lt;code&gt;toList&lt;/code&gt;&lt;/a&gt; method.&lt;/p&gt;

&lt;p&gt;For example, in the case of a string, we get a list of its characters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"word-salad"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// [w, o, r, d, -, s, a, l, a, d]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Given a map of placements and the associated medals, we can call &lt;code&gt;toList&lt;/code&gt; on that to get a list of key-value pairs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;mapOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"Gold"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"Silver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"Bronze"&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// [(1, Gold), (2, Silver), (3, Bronze)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sequences, ranges, and progressions behave similarly. They materialize their values, and put them in a list when calling &lt;code&gt;toList&lt;/code&gt;. As an example, we can consider a random sequence of numbers, or the inclusive integer range from zero to ten:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nextInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;takeIf&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// [73, 77, 69, 79, 71, 64]&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An extra case worth mentioning is calling &lt;code&gt;toList&lt;/code&gt; on something that already is a list. This creates brand-new copy of the original list. We can see this in the following example, where we create a mutable list with a few numbers. By calling &lt;code&gt;toList&lt;/code&gt;, we obtain a new working copy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;otherList&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [5, 2, 3]&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;otherList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, when the original list is changed, the working copy we just created does not contain any of the changes applied to the original collection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessing list items
&lt;/h3&gt;

&lt;p&gt;To get items out of our lists, we have multiple options. The most basic way of doing so is using the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/get.html" rel="noopener noreferrer"&gt;&lt;code&gt;get&lt;/code&gt;&lt;/a&gt; function, together with an index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;myList&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🍔"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🌭"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🍕"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;myList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 🌭&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But if you ever type out &lt;code&gt;.get&lt;/code&gt; manually, you’ll see that IntelliJ IDEA already gives you the helpful hint to use some much more popular syntactic sugar for it – the indexed access operator, denoted by the brackets with an index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;myList&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// 🌭&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are also some additional flavors of the &lt;code&gt;get&lt;/code&gt; function which we can explore. Two of those that come to mind are &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/get-or-else.html" rel="noopener noreferrer"&gt;&lt;code&gt;getOrElse&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/get-or-null.html" rel="noopener noreferrer"&gt;&lt;code&gt;getOrNull&lt;/code&gt;&lt;/a&gt;. They help us handle cases where we might be accessing an index that falls out of bounds (which can either be a negative index, or an index that’s larger than the last index in our collection.)&lt;/p&gt;

&lt;p&gt;Using the default indexed access causes an &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-index-out-of-bounds-exception/" rel="noopener noreferrer"&gt;exception&lt;/a&gt; when provided a parameter that's out of bounds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;myList&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// Index 3 out of bounds for length 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/get-or-null.html" rel="noopener noreferrer"&gt;&lt;code&gt;getOrNull&lt;/code&gt;&lt;/a&gt; to short-circuit our return value to &lt;code&gt;null&lt;/code&gt;. Alternatively, we can use &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/get-or-else.html" rel="noopener noreferrer"&gt;&lt;code&gt;getOrElse&lt;/code&gt;&lt;/a&gt; to compute a default value to be used instead. The default value is computed based on a passed lambda, which also receives the index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;myList&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🍔"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🌭"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🍕"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;myList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getOrNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// null&lt;/span&gt;

&lt;span class="n"&gt;myList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getOrElse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"There's no index $it!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="s"&gt;"😔"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// There's no index 3!&lt;/span&gt;
&lt;span class="c1"&gt;// 😔&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These special functions are only necessary to work with indexes that might fall out of bounds, though. &lt;a href="https://kotlinlang.org/docs/null-safety.html" rel="noopener noreferrer"&gt;Nullability&lt;/a&gt;, for example, is handled the same way as you would in any other situation in Kotlin: using the power of the Elvis operator, smart-casts and friends.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;listOfNullableItems&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;listOfNullableItems&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Slicing
&lt;/h3&gt;

&lt;p&gt;Of course, we can go beyond getting individual items out of our list. Because a list is a collection like any other, we have access to the same &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/take.html" rel="noopener noreferrer"&gt;&lt;code&gt;take&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/drop.html" rel="noopener noreferrer"&gt;&lt;code&gt;drop&lt;/code&gt;&lt;/a&gt; functions that were introduced in the &lt;em&gt;&lt;a href="https://dev.to/kotlin/diving-into-kotlin-collections-587o"&gt;Diving into Kotlin collections&lt;/a&gt;&lt;/em&gt; post.&lt;/p&gt;

&lt;p&gt;But lists have a special way of retrieving multiple items - the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/slice.html" rel="noopener noreferrer"&gt;&lt;code&gt;slice&lt;/code&gt;&lt;/a&gt; function!&lt;/p&gt;

&lt;p&gt;When we give this function a bunch of indexes, it returns the elements at those places in our collection. In this example, we’re passing a list with index &lt;code&gt;0, 2, 4&lt;/code&gt;, and get those items from our list of letters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;myList&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"e"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;myList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;// [a, c, e]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of writing out all the indices by hand, we could also use &lt;code&gt;IntRange&lt;/code&gt;s or progressions to specify the indexes. For example, we could request “all items from 0 through 3”, or specify a custom step-size of 2. We could even pull out some items in reverse order, if we create a progression that uses &lt;code&gt;downTo&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;myList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [a, b, c, d]&lt;/span&gt;

&lt;span class="n"&gt;myList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;myList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lastIndex&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [a, c, e]&lt;/span&gt;

&lt;span class="n"&gt;myList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;downTo&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [c, b, a]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you may suspect, this &lt;em&gt;list&lt;/em&gt; of list features is not quite exhaustive – as always, there’s some more to explore even on this subject. But let’s put that on the back burner for a bit, and move on to a special kind of list – it's time to talk about &lt;em&gt;mutable lists&lt;/em&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Mutable Lists
&lt;/h2&gt;

&lt;p&gt;What's so special about mutable lists? Well, you can &lt;em&gt;mutate&lt;/em&gt; them! That, of course, doesn’t mean that these lists will turn into zombies (🧟‍♂️), but that you can change their content. If we consult an excerpt of a class hierarchy, we can see that &lt;code&gt;MutableList&lt;/code&gt; specializes &lt;code&gt;List&lt;/code&gt;, meaning everything we’ve learned about lists so far also works for their mutable counterpart, plus some extra functionality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnrg0js7pl6435klg2gm0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnrg0js7pl6435klg2gm0.png" alt="list-specialization"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;It's precisely that extra functionality that we’re interested in right now!&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating mutable lists
&lt;/h3&gt;

&lt;p&gt;Once again, mutable lists are commonly created via the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-list-of.html" rel="noopener noreferrer"&gt;&lt;code&gt;mutableListOf&lt;/code&gt;&lt;/a&gt; function, with a bunch of values as arguments. And, wherever you were able to find a &lt;code&gt;toList&lt;/code&gt; method, as discussed previously, you’ll probably also find a &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/to-mutable-list.html" rel="noopener noreferrer"&gt;&lt;code&gt;toMutableList&lt;/code&gt;&lt;/a&gt;. That also includes other lists and mutable lists – where you’ll get a fresh copy when calling &lt;code&gt;toMutableList&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 2, 3]&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toMutableList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;/span&gt;

&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toMutableList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add / Remove / Update
&lt;/h3&gt;

&lt;p&gt;Let's move on to the core of this subject – the ability to change content. That starts with adding something to the collection. If we want to add an extra number to the end of our mutable list we can do so via the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/add.html" rel="noopener noreferrer"&gt;&lt;code&gt;add&lt;/code&gt;&lt;/a&gt; function, or by using the &lt;code&gt;+=&lt;/code&gt; operator shorthand, both of which append an item to the end of the list.&lt;/p&gt;

&lt;p&gt;If we know &lt;em&gt;where&lt;/em&gt; in the collection we want our item to go, the &lt;code&gt;add&lt;/code&gt; function also accepts an index, which inserts the new element at that position and moves the surrounding elements to accommodate it. In the same way, we can also add a whole other collection to our mutable list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 2, 3, 4, 4]&lt;/span&gt;

&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 2, 10, 3, 4, 4]&lt;/span&gt;

&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 2, 10, 3, 4, 4, 5, 6, 7]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’re of course not constrained to just adding elements to our list – we can also remove them. If we know what element we want to get rid of, we can do that via the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/remove.html" rel="noopener noreferrer"&gt;&lt;code&gt;remove&lt;/code&gt;&lt;/a&gt; function or the &lt;code&gt;-=&lt;/code&gt; operator shorthand, which removes from our collection &lt;em&gt;a single instance&lt;/em&gt; of the element we provide. In this example, after calling -= and &lt;code&gt;remove&lt;/code&gt;, we got rid of two of the 3s in our original collection – because each invocation removed one of them.&lt;/p&gt;

&lt;p&gt;Alternatively, we can also pass the &lt;code&gt;-=&lt;/code&gt; operator a collection of elements. In this case, the operator acts as a shorthand for the &lt;code&gt;removeAll&lt;/code&gt; function. Here, it looks at every element in the collection we pass, and &lt;em&gt;removes all instances of them&lt;/em&gt; in our original, mutable collection. (This is an important distinction to make!) So, by passing 1 and 4 as a collection, we remove &lt;em&gt;all instances&lt;/em&gt; of those numbers from our mutable list, and we’re left with only 2 and 3 at the end.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 2, 3, 4, 4, 4]&lt;/span&gt;

&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we know the index where we want to kick an item out, we use the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/remove-at.html" rel="noopener noreferrer"&gt;&lt;code&gt;removeAt&lt;/code&gt;&lt;/a&gt; function instead. For example, we could remove the second element in our list, which resides at index 1.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 3, 3, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To update an item, we most commonly use the &lt;a href="https://kotlinlang.org/docs/operator-overloading.html#indexed-access-operator" rel="noopener noreferrer"&gt;&lt;em&gt;indexed access operator&lt;/em&gt;&lt;/a&gt; – so the brackets – together with an assignment. That one calls the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/set.html" rel="noopener noreferrer"&gt;&lt;code&gt;set&lt;/code&gt;&lt;/a&gt; function with that index and element under the hood, and switches out the item at the specified index – in this case, trading a "b" for an "a".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"e"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"a"&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [a, a, c, d, e]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Fill and Clear
&lt;/h3&gt;

&lt;p&gt;In certain situations, we might want to turn all elements of our list into the same element – like zeroing out a buffer before reusing it. This is something we can do using the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/fill.html" rel="noopener noreferrer"&gt;&lt;code&gt;fill&lt;/code&gt;&lt;/a&gt; function, which replaces each element with the same value we specify. If we look at a list of fruits, for example, and suddenly realize that all of them are really just sugar, we use fill to replace them with candy (🍬). While that metaphor may not be &lt;em&gt;entirely scientifically accurate&lt;/em&gt;, it's tasty nonetheless!&lt;/p&gt;

&lt;p&gt;And when we want to wipe our collection clean, the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/clear.html" rel="noopener noreferrer"&gt;&lt;code&gt;clear&lt;/code&gt;&lt;/a&gt; function can help with removing all elements from a collection – in our case, getting rid of all the candy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fruits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🍉"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🍊"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🥝"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// wait, it's all sugar?&lt;/span&gt;
&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🍬"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [🍬, 🍬, 🍬]&lt;/span&gt;

&lt;span class="c1"&gt;// ... nom nom&lt;/span&gt;
&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// []&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perhaps unsurprisingly, mutable lists grow and shrink automatically to accommodate all your items, so you can have an arbitrary number of elements in your collection. This might be obvious, but it’s so darn convenient, so I figured I’d mention it. The things we take for granted!&lt;/p&gt;

&lt;h3&gt;
  
  
  In-place modifications
&lt;/h3&gt;

&lt;p&gt;Thinking back to some of the previous entries of this series, we’ve seen a number of neat functions which we wouldn’t want to miss for mutable collections either – things like &lt;code&gt;sorted&lt;/code&gt;, &lt;code&gt;shuffled&lt;/code&gt;, and &lt;code&gt;reversed&lt;/code&gt;. However, those don’t modify the original collection.&lt;/p&gt;

&lt;p&gt;Luckily for us, these functions also have a mutable counterpart. So, when we want to sort, shuffle, or reverse a mutable list in place – instead of creating a new, separate copy with the effects applied – we use the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sort.html" rel="noopener noreferrer"&gt;&lt;code&gt;sort()&lt;/code&gt;&lt;/a&gt; instead of &lt;code&gt;sorted()&lt;/code&gt;, &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/shuffle.html" rel="noopener noreferrer"&gt;&lt;code&gt;shuffle()&lt;/code&gt;&lt;/a&gt; instead of &lt;code&gt;shuffled()&lt;/code&gt;, and &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reverse.html" rel="noopener noreferrer"&gt;&lt;code&gt;reverse()&lt;/code&gt;&lt;/a&gt; instead of &lt;code&gt;reversed()&lt;/code&gt; functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shuffled&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reversed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [3, 1, 4, 1, 5, 9]&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toMutableList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shuffle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [5, 1, 1, 3, 4, 9]&lt;/span&gt;

&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 1, 3, 4, 5, 9]&lt;/span&gt;

&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [9, 5, 4, 3, 1, 1]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mutable lists also offer the possibility to remove or keep &lt;em&gt;all&lt;/em&gt; elements that fulfill a certain predicate. The &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/remove-all.html" rel="noopener noreferrer"&gt;&lt;code&gt;removeAll&lt;/code&gt;&lt;/a&gt; function can remove all elements that match the predicate we specify. Let’s say we’re not a fan of small numbers in our collection, and only want to keep numbers that are 5 or above – &lt;code&gt;removeAll&lt;/code&gt; helps us do exactly that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;numbers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeAll&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [5, 9]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/retain-all.html" rel="noopener noreferrer"&gt;&lt;code&gt;retainAll&lt;/code&gt;&lt;/a&gt; function is the opposite, and only keeps those elements in the mutable list that match. If we want to retain every character in our collection that is a letter, we do that with the &lt;code&gt;retainAll&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;letters&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'d'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'5'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;letters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retainAll&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isLetter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;letters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [a, b, d]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This might feel a bit familiar to you, and rightfully so, because these are essentially the mutating equivalents of the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/filter.html" rel="noopener noreferrer"&gt;&lt;code&gt;filter&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/filter-not.html" rel="noopener noreferrer"&gt;&lt;code&gt;filterNot&lt;/code&gt;&lt;/a&gt; functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Views on Lists
&lt;/h3&gt;

&lt;p&gt;The last topic on today’s agenda is views on lists. That name already hints at what they allow us to do – they allow us to look at the elements in our list from a different perspective – let’s see what that means.&lt;/p&gt;

&lt;p&gt;Let’s assume we have a collection of fruits. To create a view, we can use the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/sub-list.html" rel="noopener noreferrer"&gt;&lt;code&gt;subList&lt;/code&gt;&lt;/a&gt; function, which takes a beginning and end index, which determines which elements should be “visible” in the view. By having a look at an example sublist, we can see that it contains the elements from our original collections based on the indices we specify (with the upper bound being exclusive):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fruits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🍉"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🍊"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🥝"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🍏"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sub&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [🍊, 🥝, 🍏]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because this is only a &lt;em&gt;view&lt;/em&gt;, and not a copy of our original collection, changes are automatically visible. That means if we change the orange to a banana in the underlying &lt;code&gt;fruits&lt;/code&gt; list, then our sublist will reflect that change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"🍌"&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [🍌, 🥝, 🍏]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What may be even more interesting is that this sublist is in itself mutable, as well! If we change the green apple in our sublist to a pineapple, and have a look at our original fruits collection again, we see that the change is visible from here as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"🍍"&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [🍉, 🍌, 🥝, 🍍]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, we can use the fill function which we’ve learned about earlier to turn an interval inside of our fruit-list back into candy, again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🍬"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [🍉, 🍬, 🍬, 🍬]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To reiterate; all of that works because these aren’t two different collections – there is only one collection, and  &lt;code&gt;subList&lt;/code&gt; has just given us a different perspective on that list!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An important note on the topic of sublists:&lt;/strong&gt; They are only well-defined as long as the underlying, original list is &lt;em&gt;not structurally changed&lt;/em&gt;. Changes affecting the size of the list, for example, automatically cause any views that were previously returned by invoking &lt;code&gt;subList&lt;/code&gt; to have undefined behavior.&lt;/p&gt;

&lt;p&gt;For a common case, which is looking at a list backwards, the Kotlin standard library also comes with the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/as-reversed.html" rel="noopener noreferrer"&gt;&lt;code&gt;asReversed&lt;/code&gt;&lt;/a&gt; function. It provides a backwards view of the underlying list. Once again, changes made in the view are visible in the original collection, and vice versa. As you can see in the following example, turning the orange into a banana in our original list also changes what we see in the reversed view. Altering it back to a pineapple via our reversed view also alters our original mutable list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fruits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🍉"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🍊"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🥝"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🍏"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;stiurf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asReversed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stiurf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [🍏, 🥝, 🍊, 🍉]&lt;/span&gt;

&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"🍌"&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stiurf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [🍏, 🥝, 🍌, 🍉]&lt;/span&gt;

&lt;span class="n"&gt;stiurf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"🍍"&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [🍉, 🍍, 🥝, 🍏]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These types of “views” are actually available for non-mutable lists, as well, and allow you to pass around different sub-selections of your collections without having to create new copies every time – however, this seemed like a topic that would be nicer to illustrate with the mutable variant, to drive the point home that there really is only one underlying collection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;With that, we have reached the end of today’s expedition! I hope some of the stuff you’ve seen today is helping you strengthen your understanding of Kotlin lists. When you’re  writing Kotlin code the next time, see if you can apply some of the stuff we’ve talked about today – whether it’s slicing a collection, using sub-lists, or handling out-of-bounds situations for lists elegantly with the &lt;code&gt;getOrNull&lt;/code&gt; and &lt;code&gt;getOrElse&lt;/code&gt; functions.&lt;/p&gt;

&lt;p&gt;If you’ve learned something new, and want to see more like this, make sure to &lt;a href="https://dev.to/kotlin"&gt;follow us here on dev.to&lt;/a&gt;, and check out some of the interesting content we publish on &lt;a href="http://kotl.in/video" rel="noopener noreferrer"&gt;our official YouTube channel&lt;/a&gt;, as well!&lt;/p&gt;

&lt;p&gt;Now, it’s time for all of you to go and explore some more Kotlin! Take care, and see you in the next one!&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>programming</category>
      <category>android</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Advanced Kotlin Collection Functionality</title>
      <dc:creator>Sebastian Aigner</dc:creator>
      <pubDate>Mon, 14 Jun 2021 17:49:10 +0000</pubDate>
      <link>https://dev.to/kotlin/advanced-kotlin-collection-functionality-5e90</link>
      <guid>https://dev.to/kotlin/advanced-kotlin-collection-functionality-5e90</guid>
      <description>&lt;p&gt;This blog post accompanies a video from our &lt;strong&gt;YouTube series&lt;/strong&gt; which you can find on our &lt;a href="https://kotl.in/video" rel="noopener noreferrer"&gt;Kotlin YouTube channel&lt;/a&gt;, or &lt;strong&gt;watch here&lt;/strong&gt; directly!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/N4CpLxGJlq0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Today, we are learning about advanced functions that we can use to work with and manipulate all kinds of Kotlin collections!&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking predicates: &lt;code&gt;any&lt;/code&gt;, &lt;code&gt;none&lt;/code&gt; and &lt;code&gt;all&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Let’s warm up by having a look at a selection of functions that allow us to check conditions for our collection elements.&lt;/p&gt;

&lt;p&gt;They’re called &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/any.html" rel="noopener noreferrer"&gt;&lt;code&gt;any&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/none.html" rel="noopener noreferrer"&gt;&lt;code&gt;none&lt;/code&gt;&lt;/a&gt;, and &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/all.html" rel="noopener noreferrer"&gt;&lt;code&gt;all&lt;/code&gt;&lt;/a&gt;. Each of them takes a &lt;em&gt;predicate&lt;/em&gt; – so a function that returns &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt; – and checks whether the collection fits this predicate.&lt;/p&gt;

&lt;p&gt;Let’s say we have a group of friends (which is really just a &lt;code&gt;List&amp;lt;Person&amp;gt;&lt;/code&gt;, each featuring a &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;age&lt;/code&gt;, and maybe a &lt;code&gt;driversLicense&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;driversLicense&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;friendGroup&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Jo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mic"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hay"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we want to check if the group can travel by car, we want to check if &lt;em&gt;any&lt;/em&gt; of them have a driver's license – so we use the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/any.html" rel="noopener noreferrer"&gt;&lt;code&gt;any&lt;/code&gt;&lt;/a&gt; function. It returns &lt;code&gt;true&lt;/code&gt; if there is &lt;em&gt;at least one element&lt;/em&gt; in our collection for which the predicate returns &lt;code&gt;true&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;groupCanTravel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;friendGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driversLicense&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As another example, let’s say we want to check if this group of friends is allowed to enter a club – for this, we would need to make sure that &lt;em&gt;none&lt;/em&gt; of the folks in the group are underage!&lt;/p&gt;

&lt;p&gt;Here, we can use the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/none.html" rel="noopener noreferrer"&gt;&lt;code&gt;none&lt;/code&gt;&lt;/a&gt; function, which only returns &lt;code&gt;true&lt;/code&gt; when there is &lt;em&gt;not a single element in our collection&lt;/em&gt; that holds true for our predicate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;groupGetsInClub&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;friendGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;none&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The third function in the bunch is the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/all.html" rel="noopener noreferrer"&gt;&lt;code&gt;all&lt;/code&gt;&lt;/a&gt; function. At this point, you can probably spot the pattern – &lt;code&gt;all&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt;, if each and every element in our collection matches our predicate. We could use it to check whether all names in our friend group are short:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;groupHasShortNames&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;friendGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Predicates for empty collections
&lt;/h3&gt;

&lt;p&gt;While on the topic, let's have a little brain teaser: How do &lt;code&gt;any&lt;/code&gt;, &lt;code&gt;none&lt;/code&gt;, and &lt;code&gt;all&lt;/code&gt; behave for &lt;em&gt;empty collections&lt;/em&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;nobody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emptyList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// what happens here?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s look at &lt;code&gt;any&lt;/code&gt; first. There is no element that can satisfy the predicate, so it returns &lt;code&gt;false&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;nobody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driversLicense&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same goes for &lt;code&gt;none&lt;/code&gt; – there is no function that can violate our predicate, so it returns true:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;nobody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;none&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;all&lt;/code&gt; function, however, returns &lt;code&gt;true&lt;/code&gt; with an empty collection. This may surprise you in the first moment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;nobody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this is quite intentional and sound: You can't name an element that &lt;em&gt;violates&lt;/em&gt; the predicate. Therefore, the predicate has to be true for &lt;em&gt;all elements in the collection&lt;/em&gt; – even if there are &lt;em&gt;none&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;This might feel a bit mind-bending to think about at first, but you’ll find that this concept, which is called the &lt;a href="https://en.wikipedia.org/wiki/Vacuous_truth" rel="noopener noreferrer"&gt;vacuous truth&lt;/a&gt;, actually plays very well with checking conditions, and expressing logic in program code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fthg07e0ao215ck2lwm1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fthg07e0ao215ck2lwm1z.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Collection parts: &lt;code&gt;chunked&lt;/code&gt; and &lt;code&gt;windowed&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;With our brain freshly teased, let’s move on to the next topic, and learn about how to break collections into parts!&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;chunked&lt;/code&gt; function
&lt;/h3&gt;

&lt;p&gt;If we have a collection that just contains a bunch of items, we can cut up the list into individual chunks of a certain size by using the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/chunked.html" rel="noopener noreferrer"&gt;&lt;code&gt;chunked&lt;/code&gt;&lt;/a&gt; function. What we get back is a list of lists, where each element is a _chunk _of our original list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;objects&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🌱"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🚀"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"💡"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🐧"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"⚙️"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🤖"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"📚"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chunked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;// [[🌱, 🚀, 💡], [🐧, ⚙️, 🤖], [📚]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, we break our list of random objects (represented with emojis) apart, using a chunk size of 3.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The first &lt;em&gt;element&lt;/em&gt; in our result is in itself a &lt;em&gt;list&lt;/em&gt; which contains our first three objects – &lt;code&gt;[🌱, 🚀, 💡]&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The second element is once again a chunk, and contains the three elements that follow after that – &lt;code&gt;[🐧, ⚙️, 🤖]&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The last element is also a chunk – but since we ran out of elements to fill it with three items, it only contains the book stack - &lt;code&gt;[📚]&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In typical standard library fashion, the &lt;code&gt;chunked&lt;/code&gt; function also provides a little bit of extra power. To immediately transform the chunks we just created, we can apply a &lt;em&gt;transformation function&lt;/em&gt;. For example, we can reverse the order of elements in the resulting lists, without having to do another &lt;code&gt;map&lt;/code&gt; call separately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chunked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reversed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;// [[💡, 🚀, 🌱], [🤖, ⚙️, 🐧], [📚]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To summarize: the &lt;code&gt;chunked&lt;/code&gt; function cuts our original collection into lists of lists, where each list has the specified size.&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;windowed&lt;/code&gt; function
&lt;/h3&gt;

&lt;p&gt;Closely related is the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/windowed.html" rel="noopener noreferrer"&gt;&lt;code&gt;windowed&lt;/code&gt;&lt;/a&gt; function. It also returns a list of lists from our collection. Instead of cutting it up into pieces, however, this function generates a “sliding window” of our collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;windowed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;// [[🌱, 🚀, 💡], [🚀, 💡, 🐧], [💡, 🐧, ⚙️], [🐧, ⚙️, 🤖], [⚙️, 🤖, 📚]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The first window is once again the first three elements – &lt;code&gt;[🌱, 🚀, 💡]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The next window is &lt;code&gt;[🚀, 💡, 🐧]&lt;/code&gt; – we simply “moved” our window of size 3 over by one, which includes some overlap.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;windowed&lt;/code&gt; function can also be customized. We can change both &lt;em&gt;window&lt;/em&gt; and &lt;em&gt;step&lt;/em&gt; size, the latter being the number of elements that the window should “slide along” for each step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;windowed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partialWindows&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;// [[🌱, 🚀, 💡, 🐧], [💡, 🐧, ⚙️, 🤖], [⚙️, 🤖, 📚], [📚]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see in the example above, we can also control whether our result should contain &lt;em&gt;partial windows&lt;/em&gt;. This changes the behavior when we’ve reached the end of our input collection, and we’re running out of elements.&lt;/p&gt;

&lt;p&gt;With partial windows enabled, we just &lt;em&gt;keep sliding&lt;/em&gt;, and we get the last elements trickling in, in the form of smaller windows, until we get a window which once again only contains the last element from our input collection – &lt;code&gt;[⚙️, 🤖, 📚], [📚]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;windowed&lt;/code&gt; also allows us to perform an additional transformation at the end, which can modify the individual windows directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;windowed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reversed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;// [[🐧, 💡, 🚀, 🌱], [🤖, ⚙️, 🐧, 💡], [📚, 🤖, ⚙️], [📚]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Un-nesting Collections: Flatten and Flatmap
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;chunked&lt;/code&gt; and &lt;code&gt;windowed&lt;/code&gt; functions, along with some others all return nested collections – lists of lists. What if we want to &lt;em&gt;un-nest&lt;/em&gt; these, turning them back into flat lists of elements? As usual, we do not need to fear, because the standard library has got us covered.&lt;/p&gt;

&lt;p&gt;We can call the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/flatten.html" rel="noopener noreferrer"&gt;&lt;code&gt;flatten&lt;/code&gt;&lt;/a&gt; function on a collection of collections. As you may suspect, the result is a single list of all the elements that were originally contained inside of our nested collections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;objects&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🌱"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🚀"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"💡"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🐧"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"⚙️"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🤖"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"📚"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;windowed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reversed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// [🐧, 💡, 🚀, 🌱, 🤖, ⚙️, 🐧, 💡, 📚, 🤖, ⚙️, 📚]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is also a good point to talk about the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/flat-map.html" rel="noopener noreferrer"&gt;&lt;code&gt;flatMap&lt;/code&gt;&lt;/a&gt; function. &lt;code&gt;flatMap&lt;/code&gt; is like a combination of first using &lt;code&gt;map&lt;/code&gt;, and then using &lt;code&gt;flatten&lt;/code&gt; – It takes a lambda which generates a &lt;em&gt;collection&lt;/em&gt; from each of the elements in our input collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;lettersInNames&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Lou"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Mel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Cyn"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;flatMap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lettersInNames&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [L, o, u, M, e, l, C, y, n]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, the function that we provide creates a &lt;em&gt;list&lt;/em&gt; for each element in our input collection, containing the letters of the original string. Next, that collection of collections gets flattened. As desired, we end up with a plain list of elements – the list of characters from the names of the original collection.&lt;/p&gt;

&lt;p&gt;If you are doing an operation on a list, which in turn generates a collection for each one of the input elements, consider if &lt;code&gt;flatMap&lt;/code&gt; can help you simplify your code!&lt;/p&gt;

&lt;h2&gt;
  
  
  Combining collections: &lt;code&gt;zip&lt;/code&gt; and &lt;code&gt;unzip&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;So far, we have always looked at a single collection, and what we can do with it. Let's learn about a way to combine two collections, and create a new one from them – it's time to &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/zip.html" rel="noopener noreferrer"&gt;&lt;code&gt;zip&lt;/code&gt;&lt;/a&gt;!&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;zip&lt;/code&gt; function
&lt;/h3&gt;

&lt;p&gt;Assume we have two collections, where the elements at each index are somehow related. For example, this could be a list of cities in Germany, and we have another list of German license plates that correspond to those cities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;germanCities&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"Aachen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Bielefeld"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"München"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;germanLicensePlates&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"AC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"BI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"M"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;germanCities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;germanLicensePlates&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;// [(Aachen, AC), (Bielefeld, BI), (München, M)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, by zipping these two collections, we get a &lt;em&gt;list of pairs&lt;/em&gt;, where each pair contains the elements with the same index from the original two collections.&lt;/p&gt;

&lt;p&gt;Metaphorically, this is similar to a zipper on a jacket, where the teeth match up one by one. We zip together the elements of our collection, and we get pairs of each city and its corresponding license plate.&lt;/p&gt;

&lt;p&gt;For an extra bit of flair, we can also call the &lt;code&gt;zip&lt;/code&gt; function using infix notation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;germanCities&lt;/span&gt; &lt;span class="n"&gt;zip&lt;/span&gt; &lt;span class="n"&gt;germanLicensePlates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [(Aachen, AC), (Bielefeld, BI), (München, M)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;zip&lt;/code&gt; can also take a transformation function. We can pass a lambda that receives the values of the individual zipped pairs, and we can apply a transformation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;germanCities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;germanLicensePlates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plate&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;plate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lowercase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;// [(AACHEN, ac), (BIELEFELD, bi), (MÜNCHEN, m)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The &lt;code&gt;unzip&lt;/code&gt; function
&lt;/h3&gt;

&lt;p&gt;The standard library also contains the inverse function, called &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/unzip.html" rel="noopener noreferrer"&gt;&lt;code&gt;unzip&lt;/code&gt;&lt;/a&gt;, which takes a list of pairs, and splits them back into a pair of two separate lists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;citiesToPlates&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;germanCities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;germanLicensePlates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plate&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;plate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lowercase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="py"&gt;cities&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;plates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;citiesToPlates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unzip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cities&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [AACHEN, BIELEFELD, MÜNCHEN]&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [ac, bi, m]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example above uses a destructuring declaration to easily access both of them.&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;zipWithNext&lt;/code&gt; function
&lt;/h3&gt;

&lt;p&gt;In a way, &lt;code&gt;zipWithNext&lt;/code&gt; is really a specialized case of the &lt;code&gt;windowed&lt;/code&gt; function we got to know today: Instead instead of zipping together two separate lists element by element, this function takes one collection, and zips each of its items with the one that follows it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;random&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zipWithNext&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;// [(3, 1), (1, 4), (4, 1), (1, 5), (5, 9), (9, 2), (2, 6), (6, 5), (5, 4)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, we're zipping together a list of numbers. If we want to check the “change” – how much the value increments or decrements each step – we can express this quite elegantly using &lt;code&gt;zipWithNext&lt;/code&gt;. We provide a lambda that receives a pair of one number and the one that follows immediately after:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;random&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;changes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zipWithNext&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [-2, 3, -3, 4, 4, -7, 4, -1, -1]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Custom aggregations: &lt;code&gt;reduce&lt;/code&gt; and &lt;code&gt;fold&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;We have finally arrived at the &lt;em&gt;grand finale&lt;/em&gt; for this post – functions that help us build custom aggregations.&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;reduce&lt;/code&gt; function
&lt;/h3&gt;

&lt;p&gt;Let’s set the scene with a small callback – in the &lt;a href="https://dev.to/kotlin/diving-into-kotlin-collections-587o"&gt;previous post&lt;/a&gt;, we learned about functions like &lt;code&gt;sum&lt;/code&gt;, &lt;code&gt;average&lt;/code&gt;, &lt;code&gt;count&lt;/code&gt;, and functions to receive the minimum and maximum elements inside a collection. All of these &lt;em&gt;reduce&lt;/em&gt; our collection to a single value.&lt;/p&gt;

&lt;p&gt;It's possible that we find ourselves in a situation where there’s no out-of-the-box function for how we want to generate a single value for our collection. For example, we may want to multiply all numbers in a list, instead of summing them.&lt;/p&gt;

&lt;p&gt;In this case, we can rely on the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reduce.html" rel="noopener noreferrer"&gt;&lt;code&gt;reduce&lt;/code&gt;&lt;/a&gt; function as a more generic version for aggregating a collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;random&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;multiplicativeAggregate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;multiplicativeAggregate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// 129600&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As seen in the example above, we call the reduce function with a lambda block which receives two parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An accumulator, which has the same type as our collection, and&lt;/li&gt;
&lt;li&gt;An individual item from our collection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The task of the lambda function is to &lt;em&gt;return a new accumulator&lt;/em&gt;. Each invocation, one after the other, receives not only the &lt;em&gt;current element&lt;/em&gt;, but also the &lt;em&gt;result of the previous calculation&lt;/em&gt;, inside the accumulator.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The function starts with the first element of our collection in the accumulator.&lt;/li&gt;
&lt;li&gt;Then it runs our operation – in this example, we multiply the accumulator (which right now is the first number) with the current element (which is the second number).&lt;/li&gt;
&lt;li&gt;We’ve calculated a new value, which will be stored in the accumulator, and used when our function is called once more with the third element&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This cycle repeats, and we continue to gradually build up the final result in our accumulator. One might even say we’re &lt;em&gt;accumulating&lt;/em&gt; that result!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fri4o64h51mzhg2cwe4g2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fri4o64h51mzhg2cwe4g2.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we’ve gone through all the elements in our collection, &lt;code&gt;reduce&lt;/code&gt; returns the final value that’s inside the accumulator.&lt;/p&gt;

&lt;p&gt;As you can see, with &lt;code&gt;reduce&lt;/code&gt;, we can hide a lot of mechanics for aggregating our collection behind one function call, and stay true to Kotlin’s concise nature.&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;fold&lt;/code&gt; function
&lt;/h3&gt;

&lt;p&gt;But we can actually go beyond this, and can take this versatility one step further – with the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/fold.html" rel="noopener noreferrer"&gt;&lt;code&gt;fold&lt;/code&gt;&lt;/a&gt; operation. Remember – when we used &lt;code&gt;reduce&lt;/code&gt;, the iteration starts with the first element of our input collection in the accumulator. &lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;fold&lt;/code&gt; function, we get to specify our own accumulator – and in fact, it can even have a different type than the items in our input collection! As an example, we can take a list of words, and multiply the number of their characters together using &lt;code&gt;fold&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fruits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"cherry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"banana"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"orange"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;multiplied&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;multiplied&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 1080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The underlying mechanism is the same – the lambda passed to the &lt;code&gt;fold&lt;/code&gt; function gets called with an accumulator and a value, and calculates a new accumulator. The difference is that we specify the initial value of the accumulator ourselves.&lt;/p&gt;

&lt;p&gt;(&lt;em&gt;Note that we pass &lt;code&gt;1&lt;/code&gt; as an initial value for our accumulator, and not &lt;code&gt;0&lt;/code&gt;. That’s because for multiplication, 1 is the &lt;a href="https://en.wikipedia.org/wiki/Identity_element" rel="noopener noreferrer"&gt;neutral element&lt;/a&gt;&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Both &lt;code&gt;fold&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt; come in a number of other flavors, as well:&lt;/p&gt;

&lt;p&gt;– the sibling functions &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reduce-right.html" rel="noopener noreferrer"&gt;&lt;code&gt;reduceRight&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/fold-right.html" rel="noopener noreferrer"&gt;&lt;code&gt;foldRight&lt;/code&gt;&lt;/a&gt; change the order of iteration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reduce-or-null.html" rel="noopener noreferrer"&gt;&lt;code&gt;reduceOrNull&lt;/code&gt;&lt;/a&gt; allows you to work with empty collections without throwing exceptions.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/running-fold.html" rel="noopener noreferrer"&gt;&lt;code&gt;runningFold&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/running-reduce.html" rel="noopener noreferrer"&gt;&lt;code&gt;runningReduce&lt;/code&gt;&lt;/a&gt; don’t just return a single value representing the final state of the accumulator, but instead return a list of all the intermediate accumulator values as well.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  That's it!
&lt;/h2&gt;

&lt;p&gt;This concludes my overview of some advanced collection operations in Kotlin – I hope you found this post useful, and have learned something new!&lt;/p&gt;

&lt;p&gt;Maybe you can find a point in your code where a predicate, some zipping, chunking or windowing could come in handy! Or maybe you want to explore by defining your own aggregations functions based on the &lt;code&gt;reduce&lt;/code&gt; or &lt;code&gt;fold&lt;/code&gt; functions.&lt;/p&gt;

&lt;p&gt;To get reminded when new Kotlin content is released, follow us here on &lt;a href="https://dev.to/kotlin"&gt;dev.to/kotlin&lt;/a&gt;, and make sure to follow me on Twitter &lt;a href="https://twitter.com/sebi_io" rel="noopener noreferrer"&gt;@sebi_io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also, use this opportunity sure to find the subscribe button and notification bell on our &lt;a href="https://kotl.in/video" rel="noopener noreferrer"&gt;YouTube channel&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Take care!&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>programming</category>
      <category>android</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Tips &amp; tricks for building a game using Compose for Desktop</title>
      <dc:creator>Sebastian Aigner</dc:creator>
      <pubDate>Thu, 06 May 2021 13:03:41 +0000</pubDate>
      <link>https://dev.to/kotlin/tips-tricks-for-building-a-game-using-jetpack-compose-for-desktop-266o</link>
      <guid>https://dev.to/kotlin/tips-tricks-for-building-a-game-using-jetpack-compose-for-desktop-266o</guid>
      <description>&lt;p&gt;In the &lt;strong&gt;first part of my blog post series&lt;/strong&gt; about building a small clone of the classic arcade game &lt;a href="https://en.wikipedia.org/wiki/Asteroids_(video_game)" rel="noopener noreferrer"&gt;&lt;strong&gt;Asteroids&lt;/strong&gt;&lt;/a&gt; on top of Jetpack Compose for Desktop, we saw how to implement the main game loop, as well as manage state and draw basic shapes. In this post, we will explore some more details of the game implementation. This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rendering details&lt;/strong&gt; – making sure game objects don't escape our play area, and using a device-independent coordinate system for rendering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geometry and linear algebra&lt;/strong&gt; – the &lt;em&gt;secret sauce&lt;/em&gt; that makes the space ships fly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frame-independent movement&lt;/strong&gt; – so that our game works consistently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's learn about these topics!&lt;/p&gt;

&lt;h2&gt;
  
  
  Rendering: Clipping and Coordinate Systems
&lt;/h2&gt;

&lt;p&gt;In the context of rendering, there are two areas that still need our attention – we need to make sure that our &lt;strong&gt;game objects are constrained to the game surface&lt;/strong&gt;, and we need to make a conscious decision about the &lt;strong&gt;units of the coordinates&lt;/strong&gt; we use to describe the position of a game object. We'll discuss both in this section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clipping
&lt;/h3&gt;

&lt;p&gt;By default, Compose naively draws your objects without any clipping. This means game objects can poke outside the "play surface", which produces a weirdly fourth-wall-breaking effect:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xh0d39znpo8w97djsab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xh0d39znpo8w97djsab.png" alt="game objects escaping the bounds of reality"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We &lt;strong&gt;constrain the game objects to the bounds&lt;/strong&gt; of our play surface by applying &lt;code&gt;Modifier.clipToBounds()&lt;/code&gt; to the &lt;code&gt;Box&lt;/code&gt; which defines our play surface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxWidth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxHeight&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clipToBounds&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="c1"&gt;// . . .&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because all our game elements are drawn as children of this play area &lt;code&gt;Box&lt;/code&gt;, using this modifier causes the rendered entities inside it to be cut off at the edges (instead of being drawn over the surrounding user interface):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zvlctk9ajr379k1m4rv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zvlctk9ajr379k1m4rv.png" alt="game objects staying snugly inside the play area"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Device-Independent Pixels and Density
&lt;/h3&gt;

&lt;p&gt;Something else to be aware of when doing any kind of rendering tasks in Compose for Desktop is to &lt;strong&gt;keep the units of measurement in the back of your mind&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Wherever I worked with coordinates, I decided to work in &lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp" rel="noopener noreferrer"&gt;&lt;strong&gt;device-independent pixels&lt;/strong&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;mouse pointer position&lt;/strong&gt; is stored as a &lt;code&gt;DpOffset&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Game width&lt;/strong&gt; and &lt;strong&gt;height&lt;/strong&gt; are stored as &lt;code&gt;Dp&lt;/code&gt;s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Game objects&lt;/strong&gt; are placed on the play surface using their &lt;code&gt;.dp&lt;/code&gt; coordinates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helps the game work consistently across high-density displays and low-density displays alike. However, it also &lt;strong&gt;requires some operations to be performed in the context of &lt;code&gt;Density&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, the &lt;code&gt;pointerMoveFilter&lt;/code&gt; returns an &lt;code&gt;Offset&lt;/code&gt; in pixels – and &lt;strong&gt;they are not device-independent&lt;/strong&gt;!. To work around this, we obtain the local screen density in our composition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;density&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LocalDensity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then use &lt;code&gt;with(density)&lt;/code&gt; to access the &lt;code&gt;toDp()&lt;/code&gt; extension functions to the &lt;code&gt;Offset&lt;/code&gt; into a &lt;code&gt;DpOffset&lt;/code&gt;, allowing us to store our &lt;code&gt;targetLocation&lt;/code&gt; in this device-independent pixel format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pointerMoveFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onMove&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;density&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;targetLocation&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DpOffset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toDp&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toDp&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For storing the play area's width and height, we do a very similar thing, just without wrapping it in a &lt;code&gt;DpOffset&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onSizeChanged&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;density&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toDp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toDp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A Game of Geometry and Linear Algebra &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Underneath the visualization, the "Asteroids" game builds on just a few basic blocks to implement its mechanics – it is really a game of vectors and linear algebra:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;position&lt;/strong&gt;, &lt;strong&gt;movement&lt;/strong&gt;, and &lt;strong&gt;acceleration&lt;/strong&gt; of the ship can be described by &lt;em&gt;position, movement, and acceleration vectors&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;orientation&lt;/strong&gt; of the ship is the &lt;em&gt;angle&lt;/em&gt; of the &lt;em&gt;vector&lt;/em&gt; between the ship and the cursor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Circle-circle collisions&lt;/strong&gt; can be tested based on &lt;em&gt;distance vectors&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of reinventing the &lt;del&gt;wheel&lt;/del&gt; vector, I decided to use &lt;code&gt;openrndr-math&lt;/code&gt;, which includes an implementation of the &lt;code&gt;Vector2&lt;/code&gt; class including all common operations, like scalar multiplication, addition, subtraction, the dot product, and more. (Ever since listening to the &lt;a href="https://talkingkotlin.com/openrndr-with-edwin-jakobs/" rel="noopener noreferrer"&gt;Talking Kotlin&lt;/a&gt; episode, I've been meaning to explore &lt;a href="https://openrndr.org/" rel="noopener noreferrer"&gt;OPENRNDR&lt;/a&gt; in detail, but that will have to happen in a separate project.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://api.openrndr.org/openrndr-math/openrndr-math/org.openrndr.math/-vector2/index.html" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4t373i87ll0hb6e6zsvn.png" alt="OPENRNDR Vector2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As somebody who happens to be a bit rusty with their linear algebra skills, I extended the functionality of the class a bit. For example, I defined the following extension function to allow me to access the angle a &lt;code&gt;Vector2&lt;/code&gt; in degrees between 0-360:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nc"&gt;Vector2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;rawAngle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;atan2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rawAngle&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thankfully, I did not have to spend too much time on figuring out the call to &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.math/atan2.html" rel="noopener noreferrer"&gt;&lt;code&gt;atan2&lt;/code&gt;&lt;/a&gt;, because I previously watched one of &lt;a href="http://twitter.com/intelligibabble" rel="noopener noreferrer"&gt;Leland Richardson&lt;/a&gt;'s &lt;a href="https://www.youtube.com/watch?v=fwn7olJOc70" rel="noopener noreferrer"&gt;live streams&lt;/a&gt; where he also uses this function to calculate some angles.&lt;/p&gt;

&lt;p&gt;Extensions like this one help me express ideas in ways I understand them myself – and hopefully still will a few months down the road.&lt;/p&gt;

&lt;p&gt;I also made use of properties with &lt;a href="https://kotlinlang.org/docs/properties.html#getters-and-setters" rel="noopener noreferrer"&gt;backing fields&lt;/a&gt; to make it possible to access a &lt;code&gt;GameObject&lt;/code&gt;'s movement vector in different representations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As a combination of &lt;strong&gt;length&lt;/strong&gt; (speed) and &lt;strong&gt;angle&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;As a vector with &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; coordinates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the context of a &lt;code&gt;GameObject&lt;/code&gt;, that can look like the following, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;speed&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;mutableStateOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;angle&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;mutableStateOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;position&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;mutableStateOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;movementVector&lt;/span&gt;
    &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Vector2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;UNIT_X&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;speed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;
        &lt;span class="n"&gt;angle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we're using this functionality outside of the &lt;code&gt;GameObject&lt;/code&gt; class a lot, we could also consider defining additional &lt;code&gt;length&lt;/code&gt; / &lt;code&gt;angle&lt;/code&gt; getters and setters as extension properties on the &lt;code&gt;Vector2&lt;/code&gt; class, directly.&lt;/p&gt;

&lt;p&gt;For our simulation, we still need to do a bit more – we haven't yet addressed the problem of how to update location and speed based on the elapsed real time. Let's talk about the approach for that next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frame-Independent Movement With Delta Timing &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;When building game logic, we need to keep one essential point in mind: &lt;strong&gt;Not all frames are created equal!&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On a 60 Hz display, each frame is visible for 16ms.&lt;/li&gt;
&lt;li&gt;On a 120 Hz display, that number drops to 8.3ms.&lt;/li&gt;
&lt;li&gt;On a 240 Hz display, each frame only shows for 4.2ms.&lt;/li&gt;
&lt;li&gt;On a system under load, or while running in a non-focused window, the application frame rate may be lower than 60 Hz.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means that &lt;strong&gt;we can't use "frames" as a measurement of time&lt;/strong&gt;: If we define the speed of our spaceship in relation to the frame rate, it would move four times faster on a 240 Hz display than on a 60 Hz display.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvo8s3j8b4v0zx8b3eozn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvo8s3j8b4v0zx8b3eozn.png" alt="frame-based"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We need to &lt;strong&gt;decouple the game logic&lt;/strong&gt; (and its rudimentary "physics simulation") &lt;strong&gt;from the frame rate&lt;/strong&gt; at which our application runs. Even &lt;a href="https://youtu.be/qpC43CdvjyA?t=25" rel="noopener noreferrer"&gt;AAA games&lt;/a&gt; don't get this right all the time – but for our projects, we can do better!&lt;/p&gt;

&lt;p&gt;A straightforward approach for this decoupling is to use &lt;a href="https://en.wikipedia.org/wiki/Delta_timing" rel="noopener noreferrer"&gt;&lt;strong&gt;delta timing&lt;/strong&gt;&lt;/a&gt;: We calculate the new game state based on the &lt;em&gt;time difference&lt;/em&gt; (the &lt;em&gt;delta&lt;/em&gt;) since the last time we updated the game. &lt;br&gt;
This usually means we &lt;em&gt;multiply&lt;/em&gt; the result of our calculations with the time delta, &lt;em&gt;scaling&lt;/em&gt; the result based on the elapsed time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dnr7776bas1ly70yjvr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dnr7776bas1ly70yjvr.png" alt="time-based"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Compose for Desktop, we use &lt;code&gt;withFrameMillis&lt;/code&gt; and &lt;code&gt;withFrameNanos&lt;/code&gt;. Both of them provide a timestamp, so we just need to keep track of the previous timestamp to calculate the &lt;code&gt;delta&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;prevTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0L&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;delta&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;prevTime&lt;/span&gt;
    &lt;span class="c1"&gt;// . . .&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case, a &lt;code&gt;GameObject&lt;/code&gt; has an &lt;code&gt;update&lt;/code&gt; function that takes a &lt;code&gt;realDelta: Float&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;velocity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;movementVector&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;realDelta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toDouble&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;velocity&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As demonstrated in the code above, I use it to scale the velocity of game objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;This concludes our tour of building a small game with Compose for Desktop! To see how all the pieces fit together, read the source code (~300 lines of code) on &lt;a href="https://github.com/SebastianAigner/asteroids-compose-for-desktop" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Building Asteroids on Compose for Desktop was great fun! I am always surprised by the iteration speed that &lt;a href="https://www.jetbrains.com/lp/compose/" rel="noopener noreferrer"&gt;Compose for Desktop&lt;/a&gt; provides: &lt;strong&gt;Getting from a first rectangle to a full game in just one long evening.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Of course, implementing a retro game like Asteroids on modern hardware comes with the luxury of not having to think too hard about performance optimizations, allocations, entity-component systems, or more. When building something more ambitious, these points likely need addressing, and you might find yourself using a few additional libraries besides a &lt;code&gt;Vector2&lt;/code&gt; implementation.&lt;/p&gt;

&lt;p&gt;For the next &lt;a href="https://en.wikipedia.org/wiki/Super_Hexagon" rel="noopener noreferrer"&gt;Super Hexagon&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Roguelike" rel="noopener noreferrer"&gt;pixel roguelike&lt;/a&gt;, or other 2D game, however, you can definitely &lt;strong&gt;give Compose a shot&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once again, you can find all 300 lines of source code for this project on &lt;a href="https://github.com/SebastianAigner/asteroids-compose-for-desktop" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're looking for additional inspiration, take a look at some other &lt;strong&gt;folks building games with Compose&lt;/strong&gt;!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vivek Sharma built &lt;a href="https://twitter.com/V9vek/status/1350156513625534464" rel="noopener noreferrer"&gt;everybody's favorite dinosaur game&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;vitaviva built &lt;a href="https://twitter.com/vitaviva2/status/1379876842560122886" rel="noopener noreferrer"&gt;Tetris with Compose&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;John O'Reilly made a &lt;a href="https://github.com/joreilly/chip-8" rel="noopener noreferrer"&gt;Compose for Desktop CHIP-8 frontend&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;theapache64 pushes the limits of Compose's builtin components to implement &lt;a href="https://twitter.com/theapache64/status/1379735815023030279" rel="noopener noreferrer"&gt;Switch, Check, and Radio Snake&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gamedev</category>
      <category>kotlin</category>
      <category>jetpackcompose</category>
      <category>android</category>
    </item>
    <item>
      <title>How I built an "Asteroids" game using Jetpack Compose for Desktop</title>
      <dc:creator>Sebastian Aigner</dc:creator>
      <pubDate>Thu, 06 May 2021 13:03:23 +0000</pubDate>
      <link>https://dev.to/kotlin/how-i-built-an-asteroids-game-using-jetpack-compose-for-desktop-309l</link>
      <guid>https://dev.to/kotlin/how-i-built-an-asteroids-game-using-jetpack-compose-for-desktop-309l</guid>
      <description>&lt;p&gt;A while ago, I tweeted about a small game I had created on top of &lt;a href="https://www.jetbrains.com/lp/compose/"&gt;&lt;strong&gt;Jetpack Compose for Desktop&lt;/strong&gt;&lt;/a&gt;: A small clone of the &lt;strong&gt;classic arcade game&lt;/strong&gt; &lt;a href="https://en.wikipedia.org/wiki/Asteroids_(video_game)"&gt;&lt;strong&gt;Asteroids&lt;/strong&gt;&lt;/a&gt;, in which you control a space ship with your mouse, and navigate the vastness of space, avoiding and breaking asteroids in the process.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1382668779377762305-462" src="https://platform.twitter.com/embed/Tweet.html?id=1382668779377762305"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1382668779377762305-462');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1382668779377762305&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Today, it's time to take a look under the hood and understand how I built a basic version of this game, and how &lt;strong&gt;Compose for Desktop helped me achieve it in just one evening&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;We will take a look at parts and structures in the code that I find the most interesting. To see how it all fits together, I suggest exploring the &lt;a href="https://github.com/SebastianAigner/asteroids-compose-for-desktop"&gt;&lt;strong&gt;whole code on GitHub&lt;/strong&gt;&lt;/a&gt;. The whole implementation is &lt;strong&gt;only 300 lines of code&lt;/strong&gt;, which I hope makes studying and understanding it easy.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Game
&lt;/h3&gt;

&lt;p&gt;If you're not caught up on your 80s arcade trivia, &lt;a href="https://en.wikipedia.org/wiki/Asteroids_(video_game)"&gt;Asteroids&lt;/a&gt; was a  popular arcade game where you try to steer your space ship through space, avoiding and destroying asteroids with your ship.&lt;/p&gt;

&lt;p&gt;Because of the limitations of the hardware at the time, the game is quite simplistic in appearance: a triangular spaceship moves across a plain background and avoids simple displays of asteroids on a 2D surface.&lt;/p&gt;

&lt;p&gt;What makes this a challenge is the &lt;em&gt;interia&lt;/em&gt;: Just like a real space ship, your spaceship moves along its course in a straight line at constant speed, and you need to make corrective maneuvers by turning your ship and directing your thrust.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Asteroids has achieved cult status in the arcade game scene.&lt;/strong&gt; Because of that, I wanted to see what it would take to recreate this experience using Jetpack Compose for Desktop!&lt;/p&gt;

&lt;h3&gt;
  
  
  The Building Blocks
&lt;/h3&gt;

&lt;p&gt;I have roughly divided the project into a few building blocks that make up the project, and that we will talk about. Namely, those are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Game Loop&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Game State Management&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rendering to the Screen&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the &lt;strong&gt;&lt;a href="https://dev.to/kotlin/tips-tricks-for-building-a-game-using-jetpack-compose-for-desktop-266o"&gt;second part&lt;/a&gt;&lt;/strong&gt; of this series on building a game with Compose for Desktop, we will also look at additional &lt;strong&gt;rendering details&lt;/strong&gt;, the &lt;strong&gt;geometry and linear algebra&lt;/strong&gt; behind the game, and &lt;strong&gt;frame-independent movement&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's dive right in!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Game Loop &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;At the center of most games stands the &lt;strong&gt;game loop&lt;/strong&gt;. It acts as the &lt;strong&gt;entry point&lt;/strong&gt; that calls the game logic code. This is a fundamental difference between implementing typical declarative user interfaces and building games:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Declarative UI&lt;/strong&gt; is usually mostly static, and reacts to user actions (clicking, dragging) or other events (new data, computation progress...)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Games&lt;/strong&gt; run their logic many times per second, simulating the game world and its entities one frame at a time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is not to say that these two approaches are incompatible! All we need to run a main "game loop" is to get our &lt;strong&gt;function to execute&lt;/strong&gt; once per frame. In Jetpack Compose, we have the &lt;code&gt;withFrame&lt;/code&gt; family of functions (&lt;code&gt;withFrameMillis&lt;/code&gt;, &lt;code&gt;withFrameNanos&lt;/code&gt;), which can help us achieve exactly that.&lt;/p&gt;

&lt;p&gt;Let's assume we already have a &lt;code&gt;game&lt;/code&gt; object – we will talk about state management shortly. We can then create a &lt;code&gt;LaunchedEffect&lt;/code&gt; which asks Jetpack Compose for Desktop to &lt;strong&gt;call our &lt;code&gt;update&lt;/code&gt; function whenever a new frame is rendered&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;LaunchedEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;withFrameNanos&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;withFrameNanos&lt;/code&gt; is a suspending method. Its exact implementation is described in the &lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary#withframemillis"&gt;documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;withFrameNanos&lt;/code&gt; suspends until a new frame is requested, immediately invokes &lt;code&gt;onFrame&lt;/code&gt; with the frame time in nanoseconds in the calling context of frame dispatch, then resumes with the result from &lt;code&gt;onFrame&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The frame time, which it provides us with, will also come in handy, as we will see in the &lt;a href="https://dev.to/kotlin/tips-tricks-for-building-a-game-using-jetpack-compose-for-desktop-266o"&gt;second part&lt;/a&gt; of this blog post series, when we talk about &lt;em&gt;frame-independent movement&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Game State Management &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Jetpack Compose is excellent at managing state&lt;/strong&gt;, and when building a game like Asteroids, we can use the same mechanisms to keep track of the data attached to game objects or the current play session, to name just two examples.&lt;/p&gt;

&lt;p&gt;As suggested in the previous section, my Asteroids game has a &lt;code&gt;Game&lt;/code&gt; class, an instance of which is wrapped in a &lt;code&gt;remember&lt;/code&gt; call in the main composition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;game&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;remember&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It acts as a container for all game-related data. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Game object information (in a &lt;code&gt;mutableStateListOf&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The current game phase (&lt;code&gt;RUNNING&lt;/code&gt; / &lt;code&gt;STOPPED&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The size of the playing field (based on window dimensions)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Inside the &lt;code&gt;Game&lt;/code&gt; object, we treat the state data as mutable, and make any state changes as we see fit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Game Objects
&lt;/h3&gt;

&lt;p&gt;Individual game objects once again group the state belonging to an individual game entity: a spaceship, an asteroid, or a bullet, and provide methods to modify their state, spawn new game objects, or check their relation to other game objects.&lt;/p&gt;

&lt;p&gt;In my implementation of Asteroids, all game objects share a lot of behavior, from the way they move through the environment to how they check their collision – we'll talk about the geometry and linear algebra that goes into that a bit later.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;GameObject&lt;/code&gt; class provides implementations for these shared behaviors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GameObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Vector2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Vector2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ZERO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;speed&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;mutableStateOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;angle&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;mutableStateOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;position&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;mutableStateOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;movementVector&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;realDelta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;velocity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;movementVector&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;realDelta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toDouble&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;velocity&lt;/span&gt;
        &lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Vector2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toDouble&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toDouble&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;overlapsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;GameObject&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;distanceTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, the &lt;code&gt;ShipData&lt;/code&gt; class inherits &lt;code&gt;speed&lt;/code&gt;, &lt;code&gt;angle&lt;/code&gt;, &lt;code&gt;position&lt;/code&gt; and its &lt;code&gt;update&lt;/code&gt; method from &lt;code&gt;GameObject&lt;/code&gt;, but defines its own size, angle, and a function to fire a bullet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShipData&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;GameObject&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;40.0&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;visualAngle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;ship&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;
        &lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gameObjects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BulletData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ship&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;speed&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ship&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visualAngle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ship&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the &lt;code&gt;ShipData&lt;/code&gt; (or even a &lt;code&gt;GameObject&lt;/code&gt; in general) does not include any logic on how to render this item to the display – &lt;strong&gt;with Jetpack Compose, keeping state and presentation separated is quite easy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because a lot of behavior is shared between all types of entities in the game, our main game loop can treat them as the supertype &lt;code&gt;GameObject&lt;/code&gt; for the most part, and only specific interactions between certain types of objects, like bullet-asteroid or asteroid-player collisions, need to be handled specifically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rendering to the Screen &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I found that in Jetpack Compose, &lt;strong&gt;separating game data from the visual representation comes quite naturally&lt;/strong&gt;. Game objects like a ship, an asteroid, or a bullet are all represented in two parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A class holding the state associated with the game object (in terms of "Compose state" – via &lt;code&gt;mutableStateOf&lt;/code&gt; and friends) – We briefly talked about this in the previous section.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;@Composable&lt;/code&gt;, defining the rendering based on the game object's data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To illustrate the latter, here's the minimal visual representation of the &lt;code&gt;Asteroid&lt;/code&gt; composable. It receives &lt;code&gt;asteroidData&lt;/code&gt;, which is the container for all information regarding the state of this particular game object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Composable&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;Asteroid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asteroidData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AsteroidData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;asteroidSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;asteroidData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt;
    &lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;Modifier&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asteroidData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xOffset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;asteroidData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yOffset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asteroidSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asteroidData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFloat&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CircleShape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;153&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code snippet is enough to &lt;strong&gt;describe the whole visual representation&lt;/strong&gt; of an asteroid.&lt;/p&gt;

&lt;p&gt;We start with a &lt;a href="https://developer.android.com/jetpack/compose/layout"&gt;&lt;code&gt;Box&lt;/code&gt;&lt;/a&gt; – one of Compose's most basic layout primitives, which allows us to have entities overlap (which is useful since we manually take care of placing the individual entities). We then use Jetpack Compose's &lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier"&gt;&lt;code&gt;Modifier&lt;/code&gt;s&lt;/a&gt; to specify the position of the asteroid in the form of an &lt;code&gt;offset&lt;/code&gt;, its size, rotation angle, shape (by clipping a &lt;code&gt;CircleShape&lt;/code&gt;), and background color.&lt;/p&gt;

&lt;p&gt;Note that Compose offers quite &lt;strong&gt;high-level APIs even for these basic shapes&lt;/strong&gt; – for example, we can use &lt;code&gt;.rotate&lt;/code&gt; directly, without having to manually do geometry work to figure out how to get our entities facing the right way.&lt;/p&gt;

&lt;p&gt;To keep this snippet as concise as possible, I've also introduced some extension functions on &lt;code&gt;GameObject&lt;/code&gt; that make it possible to reuse the logic of computing the offset of a game object based on its position and size, called &lt;code&gt;xOffset&lt;/code&gt; and &lt;code&gt;yOffset&lt;/code&gt;, which I've snuck into the previous code snippet already. Their implementation is relatively straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;GameObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xOffset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Dp&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;GameObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yOffset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Dp&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A slightly more complicated composable would be the &lt;code&gt;Ship&lt;/code&gt; component, which combines the shapes of a triangle and circle to create a minimalistic spaceship:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Composable&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;Ship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shipData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ShipData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;shipSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;shipData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt;
    &lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;Modifier&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shipData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xOffset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shipData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yOffset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shipSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shipData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visualAngle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFloat&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CircleShape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Black&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Canvas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxSize&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;onDraw&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;drawPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;White&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;shipSize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toPx&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="nf"&gt;moveTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Top-left corner...&lt;/span&gt;
                    &lt;span class="nf"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ...to right-center...&lt;/span&gt;
                    &lt;span class="nf"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ... to bottom-left corner.&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Box&lt;/code&gt; defining the ship is quite similar to the one we saw for an &lt;code&gt;Asteroid&lt;/code&gt;, but we additionally add a &lt;code&gt;Canvas&lt;/code&gt; to draw some additional shapes on top of our spaceship – in this case, a triangle path. In typical Compose fashion, we just add this &lt;code&gt;Canvas&lt;/code&gt; in the lambda block following our &lt;code&gt;Box&lt;/code&gt;, meaning the &lt;code&gt;Canvas&lt;/code&gt; will inhert the coordinate system of its parent, including its offset and rotation.&lt;/p&gt;

&lt;p&gt;These composables are then just rendered to a &lt;em&gt;play surface&lt;/em&gt; – nothing more than a &lt;code&gt;Box&lt;/code&gt; with a locked aspect ratio of &lt;code&gt;1.0f&lt;/code&gt; (to keep it quadratic). Of course, applying some artistic talent to these visual representations of the game is also possible, but we're keeping it minimal for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continued in Part 2
&lt;/h2&gt;

&lt;p&gt;There's still a bit more work to do until we can call our game done. In part 2 of this blog post series, we will look at additional rendering details, the geometry and linear algebra behind the game's simple physics simulation, as well as frame-independent movement. &lt;strong&gt;&lt;a href="https://dev.to/kotlin/tips-tricks-for-building-a-game-using-jetpack-compose-for-desktop-266o"&gt;Read on and find out!&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>kotlin</category>
      <category>jetpackcompose</category>
      <category>android</category>
    </item>
    <item>
      <title>Why Learn Kotlin?</title>
      <dc:creator>Sebastian Aigner</dc:creator>
      <pubDate>Wed, 28 Apr 2021 18:00:55 +0000</pubDate>
      <link>https://dev.to/kotlin/why-learn-kotlin-358n</link>
      <guid>https://dev.to/kotlin/why-learn-kotlin-358n</guid>
      <description>&lt;p&gt;&lt;em&gt;Ksenia Shneyveys, Kotlin Marketing Manager for Education, shares insights on how and why to get started with the Kotlin programming language&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We would love to hear about your own motivations for learning Kotlin by &lt;a href="https://blog.jetbrains.com/kotlin/2021/04/why-learn-kotlin/"&gt;leaving your story on our official blog!&lt;/a&gt; If you share your story with us, you will also have the chance to win an “&lt;a href="https://leanpub.com/AtomicKotlin"&gt;Atomic Kotlin&lt;/a&gt;” ebook!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Kotlin has always been and continues to be a modern language in the industry, addressing the real needs of real developers. It is increasingly being adopted in many trending fields, including &lt;a href="https://kotlinlang.org/lp/mobile/"&gt;mobile&lt;/a&gt;, &lt;a href="https://kotlinlang.org/docs/js-overview.html"&gt;web&lt;/a&gt;, &lt;a href="https://kotlinlang.org/lp/server-side/"&gt;server-side&lt;/a&gt; and cloud development, &lt;a href="https://kotlinlang.org/docs/data-science-overview.html"&gt;data science&lt;/a&gt;, and &lt;a href="https://kotlinlang.org/education/"&gt;education&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This all gives a strong indication that there is already significant demand for Kotlin developers and there will continue to be in the future.&lt;/p&gt;

&lt;p&gt;So where can you start learning this skill? “&lt;a href="https://leanpub.com/AtomicKotlin"&gt;Atomic Kotlin&lt;/a&gt;”!&lt;/p&gt;

&lt;p&gt;This book is suited for Kotlin learners of all levels, and it is available in print and as an ebook. It breaks Kotlin programming language concepts into atoms, and provides hands-on exercises inside IntelliJ IDEA.&lt;/p&gt;

&lt;p&gt;To celebrate the recent release of “Atomic Kotlin”, we asked our &lt;a href="https://twitter.com/kotlin"&gt;Twitter&lt;/a&gt; community to share their motivation for learning Kotlin. You all did not disappoint! There were a lot of great responses from the community, and we saw a couple of patterns emerging. In this post, we are going to share with you some of the answers people gave about why Kotlin is a great language to learn.&lt;/p&gt;

&lt;p&gt;&lt;a title="Buy your copy" href="https://leanpub.com/AtomicKotlin"&gt;Buy your copy&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Modern Language
&lt;/h2&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;&lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt; &lt;br&gt;I love Kotlin because it is clean, logical, safe, fast, modern, flexible, intuitive, versatile, and sits on the shoulder of the Java giant.&lt;/p&gt;— Jan Meww (@JanMeww) &lt;a href="https://twitter.com/JanMeww/status/1367028610335399937?ref_src=twsrc%5Etfw"&gt;March 3, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;&lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt; I want to learn more about Kotlin because of the modern syntax and some new ideas (e.g. coroutines) it brings to the current Java Web Development. Have tried it for some weeks and has been a bliss!!!&lt;/p&gt;— Fabio Salas (&lt;a class="mentioned-user" href="https://dev.to/fabiosalasm"&gt;@fabiosalasm&lt;/a&gt;) &lt;a href="https://twitter.com/fabiosalasm/status/1366842511306723333?ref_src=twsrc%5Etfw"&gt;March 2, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kotlin is a modern programming language that combines all the best bits of imperative, object-oriented, and functional programming. It is general-purpose and multi-paradigm, and conciseness and safety are some of the language's key features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Easy to Learn
&lt;/h2&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;Why I want to learn Kotlin? well..You don’t come across a language that often which is as elegant and easy to learn like Kotlin. To put icing on the cake it can coexist with your Java ecosystems as well ..what more can you ask &lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt;&lt;/p&gt;— Nirmal (@thooskoo) &lt;a href="https://twitter.com/thooskoo/status/1371518867281956866?ref_src=twsrc%5Etfw"&gt;March 15, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://kotlinlang.org/docs/basic-syntax.html"&gt;Kotlin’s syntax&lt;/a&gt; is simple to grasp for beginners, while at the same time, the language offers sophisticated powerful features for experienced programmers.&lt;/p&gt;

&lt;p&gt;Kotlin can build on the learners’ previous programming experience. It is simple to grasp for those with a Java or Python background. Kotlin’s syntax is also easy to learn for iOS developers because it is based on the same modern concepts they are already familiar with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Great Materials
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I have gone through the sample of Atomic kotlin book, solved exercises from github repo. It's truely awesome &amp;amp; I want to learn the whole content. I want to use only one language to most of my application development to ship it to different platform - Kotlin &lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt;&lt;/p&gt;— Kalaiselvan (@kalaiselvan369) &lt;a href="https://twitter.com/kalaiselvan369/status/1367862374200315906?ref_src=twsrc%5Etfw"&gt;March 5, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is a lot of up-to-date material available to help you learn Kotlin. One of our favorite resources for learning Kotlin from scratch is “&lt;a href="https://leanpub.com/AtomicKotlin"&gt;Atomic Kotlin&lt;/a&gt;”. Readers can see their progress while solving the tasks that are checked automatically within &lt;a href="https://www.jetbrains.com/edu-products/download/#section=idea"&gt;IntelliJ IDEA&lt;/a&gt;. There are hints and solutions to help them out if they get stuck. All the examples in "Atomic Kotlin" are available in this &lt;a href="https://github.com/BruceEckel/AtomicKotlinExamples"&gt;GitHub repository&lt;/a&gt;. You can compile, run, and test the examples which are automatically extracted directly from the book.&lt;/p&gt;

&lt;p&gt;&lt;a title="Buy your copy" href="https://leanpub.com/AtomicKotlin"&gt;Buy your copy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can learn what the authors of "Atomic Kotlin", &lt;a href="https://www.mindviewllc.com/"&gt;Bruce Eckel&lt;/a&gt; and Svetlana Isakova, think about learning the language in this episode of the JetBrains Connect series. In it, they discuss the question of why to learn Kotlin, with host Paul Everitt:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/0V-qp-qpjzU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiplatform
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt; &lt;br&gt;&lt;br&gt;Want to learn Kotlin since I want to be a multi platform developer &amp;amp; focus more on building the product in different platforms rather than on learning different languages. I believe Kotlin would give me feathers to fly between platforms &amp;amp; reach my true potential.&lt;/p&gt;— jplus (@jplus62611121) &lt;a href="https://twitter.com/jplus62611121/status/1371451253377486859?ref_src=twsrc%5Etfw"&gt;March 15, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;I'm a Ruby developer but want to learn Kotlin as my next language because it have all signs of a modern and concise programming language and it reads well too, which is important. I can build various things with it starting from API to fully-fledged Android app. Fun &lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt;&lt;/p&gt;— Костромицкий Денис (&lt;a class="mentioned-user" href="https://dev.to/mojobiri"&gt;@mojobiri&lt;/a&gt;) &lt;a href="https://twitter.com/mojobiri/status/1367405922864271362?ref_src=twsrc%5Etfw"&gt;March 4, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a language that supports multiplatform targets, you can run Kotlin on virtually any device these days, be it a PC or a Mac, and also as native code. This means you can build mobile, web frontend, and backend applications with Kotlin as well.&lt;/p&gt;

&lt;p&gt;In addition to being the official language for Android development, Kotlin is a proven technology for building cross-platform mobile applications. It eliminates all the disadvantages of other leading approaches and lets you create mobile apps with native performance and UIs while sharing the business logic completely. Visit the &lt;a href="https://kotlinlang.org/lp/mobile/"&gt;Kotlin Multiplatform Mobile portal&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Progression from Java
&lt;/h2&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;I really like the JVM, and I already know some Kotlin, but I would definitely like to learn more and get better at it, and learn more about the JVM too. Kotlin combines a lot of features from languages that I really like. &lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt;&lt;/p&gt;— Moiré (@Moire9_) &lt;a href="https://twitter.com/Moire9_/status/1367544838569160714?ref_src=twsrc%5Etfw"&gt;March 4, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;Because I’m finishing my studies which were heavily focused on Java and I just started a job in which I use Kotlin every day. No reason not to exceed the expectations! &lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt;&lt;/p&gt;— Bartosz Rogowski (@rogowskibart) &lt;a href="https://twitter.com/rogowskibart/status/1370813212086706177?ref_src=twsrc%5Etfw"&gt;March 13, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;&lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt;&lt;br&gt;Because I want to write Kotlin, not Java with Kotlin syntax. Currently coding together with Spring and I love it.&lt;/p&gt;— MeSmash (@MeSmash3) &lt;a href="https://twitter.com/MeSmash3/status/1366829146777792525?ref_src=twsrc%5Etfw"&gt;March 2, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kotlin’s interoperability allows it to be introduced seamlessly anywhere you’re already using Java. Kotlin fixes some of the issues Java suffers from and has some features that are absent from Java.&lt;/p&gt;

&lt;h2&gt;
  
  
  Career prospects
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;As a self-learner, I started with a couple of Java courses in December. Since then I've been pursuing Kotlin and have been engaged in learning the Kotlin ecosystem to land my first dev job! Having material to build on my foundation of the language will be impactful! &lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt;&lt;/p&gt;— Bryan (@Lidberg_B) &lt;a href="https://twitter.com/Lidberg_B/status/1370850705251180552?ref_src=twsrc%5Etfw"&gt;March 13, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;Knowing, cOncise, pragmaTic, Legible, sImple, perfomiNg... &lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt;&lt;br&gt;My learning with these features will make my career grow and my university dream came true through this language.&lt;/p&gt;— Miguel Paulista (@mikePaulista_13) &lt;a href="https://twitter.com/mikePaulista_13/status/1369329285656350723?ref_src=twsrc%5Etfw"&gt;March 9, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://kotlinlang.org/#usage-highlights"&gt;Many great companies&lt;/a&gt; already use Kotlin to build their products, and Kotlin skills are increasingly in demand as more and more businesses are adopting the language. Indeed, the number of Kotlin job postings has skyrocketed by 1400% since 2017 (Source: &lt;a href="https://insights.dice.com/2019/06/24/kotlin-how-why-tech-professionals-use-it/"&gt;Dice&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Community Driven
&lt;/h2&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;&lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt; Kotlin is a community driven language and they give great importance for the feedback from devs. I feel good to be invested in such Lang and I believe it has a great future!&lt;/p&gt;—     (@GopalAkshintala) &lt;a href="https://twitter.com/GopalAkshintala/status/1366948847881101315?ref_src=twsrc%5Etfw"&gt;March 3, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;Because I'm believing in Kotlin Team and their works(books, features, libraries and everything made by Kotlin)&lt;a href="https://twitter.com/hashtag/atomickotlin?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#atomickotlin&lt;/a&gt;&lt;/p&gt;— Hamza GATTAL (@hmzgtl05) &lt;a href="https://twitter.com/hmzgtl05/status/1370832650429202434?ref_src=twsrc%5Etfw"&gt;March 13, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since its very beginning in 2011, Kotlin has been developed as an open-source language.&lt;/p&gt;

&lt;p&gt;Kotlin evolves with the help of our &lt;a href="https://kotlinlang.org/community/"&gt;diverse community&lt;/a&gt;, which includes almost &lt;a href="https://kotlinlang.org/user-groups/user-group-list.html"&gt;200 Kotlin User Groups&lt;/a&gt;, 37K+ &lt;a href="https://surveys.jetbrains.com/s3/kotlin-slack-sign-up"&gt;Kotlinlang Slack&lt;/a&gt; users, and countless other members spread across our &lt;a href="https://discuss.kotlinlang.org/"&gt;forum&lt;/a&gt;, our &lt;a href="https://www.reddit.com/r/Kotlin/"&gt;sub-Reddit&lt;/a&gt;, &lt;a href="https://www.youtube.com/channel/UCP7uiEZIqci43m22KDl0sNw"&gt;YouTube&lt;/a&gt;, &lt;a href="https://twitter.com/kotlin"&gt;Twitter&lt;/a&gt;, and many other platforms. Over 450 contributors are working on Kotlin, including 90 JetBrains developers.&lt;/p&gt;

&lt;p&gt;Your feedback provides the basis for &lt;a href="https://kotlinlang.org/docs/roadmap.html"&gt;our roadmap&lt;/a&gt;. Thank you for your continued support!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did you Learn Kotlin?
&lt;/h2&gt;

&lt;p&gt;If you haven’t already taken up Kotlin, we hope that this post has left you feeling inspired to do so. We would love to hear about your own motivations for learning Kotlin by &lt;a href="https://blog.jetbrains.com/kotlin/2021/04/why-learn-kotlin/"&gt;leaving your story on our official blog!&lt;/a&gt; If you share your story with us, you will also have the chance to win an “&lt;a href="https://leanpub.com/AtomicKotlin"&gt;Atomic Kotlin&lt;/a&gt;” ebook!&lt;/p&gt;

&lt;p&gt;We’ll select 5 winners from the commenters on &lt;a href="https://blog.jetbrains.com/kotlin/2021/04/why-learn-kotlin/"&gt;blog.jetbrains.com&lt;/a&gt; on May 12.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>programming</category>
      <category>beginners</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Diving into Kotlin collections</title>
      <dc:creator>Sebastian Aigner</dc:creator>
      <pubDate>Mon, 29 Mar 2021 18:00:41 +0000</pubDate>
      <link>https://dev.to/kotlin/diving-into-kotlin-collections-587o</link>
      <guid>https://dev.to/kotlin/diving-into-kotlin-collections-587o</guid>
      <description>&lt;p&gt;This blog post accompanies a video from our &lt;strong&gt;YouTube series&lt;/strong&gt; which you can find on our &lt;a href="https://kotl.in/video" rel="noopener noreferrer"&gt;Kotlin YouTube channel&lt;/a&gt;, or &lt;strong&gt;watch here&lt;/strong&gt; directly!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/F8jj7e-_jFA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kotlinlang.org/docs/collections-overview.html" rel="noopener noreferrer"&gt;Kotlin Collections&lt;/a&gt;! You’ve heard of them, you’ve used them – so it makes sense to learn even more about them! Kotlin's standard library provides &lt;strong&gt;awesome tools to manage groups of items&lt;/strong&gt;, and we’re going to take a closer look!&lt;/p&gt;

&lt;p&gt;Let's see &lt;strong&gt;what types of collections&lt;/strong&gt; the Kotlin standard library offers, and explore a &lt;strong&gt;common subset of operations&lt;/strong&gt; that’s available for all of the collections you get in the standard library. Let’s get started.&lt;/p&gt;

&lt;p&gt;In the Kotlin standard library, we have three big types of collections: &lt;strong&gt;Lists&lt;/strong&gt;, &lt;strong&gt;Sets&lt;/strong&gt;, and &lt;strong&gt;Maps&lt;/strong&gt;. Just like many other parts of the standard library, these &lt;strong&gt;collections are available anywhere you can write Kotlin&lt;/strong&gt;: on the JVM, but also in Kotlin/Native, Kotlin/JS, and common Kotlin code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lists
&lt;/h2&gt;

&lt;p&gt;Let’s start with the &lt;strong&gt;most popular candidate&lt;/strong&gt; of a collection in Kotlin: a &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/" rel="noopener noreferrer"&gt;&lt;code&gt;List&lt;/code&gt;&lt;/a&gt;. To rehearse:&lt;/p&gt;

&lt;p&gt;A list is a collection of &lt;strong&gt;ordered elements&lt;/strong&gt;. That means that you can access the elements of a list using &lt;strong&gt;indices&lt;/strong&gt; – so you can say “give me the element at position two”. There’s also &lt;strong&gt;no constraints on duplicate elements&lt;/strong&gt; in our list. We can just put in whatever elements we’d like. So, very few constraints on content, and maximum versatility in how we access the elements!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;aList&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"Apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Banana"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Cherry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Apple"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;aList&lt;/span&gt; &lt;span class="c1"&gt;// [Apple, Banana, Cherry, Apple]&lt;/span&gt;

&lt;span class="n"&gt;aList&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// Banana&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sets
&lt;/h2&gt;

&lt;p&gt;Next up, we have the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-set/" rel="noopener noreferrer"&gt;&lt;code&gt;Set&lt;/code&gt;&lt;/a&gt;! Sets are groups of objects where we don’t care about the order of elements. Instead, we want to make sure that our collection &lt;strong&gt;never contains any duplicates&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s the key property of a set: all of its &lt;strong&gt;contents are unique&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That makes sets a bit more of a specialized data structure, but there’s a good chance you want to use them in everyday scenarios anyway.&lt;/p&gt;

&lt;p&gt;What are &lt;strong&gt;typical things&lt;/strong&gt; you might want to store in a set? Tags, for example. Or, maybe you’re building a social network, and you want to store the IDs of all the friends that a certain user has. In both cases, you don't want to have duplicates in these collections, and probably don't care about the order.&lt;/p&gt;

&lt;p&gt;A set can help you &lt;strong&gt;enforce these constraints&lt;/strong&gt; without having to really think about it, and &lt;strong&gt;without manual duplication checks&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;emotions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"Happy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Curious"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Joyful"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Happy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// even if we try to add duplicates...&lt;/span&gt;
    &lt;span class="s"&gt;"Joyful"&lt;/span&gt; &lt;span class="c1"&gt;// ...to our set...&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emotions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ...the elements in our set stay unique!&lt;/span&gt;
&lt;span class="c1"&gt;// [Happy, Curious, Joyful]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sets are actually also a &lt;strong&gt;common mathematical abstraction&lt;/strong&gt;. Typical mathematical concepts, like &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/union.html" rel="noopener noreferrer"&gt;unions&lt;/a&gt;, &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/intersect.html" rel="noopener noreferrer"&gt;intersections&lt;/a&gt;, or the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/subtract.html" rel="noopener noreferrer"&gt;set difference&lt;/a&gt; also translate neatly into Kotlin code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maps
&lt;/h2&gt;

&lt;p&gt;Last, but certainly not least, we have &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/" rel="noopener noreferrer"&gt;&lt;code&gt;Map&lt;/code&gt;&lt;/a&gt;. A map is a &lt;strong&gt;set of key-value pairs&lt;/strong&gt;, where &lt;strong&gt;each key is unique&lt;/strong&gt;. It’s also sometimes called a “dictionary” for that reason. You encounter maps whenever you’re &lt;strong&gt;associating data&lt;/strong&gt; – storing a persons name and their favorite pizza topping, or associating a license plate with vehicle information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;peopleToPizzaToppings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mapOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="s"&gt;"Ken"&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"Pineapple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s"&gt;"Lou"&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"Peperoni"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s"&gt;"Ash"&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"Ketchup"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peopleToPizzaToppings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// {Ken=Pineapple, Lou=Peperoni, Ash=Ketchup}&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Ash"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="c1"&gt;// Ketchup&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key-value pairs are everywhere, and just like in many other languages, maps are the go-to way to manage them in Kotlin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Collections can be mutable
&lt;/h2&gt;

&lt;p&gt;By default, these collections in Kotlin are &lt;strong&gt;read-only&lt;/strong&gt;. This is in the spirit of &lt;strong&gt;immutability&lt;/strong&gt; which accompanies typical functional paradigms – instead of changing the contents of a collection, you create a new collection with the changes applied, which you can then &lt;strong&gt;safely pass around&lt;/strong&gt; in your application, ensuring that the &lt;strong&gt;original collection stays unchanged&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3avccfflc4ugw7l0xykt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3avccfflc4ugw7l0xykt.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But we also have &lt;strong&gt;mutable flavors&lt;/strong&gt; of all of the collections in Kotlin: we have &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/" rel="noopener noreferrer"&gt;&lt;code&gt;MutableList&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-set/" rel="noopener noreferrer"&gt;&lt;code&gt;MutableSet&lt;/code&gt;&lt;/a&gt;, and &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-map/" rel="noopener noreferrer"&gt;&lt;code&gt;MutableMap&lt;/code&gt;&lt;/a&gt;. Those are modifiable, meaning you can &lt;strong&gt;comfortably add and remove elements&lt;/strong&gt;. With data where you’re inherently expecting change, you’d probably use these mutable variants.&lt;/p&gt;

&lt;h2&gt;
  
  
  Collections are iterable
&lt;/h2&gt;

&lt;p&gt;Kotlin collections being &lt;em&gt;iterable&lt;/em&gt; means that the standard library provides a &lt;strong&gt;common, standardized set of typical operations for collections&lt;/strong&gt;, for example, to retrieve their size, check if they contain a certain item, and more.&lt;/p&gt;

&lt;p&gt;Lists and sets directly implement the Collection interface, which in turn implements the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-iterable/" rel="noopener noreferrer"&gt;&lt;code&gt;Iterable&lt;/code&gt;&lt;/a&gt; interface. Maps have an &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/iterator.html" rel="noopener noreferrer"&gt;&lt;code&gt;iterator()&lt;/code&gt;&lt;/a&gt; operator function, and provide iterable properties, like their set of keys, their list of values, as well as the entries of the map, so key-value pairs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh7j7a868lyz9dowlwnrn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh7j7a868lyz9dowlwnrn.png" alt="image"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Let’s learn about some &lt;strong&gt;shared functionality of iterables&lt;/strong&gt;. The following examples are going to use a list, but really, we can just assume that we’re just working with an &lt;code&gt;Iterable&lt;/code&gt; here – the concrete implementation does not matter. Also, all the functions discussed &lt;strong&gt;leave the original collection unchanged&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looping over collections
&lt;/h2&gt;

&lt;p&gt;A core function of an &lt;code&gt;Iterable&lt;/code&gt;, as its name suggests, is that it provides a mechanism to &lt;strong&gt;access the elements&lt;/strong&gt; that our collection contains, one after the other – to iterate it.&lt;/p&gt;

&lt;p&gt;The easiest way to go through all the elements in a collection is the basic Kotlin &lt;a href="https://kotlinlang.org/docs/control-flow.html#for-loops" rel="noopener noreferrer"&gt;&lt;code&gt;for&lt;/code&gt;&lt;/a&gt; loop. When we use the &lt;code&gt;for&lt;/code&gt; loop with an &lt;code&gt;Iterable&lt;/code&gt;, the &lt;code&gt;in&lt;/code&gt; operator cleverly understands that we want to &lt;strong&gt;go over the iterator&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fruits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"Apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Banana"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Cherry"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Apple&lt;/span&gt;
&lt;span class="c1"&gt;// Banana&lt;/span&gt;
&lt;span class="c1"&gt;// Cherry&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a &lt;strong&gt;more functional style&lt;/strong&gt;, we can also write this same snippet using the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/for-each.html" rel="noopener noreferrer"&gt;&lt;code&gt;forEach&lt;/code&gt;&lt;/a&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fruit&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Apple&lt;/span&gt;
&lt;span class="c1"&gt;// Banana&lt;/span&gt;
&lt;span class="c1"&gt;// Cherry&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, &lt;code&gt;forEach&lt;/code&gt; takes every element from our collection, and &lt;strong&gt;calls a function&lt;/strong&gt; (which we provide) with the element as its argument.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transforming collections: map
&lt;/h2&gt;

&lt;p&gt;Let's continue with a classic when it comes to &lt;strong&gt;transforming collections&lt;/strong&gt;: the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map.html" rel="noopener noreferrer"&gt;&lt;code&gt;map&lt;/code&gt;&lt;/a&gt; function! (Don’t be confused! The &lt;code&gt;map&lt;/code&gt; function has nothing to do with the &lt;code&gt;Map&lt;/code&gt; collection type. You can treat them as two completely different things.)&lt;/p&gt;

&lt;p&gt;Just like the &lt;code&gt;forEach&lt;/code&gt; function, the &lt;code&gt;map&lt;/code&gt; function is of &lt;a href="https://kotlinlang.org/docs/lambdas.html" rel="noopener noreferrer"&gt;higher order&lt;/a&gt;. So, it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Takes each element&lt;/strong&gt; from our collection, &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;applies a function&lt;/strong&gt; to it, and&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;creates another collection&lt;/strong&gt;, containing the return values of those function applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result of the map function doesn’t have to be the same type as the one of our input collection, either.&lt;/p&gt;

&lt;p&gt;This makes the &lt;code&gt;map&lt;/code&gt; function &lt;strong&gt;very versatile&lt;/strong&gt; – whether you want to parse a collection of strings into a collection of integers, or resolve a list of user names to a list of full user profiles –– if you’re &lt;strong&gt;transforming one collection into another&lt;/strong&gt;, it’s probably a good &lt;strong&gt;first instinct&lt;/strong&gt; to think &lt;code&gt;map&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fruits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"Apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Banana"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Cherry"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;stiurf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reversed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, you might have a transformation inside your &lt;code&gt;map&lt;/code&gt; function where you &lt;strong&gt;can’t generate valid results&lt;/strong&gt; for all input elements. In this case, we can use the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map-not-null.html" rel="noopener noreferrer"&gt;&lt;code&gt;mapNotNull&lt;/code&gt;&lt;/a&gt; function, and our resulting collection will only contain those function results that &lt;strong&gt;evaluated to an actual value&lt;/strong&gt;. This also ensures that type of our resulting variable is &lt;strong&gt;non-nullable&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;strs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"three"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"V"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mapNotNull&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toIntOrNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 2, 4] &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we need to &lt;strong&gt;keep track of the index&lt;/strong&gt; of the element which we’re currently transforming, we can use the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map-indexed.html" rel="noopener noreferrer"&gt;&lt;code&gt;mapIndexed&lt;/code&gt;&lt;/a&gt; function. It’s quite similar in how it works, but in this case, we get &lt;strong&gt;two parameters in our transformation function&lt;/strong&gt;: the &lt;em&gt;index&lt;/em&gt; and the &lt;em&gt;value&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;rank&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"Gold"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Silver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Bronze"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;ranking&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mapIndexed&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="s"&gt;"$m ($idx)"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ranking&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="na"&gt;[Gold (0), Silver (1), Bronze (2)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Filtering collections: filter and partition
&lt;/h2&gt;

&lt;p&gt;If we have a collection, but we’re only interested in &lt;strong&gt;elements that fulfil a certain condition&lt;/strong&gt;, the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/filter.html" rel="noopener noreferrer"&gt;&lt;code&gt;filter&lt;/code&gt;&lt;/a&gt; function comes to the rescue!&lt;/p&gt;

&lt;p&gt;Just like the previous examples, &lt;code&gt;filter&lt;/code&gt; accepts &lt;strong&gt;another function as its parameter&lt;/strong&gt;. This time, instead of defining a transformation, we’re defining what you can call a &lt;strong&gt;predicate&lt;/strong&gt; here.&lt;/p&gt;

&lt;p&gt;A predicate is a function that takes a collection element and &lt;strong&gt;returns a boolean value&lt;/strong&gt;: &lt;code&gt;true&lt;/code&gt; means that the given element matches the predicate, &lt;code&gt;false&lt;/code&gt; means the opposite. So this predicate acts as the “&lt;strong&gt;doorman&lt;/strong&gt;” – if the value is &lt;code&gt;true&lt;/code&gt;, the collection item is let through to the result collection, otherwise, it is discarded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cyborg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;people&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Joe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Agatha"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Amber"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;Cyborg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Rob"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;discoVisitors&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;people&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;discoVisitors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [Agatha, Amber, Rob]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re testing a &lt;strong&gt;negative condition&lt;/strong&gt;, you can use the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/filter-not.html" rel="noopener noreferrer"&gt;&lt;code&gt;filterNot&lt;/code&gt;&lt;/a&gt; function instead, which behaves identically, but &lt;strong&gt;inverts the condition&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;students&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;people&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterNot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [Joe]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that both &lt;code&gt;filter&lt;/code&gt; and &lt;code&gt;filterNot&lt;/code&gt; &lt;strong&gt;discard elements&lt;/strong&gt; where the condition doesn’t match. But maybe we don’t want to discard the “other half” of elements, and instead we want to put those into a separate list. This is where the &lt;code&gt;partition&lt;/code&gt; function comes into play.&lt;/p&gt;

&lt;p&gt;By using &lt;code&gt;partition&lt;/code&gt;, we &lt;strong&gt;combine the powers&lt;/strong&gt; of &lt;code&gt;filter&lt;/code&gt; and &lt;code&gt;filterNot&lt;/code&gt;. It returns a &lt;strong&gt;pair of lists&lt;/strong&gt;, where the first list contains all the elements for which the predicate holds true, and the second contains all the elements that fail the test. So, in our doorman analogy, instead of sending people who fail the check away, we just send them to a different place. (Using parentheses, we can &lt;strong&gt;destructure&lt;/strong&gt; this pair of lists directly into two independent variables.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="py"&gt;adults&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;people&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;partition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adults&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [Agatha, Amber, Rob]&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [Joe]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re bringing a &lt;strong&gt;collection of nullable items&lt;/strong&gt; to the party, you can use the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/filter-not-null.html" rel="noopener noreferrer"&gt;&lt;code&gt;filterNotNull&lt;/code&gt;&lt;/a&gt; function which, as you may have guessed, &lt;strong&gt;automatically discards any elements that are &lt;code&gt;null&lt;/code&gt;&lt;/strong&gt;, and gives you a new collection with an adjusted, non-nullable type accordingly.&lt;/p&gt;

&lt;p&gt;Speaking of adjusting types – if your collection contains multiple elements from a type hierarchy, but you’re only interested in &lt;strong&gt;elements of a specific type&lt;/strong&gt;, you can use &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/filter-is-instance.html" rel="noopener noreferrer"&gt;&lt;code&gt;filterIsInstance&lt;/code&gt;&lt;/a&gt;, and specify the desired type as a generic parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;people&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Joe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Agatha"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Amber"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;Cyborg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Rob"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;actualPeople&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;people&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterNotNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actualPeople&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [Joe, Agatha, Amber, Rob]&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;cyborgs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;people&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filterIsInstance&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Cyborg&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cyborgs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [Rob]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Retrieve collection parts: take and drop
&lt;/h2&gt;

&lt;p&gt;Filtering allowed us to apply a predicate function, and create a new collection containing items that match. But what about the even simpler cases? Sometimes, we just want to &lt;strong&gt;grab a few elements&lt;/strong&gt; from our collection.&lt;/p&gt;

&lt;p&gt;For that, we have the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/take.html" rel="noopener noreferrer"&gt;&lt;code&gt;take&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/drop.html" rel="noopener noreferrer"&gt;&lt;code&gt;drop&lt;/code&gt;&lt;/a&gt; functions. You might already be able to guess what they do. &lt;code&gt;take&lt;/code&gt; gives you a &lt;strong&gt;collection of the first n elements&lt;/strong&gt; from your original collection. So &lt;code&gt;take(2)&lt;/code&gt; is going to give you the first two elements. On the opposite hand, &lt;code&gt;drop(3)&lt;/code&gt; is going to &lt;strong&gt;leave out the first three elements&lt;/strong&gt; of your original collection, and only gives you everything that follows after those three elements. And you don’t have to be afraid to “overdrop” either – dropping more elements from a collection than it contains just gives you an empty list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;objects&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🌱"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🚀"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"💡"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🐧"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"⚙️"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;seedlingAndRocket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seedlingAndRocket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [🌱, 🚀]&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;penguinAndGear&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;penguinAndGear&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [🐧, ⚙️]&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;nothing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nothing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// []&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// remember, the original collection is not modified!&lt;/span&gt;
&lt;span class="c1"&gt;// [🌱, 🚀, 💡, 🐧, ⚙️]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One huge benefit of the functions we’ve seen so far is their &lt;strong&gt;composability&lt;/strong&gt;: Because mapping, filtering, taking, dropping, and all their friends return a new collection, it’s easy to just take that result, and &lt;strong&gt;immediately use it as an argument for the next collection function&lt;/strong&gt;, turning collection into collection into collection.&lt;/p&gt;

&lt;p&gt;However, we should keep in mind that chaining a number of these functions together means we generate a bunch of &lt;strong&gt;intermediate collections&lt;/strong&gt;. Now, this isn’t going to set your computer on fire immediately, but it is still something to be aware of, especially when you work with very large collections. For this case, Kotlin has a few aces up its sleeve as well, called &lt;a href="https://kotlinlang.org/docs/sequences.html" rel="noopener noreferrer"&gt;sequences&lt;/a&gt;, but we will dive into those at a later point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aggregating collections: sums, averages, minimums, maximums, and counting
&lt;/h2&gt;

&lt;p&gt;Once we’re done transforming our data, we might want to get a &lt;strong&gt;single result value&lt;/strong&gt; out of it. If we have a collection of &lt;strong&gt;numerical values&lt;/strong&gt; like integers or doubles, we get some nice functions called &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/average.html" rel="noopener noreferrer"&gt;&lt;code&gt;average&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sum.html" rel="noopener noreferrer"&gt;&lt;code&gt;sum&lt;/code&gt;&lt;/a&gt; out of the box, which help us calculate those values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;randomNumbers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;randomNumbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;average&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;// 4.09090909090909091&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;randomNumbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;// 45&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In some situations (...or, we might say, &lt;em&gt;sum&lt;/em&gt; situations...), we have a collection of more &lt;strong&gt;complex objects&lt;/strong&gt;, and want to still &lt;strong&gt;add them up&lt;/strong&gt; somehow, based on their properties. Of course, we could first use the &lt;code&gt;map&lt;/code&gt; function to obtain a collection containing only numbers – but by using the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sum-of.html" rel="noopener noreferrer"&gt;&lt;code&gt;sumOf&lt;/code&gt;&lt;/a&gt; function, we can do all of this in a single function call: we can pass a function that acts as a &lt;strong&gt;selector&lt;/strong&gt; (so a function that gives us whatever number we want to associate with the element) and &lt;code&gt;sumOf&lt;/code&gt; will use the &lt;strong&gt;result of that selector function&lt;/strong&gt; to &lt;strong&gt;add up&lt;/strong&gt; all our elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;randomNames&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dallas"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Kane"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ripley"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Lambert"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;cumulativeLength&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;randomNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sumOf&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cumulativeLength&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// 23&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we’re only interested in the &lt;strong&gt;greatest or smallest value&lt;/strong&gt; contained in our collection of numbers, we can use the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/max-or-null.html" rel="noopener noreferrer"&gt;&lt;code&gt;maxOrNull&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/min-or-null.html" rel="noopener noreferrer"&gt;&lt;code&gt;minOrNull&lt;/code&gt;&lt;/a&gt; functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;randomNumbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;minOrNull&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;// 9&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;randomNumbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;maxOrNull&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And just like &lt;code&gt;sumBy&lt;/code&gt;, we have the sibling functions &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/max-of.html" rel="noopener noreferrer"&gt;&lt;code&gt;maxOf&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/min-of.html" rel="noopener noreferrer"&gt;&lt;code&gt;minOf&lt;/code&gt;&lt;/a&gt;, where we once again pass a &lt;strong&gt;selector function&lt;/strong&gt;, which is going to be used to &lt;strong&gt;determine the maximum or minimum&lt;/strong&gt; of a collection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;longestName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;randomNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;maxOf&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;longestName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// 7&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;shortestName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;randomNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;minOf&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shortestName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we just care about the &lt;strong&gt;number of elements&lt;/strong&gt; contained in our collection, we can use the &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/count.html" rel="noopener noreferrer"&gt;&lt;code&gt;count&lt;/code&gt;&lt;/a&gt; function – either without any parameters, to just get the number of all elements, or using a &lt;strong&gt;predicate&lt;/strong&gt;. So that’s like filtering the collection first, and then counting the elements. But again, all wrapped into one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val digits = randomNumbers.count()

println(digits)
// 11

val bigDigits = randomNumbers.count { it &amp;gt; 5 }

println(bigDigits)
// 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There’s also the powerful &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/join-to-string.html" rel="noopener noreferrer"&gt;&lt;code&gt;joinToString&lt;/code&gt;&lt;/a&gt; function, which allows us to &lt;strong&gt;turn all elements of our collection into a string&lt;/strong&gt;, complete with a metric ton of customization options like separators, prefixes and postfixes, limits or a placeholder if you have more elements than what your specified limit allows. And even &lt;code&gt;joinToString&lt;/code&gt; accepts a &lt;strong&gt;transformation function&lt;/strong&gt;, once again, so you don’t need to do some kind of separate mapping beforehand, it’s all built in. Truly powerful stuff to create a string from a collection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;str&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;randomNumbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;joinToString&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;separator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"pi://"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;limit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"[$it]"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// pi://[3]-[1]-[4]-[1]-[5]-...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to refresh what kind of magic we can do with Kotlin strings, watch the Kotlin Standard Library episode that takes us into the depth of strings!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/n4WBip822A8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  More collection goodness, coming soon!
&lt;/h2&gt;

&lt;p&gt;That concludes our overview of Kotlin collections!&lt;/p&gt;

&lt;p&gt;Next, we’re going to step up our game even more, and will take a look at some advanced collection functionality. Some of the functions we’ve seen today actually have some additional variants to them, which are worth an introduction. There’s also the whole world of modifying collections. Plus, each type of collection we’ve seen, Lists, Sets, and Maps, all have their own specialized functionality as well, We’re in for a whole bunch more Kotlin collection content!&lt;/p&gt;

&lt;p&gt;Make sure you don’t miss it! To get reminded when new content is released, follow us here on &lt;a href="https://dev.to/kotlin"&gt;dev.to/kotlin&lt;/a&gt;, and make sure to follow me on Twitter &lt;a href="https://twitter.com/sebi_io" rel="noopener noreferrer"&gt;@sebi_io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also, make sure to find the subscribe button and notification bell on our &lt;a href="https://kotl.in/video" rel="noopener noreferrer"&gt;YouTube channel&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;If you don’t want to wait until that episode comes out, there’s only one solution! It’s time to go and explore some more Kotlin!&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>programming</category>
      <category>android</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Publishing your Kotlin Multiplatform library to Maven Central</title>
      <dc:creator>Ekaterina Petrova</dc:creator>
      <pubDate>Thu, 25 Mar 2021 12:40:40 +0000</pubDate>
      <link>https://dev.to/kotlin/how-to-build-and-publish-a-kotlin-multiplatform-library-going-public-4a8k</link>
      <guid>https://dev.to/kotlin/how-to-build-and-publish-a-kotlin-multiplatform-library-going-public-4a8k</guid>
      <description>&lt;p&gt;Now when we've built our first Kotlin Multiplatform library and learned about multiplatform library publishing format nothing can stop us from going public and releasing our library to MavenCentral!&lt;/p&gt;

&lt;h1&gt;
  
  
  Registering a Sonatype account
&lt;/h1&gt;

&lt;p&gt;If this is your first library, or you’ve only ever used Bintray to do this before, you will need to first register a Sonatype account.&lt;/p&gt;

&lt;p&gt;There are many articles describing the registration process on the internet. &lt;a href="https://getstream.io/blog/publishing-libraries-to-mavencentral-2021/#overview" rel="noopener noreferrer"&gt;The one from GetStream&lt;/a&gt; is exhaustive and up to date. You can start by following the first four steps, including "Generating a GPG key pair":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Register a Jira account with Sonatype (you can use &lt;a href="https://issues.sonatype.org/browse/OSSRH-65092" rel="noopener noreferrer"&gt;my issue&lt;/a&gt; as an example). ✅&lt;/li&gt;
&lt;li&gt;Verify your ownership of the group ID you want to use to publish your artifact by creating a GitHub repo. ✅&lt;/li&gt;
&lt;li&gt;Generate a GPG key pair for signing your artifacts. ✅&lt;/li&gt;
&lt;li&gt;Publish your public key. ✅&lt;/li&gt;
&lt;li&gt;Export your private key. ✅&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When the Maven repository and signing keys for your library are prepared, we are ready to move forward and set up our build to upload the library artifacts to a staging repository and then release them!&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting up publication
&lt;/h1&gt;

&lt;p&gt;Now we need to tell Gradle how to publish our libraries. Most of the work is already done by &lt;code&gt;maven-publish&lt;/code&gt; and Kotlin Gradle Plugins – all the required publications are created automatically. We've already seen the result when we published our library to the local Maven repository. But for publishing it to Maven Central we need to take some additional steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure public Maven repository URL and credentials.&lt;/li&gt;
&lt;li&gt;Provide a description and &lt;code&gt;javadocs&lt;/code&gt; for all library components.&lt;/li&gt;
&lt;li&gt;Sign publications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's handle all of these tasks by writing some Gradle scripts! I suggest extracting all the publication-related logic from our library module build.script, so you can easily reuse it for other modules in the future. &lt;/p&gt;

&lt;p&gt;The most idiomatic and flexible way to do that is to use &lt;a href="https://docs.gradle.org/current/userguide/custom_plugins.html#sec:precompiled_plugins" rel="noopener noreferrer"&gt;Gradle’s precompiled script plugins&lt;/a&gt;. Our build logic will be provided as a &lt;em&gt;precompiled script plugin&lt;/em&gt; and could be applied by plugin ID to every module of our library. &lt;/p&gt;

&lt;p&gt;To implement this, we need to put our publication logic into a separate Gradle project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Add a new gradle project &lt;code&gt;convention-plugins&lt;/code&gt; inside your library root project by creating a new folder named &lt;br&gt;
&lt;code&gt;convention-plugins&lt;/code&gt; with &lt;code&gt;build.gradle.kts&lt;/code&gt; in it. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ficig8sxcu3diab1wktin.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ficig8sxcu3diab1wktin.png" alt="Gradle project structure"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Put the following in the &lt;code&gt;build.gradle.kts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;`kotlin-dsl`&lt;/span&gt; &lt;span class="c1"&gt;// Is needed to turn our build logic written in Kotlin into Gralde Plugin&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;repositories&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;gradlePluginPortal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// To use 'maven-publish' and 'signing' plugins in our own plugin&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;code&gt;convention.publication.gradle.kts&lt;/code&gt; file in the &lt;code&gt;convention-plugins/src/main/kotlin&lt;/code&gt; directory. This is where all the publication logic will be stored.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Put all the required logic there. Applying just &lt;code&gt;maven-publish&lt;/code&gt; is enough for publishing to the local Maven repository, but not to Maven Central. In the provided script we get the credentials from &lt;code&gt;local.properties&lt;/code&gt; or environment variables, do all the required configuration in the ‘publishing’ section, and sign our publications with the signing plugin:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.gradle.api.publish.maven.MavenPublication&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.gradle.api.tasks.bundling.Jar&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.gradle.kotlin.dsl.`maven-publish`&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.gradle.kotlin.dsl.signing&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.*&lt;/span&gt;

&lt;span class="nf"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;`maven-publish`&lt;/span&gt;
   &lt;span class="n"&gt;signing&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Stub secrets to let the project sync and build without the publication values set up&lt;/span&gt;
&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"signing.keyId"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"signing.password"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"signing.secretKeyRingFile"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"ossrhUsername"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"ossrhPassword"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;

&lt;span class="c1"&gt;// Grabbing secrets from local.properties file or from environment variables, which could be used on CI&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;secretPropsFile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rootProject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"local.properties"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secretPropsFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;secretPropsFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nc"&gt;Properties&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;onEach&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
       &lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"signing.keyId"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SIGNING_KEY_ID"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"signing.password"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SIGNING_PASSWORD"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"signing.secretKeyRingFile"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SIGNING_SECRET_KEY_RING_FILE"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"ossrhUsername"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OSSRH_USERNAME"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"ossrhPassword"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OSSRH_PASSWORD"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;javadocJar&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registering&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Jar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;archiveClassifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"javadoc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getExtraString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;publishing&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// Configure maven central repository&lt;/span&gt;
   &lt;span class="nf"&gt;repositories&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nf"&gt;maven&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"sonatype"&lt;/span&gt;
           &lt;span class="nf"&gt;setUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="nf"&gt;credentials&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getExtraString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ossrhUsername"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getExtraString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ossrhPassword"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="c1"&gt;// Configure all publications&lt;/span&gt;
   &lt;span class="n"&gt;publications&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;withType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MavenPublication&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

       &lt;span class="c1"&gt;// Stub javadoc.jar artifact&lt;/span&gt;
       &lt;span class="nf"&gt;artifact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;javadocJar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

       &lt;span class="c1"&gt;// Provide artifacts information requited by Maven Central&lt;/span&gt;
       &lt;span class="nf"&gt;pom&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MPP Sample library"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sample Kotlin Multiplatform library (jvm + ios + js) test"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://github.com/KaterinaPetrova/mpp-sample-lib"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

           &lt;span class="nf"&gt;licenses&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="nf"&gt;license&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MIT"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                   &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://opensource.org/licenses/MIT"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="nf"&gt;developers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="nf"&gt;developer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"KaterinaPetrova"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                   &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ekaterina Petrova"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                   &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ekaterina.petrova@jetbrains.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="nf"&gt;scm&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://github.com/KaterinaPetrova/mpp-sample-lib"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;

       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Signing artifacts. Signing.* extra properties values will be used&lt;/span&gt;

&lt;span class="nf"&gt;signing&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publishing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publications&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go back to your library project. Ask Gradle to prebuild your plugins by adding the following in the root &lt;code&gt;settings.gradle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;includeBuild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"convention-plugins"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now we can apply this logic in our library &lt;code&gt;build.script&lt;/code&gt;. In the &lt;code&gt;plugins&lt;/code&gt; section, replace using &lt;code&gt;maven-publish&lt;/code&gt; with using our &lt;code&gt;conventional.publication&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nf"&gt;kotlin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"multiplatform"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s"&gt;"1.4.30"&lt;/span&gt;
   &lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"convention.publication"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t forget to create a &lt;code&gt;local.properties&lt;/code&gt; file with all the necessary credentials and &lt;strong&gt;make sure you have added it to .gitignore 🗝&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;signing.keyId=...
signing.password=...
signing.secretKeyRingFile=...
ossrhUsername=...
ossrhPassword=...
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now take a deep breath, make &lt;code&gt;./gradlew clean&lt;/code&gt; and sync the project. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ku5kppqoqq146zzh3m0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ku5kppqoqq146zzh3m0.png" alt="Maven publication Gradle tasks"&gt;&lt;/a&gt;&lt;br&gt;
New Gradle tasks related to the Sonatype repository should appear in the publishing group – that means that everything is ready for you to publish your library!&lt;/p&gt;
&lt;h1&gt;
  
  
  Publishing your first library to MavenCentral
&lt;/h1&gt;

&lt;p&gt;In the beginning of the article I promised you that you will be able to publish your library in just a one click – and now is the moment of truth! To upload your library to Sonatype Repository just run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./gradlew publishAllPublicationsToSonatypeRepository
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The so-called staging repository will be created, and all the artifacts for all publications will be uploaded to that repository. All that is now needed is to check that all the artifacts you wanted to upload have made it there and to press the “release” button!&lt;/p&gt;

&lt;p&gt;These final steps are well-described in &lt;a href="https://getstream.io/blog/publishing-libraries-to-mavencentral-2021/#your-first-release" rel="noopener noreferrer"&gt;the now-familiar article&lt;/a&gt;. In short, you need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://s01.oss.sonatype.org/" rel="noopener noreferrer"&gt;https://s01.oss.sonatype.org/&lt;/a&gt; and log in using the credentials you used in Sonatype Jira.&lt;/li&gt;
&lt;li&gt;Find your repository in the ‘Staging repositories’ section.&lt;/li&gt;
&lt;li&gt;Close it.&lt;/li&gt;
&lt;li&gt;🚀 Release it!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Go back to the Jira Issue you created and let them know you released your first component to activate the sync to Maven Central. &lt;em&gt;This step is needed only if it’s your first release.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz06v8kxi0io3b45vso83.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz06v8kxi0io3b45vso83.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Soon your library will become available at &lt;a href="https://repo1.maven.org/maven2/" rel="noopener noreferrer"&gt;https://repo1.maven.org/maven2/&lt;/a&gt; and other developers will be able to add it as a dependency. And in a couple of hours, it will become &lt;a href="https://search.maven.org/" rel="noopener noreferrer"&gt;discoverable in Maven Central Repository Search&lt;/a&gt;!&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jn9h57szxned439ngmy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jn9h57szxned439ngmy.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Congratulations! 🎉 You’ve just created your first Kotlin Multiplatform Library and published it on Maven Central! &lt;/p&gt;

&lt;p&gt;This is how you can now depend on the published version:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;kotlin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;android&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;ios&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;sourceSets&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;commonMain&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;getting&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.github.katerinapetrova:mpp-sample-lib:1.0.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Pretty simple, right? If you check the external dependencies section, you will see that it is quite clever as your project only downloads the artifacts of the platforms you actually target, not all of them every time. Thanks to the Gradle module metadata feature, you only have to specify dependencies on the library once in the shared source set, even if it is used in platform source sets.&lt;/p&gt;

&lt;p&gt;A lot of work has been done, but of course, it’s just the beginning of the journey. The most interesting part is ahead: to support and improve your library continuously, so you can provide your users the best DX and evolve the KMM ecosystem together with other library creators and contributors.&lt;/p&gt;
&lt;h2&gt;
  
  
  Next useful steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Now that you have published your library to Maven Central, it's time to let others know – and what better way than to &lt;a href="https://shields.io/category/version" rel="noopener noreferrer"&gt;add a badge&lt;/a&gt; to your project's README! &lt;/li&gt;
&lt;li&gt;Add your library to &lt;a href="https://libs.kmp.icerock.dev/" rel="noopener noreferrer"&gt;the community-driven list of Kotlin Multiplatform libraries&lt;/a&gt; to increase its discoverability.&lt;/li&gt;
&lt;li&gt;Take a look into the possibility &lt;a href="https://getstream.io/blog/publishing-libraries-to-mavencentral-2021/#automating-sonatype-actions" rel="noopener noreferrer"&gt;to automate the release process&lt;/a&gt; and share your experience with the community, if you’ve already successfully made it this far!&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/KaterinaPetrova" rel="noopener noreferrer"&gt;
        KaterinaPetrova
      &lt;/a&gt; / &lt;a href="https://github.com/KaterinaPetrova/mpp-sample-lib" rel="noopener noreferrer"&gt;
        mpp-sample-lib
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Sample Kotlin Multiplatform library (jvm + ios + js)
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>kotlin</category>
      <category>multiplatform</category>
    </item>
    <item>
      <title>How a Kotlin Multiplatform library is published?</title>
      <dc:creator>Ekaterina Petrova</dc:creator>
      <pubDate>Thu, 25 Mar 2021 12:40:27 +0000</pubDate>
      <link>https://dev.to/kotlin/how-to-build-and-publish-a-kotlin-multiplatform-library-discovering-the-library-structure-3oeo</link>
      <guid>https://dev.to/kotlin/how-to-build-and-publish-a-kotlin-multiplatform-library-discovering-the-library-structure-3oeo</guid>
      <description>&lt;p&gt;In the first part of the series, we've created our first multiplatform library and published it to the local Maven. Before going public, let's discover published artifacts to get an understanding of the multiplatform publishing format.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;TL;DR: The Kotlin Gradle plugin creates and configures your library publications automatically, so you don't need to know the details of the publication scheme to successfully deliver your library. But if you are curious, let's discuss it a little!&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Discovering your library structure
&lt;/h1&gt;

&lt;p&gt;If you have published regular platform (for example, android) libraries before, you may notice that the publishing format of a multiplatform library differs quite a lot. There are multiple artifacts for one version of your library, their content format is different (.jar vs .klib),  and the number of source sets doesn’t match the number of result artifacts.&lt;/p&gt;

&lt;p&gt;This is because ordinary publishing is not enough for a multiplatform library. Multiplatform libraries have more complex structures compared to normal ones, so the publication is less trivial as well. Here are key differences to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiplatform libraries consist of multiple parts: common parts with &lt;code&gt;expect&lt;/code&gt;s declarations and platform-specific parts with actual implementations.&lt;/li&gt;
&lt;li&gt;Platform-specific code may still be shared across similar platforms (e.g. in a source set shared between the iOS device and simulator, or shared code for all desktop platforms).&lt;/li&gt;
&lt;li&gt;There should be the ability to publish all those parts from a multiple host because of Kotlin/Native cross-compilation limitations. For example, the artifacts for iOS or macOS can be built only on Mac-OS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Considering all that complexity, adding the ordinary multiplatform dependency requires just a single line of code in your the &lt;code&gt;build.gradle&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.github.katerinapetrova:mpp-sample-lib:1.0.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So how does this magic work? Maven doesn’t operate with targets, source sets, and compilations. It operates only with projects. A project is everything we build and could depend on. Each project is defined by groupId, artifactId, and version, and these three fields are used by Maven as a coordinate system. This is exactly what you are using when copy-pasting a dependency string to your build.gradle file. These coordinates are defined in a .pom file — an XML representation of a Maven project. Let’s take a look at what we have in the local Maven folder of the library we’ve just published:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47n7dhcounnxzui73hk6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47n7dhcounnxzui73hk6.png" alt="Multiplatform library in the local Maven folder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We published only one library, but there are multiple folders. Each folder represents a separate maven project, containing different artifacts and a .pom file, which describes the project (we can also call them “artifacts”, as the name of the project is stored in the POM &lt;code&gt;artifactId&lt;/code&gt; field).&lt;/p&gt;

&lt;p&gt;So the Kotlin Gradle plugin has created publications, which were used by the &lt;code&gt;maven-publish&lt;/code&gt; plugin to map the sources of our Kotlin Multiplatform library to the Maven artifacts, on which we later could depend on in the consumer project as Gradle modules. This is how it was done:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faurtqhgjghqco6x12mvk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faurtqhgjghqco6x12mvk.png" alt="Kotlin Multiplatform Library Maven representation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s figure out the main points of this transformation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is a separate publication for each target. The binary format depends on the target compiler backend:

&lt;ul&gt;
&lt;li&gt;.jar with class files for Kotlin/JVM&lt;/li&gt;
&lt;li&gt;.jar with .js or .klib &lt;a href="https://kotlinlang.org/docs/js-ir-compiler.html" rel="noopener noreferrer"&gt;when using IR Compiler for Kotlin/JS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;.klib for Kotlin/Native&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;There is also an additional root publication that stands for the whole library. It consists of two important parts:

&lt;ul&gt;
&lt;li&gt;Kotlin representation of common sources of your library. Kotlin toolchain will use it to provide exact and granular dependencies from your common code to a library's common code.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.gradle.org/current/userguide/publishing_gradle_module_metadata.html" rel="noopener noreferrer"&gt;Gradle Module Metadata&lt;/a&gt;, which tells Gradle where to find other platform-specific parts of a library when you depend on the root artifact in the common source set. This is what allows you to write single-line dependency on a library in a common source set&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kotlinlang.org/docs/mpp-share-on-platforms.html#share-code-in-libraries" rel="noopener noreferrer"&gt;With the hierarchical project structure enabled&lt;/a&gt;, the API of the library’s intermediate source sets is embedded into the library artifacts (common or platform, depending on which targets this set is divided between). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This transformation doesn’t look trivial and the described points are just the tip of the iceberg, but the good news is that all the work is done by the Kotlin Gradle plugin. It creates and configures all the relevant publications automatically, so you don't need to create them manually. That significantly reduces the chance of making a mistake, especially for popular configurations. 🎉&lt;/p&gt;

&lt;p&gt;If you want to dive into the details of publication format, I suggest you watch an exciting talk by Dima Savinov, Kotlin Multiplatform team lead. &lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/5QPPZV04-50"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;And now let’s go back to our main goal — &lt;strong&gt;making our library available to the world&lt;/strong&gt;! Check out the last part of the series, which will guide you through the MavenCentral publication process 👀&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>multiplatform</category>
    </item>
  </channel>
</rss>
