In 2022 I set out to complete advent of code each day using Kotlin. It was a lot of fun and following along with Jetbrains/Sebastians videos was a great way to explore alternative solutions. Along the way I learned and was reminded of the power of all the different tools we have available in Kotlin and the standard library which I’ve endeavoured to list below. You might learn something new or it might be a reminder of something forgotten. I’ll be checking over this list before next December to refresh.
in no particular order:
extension property
Extension functions are well known and loved but you can also have extension properties
val Card.nextUpgradeAttack: Int
get() = (this.attackPoints * 1.2).toInt()
Code language: Kotlin (kotlin)
Note that you need the getter as extension properties can’t have backing fields as explained in the Kotlin docs
destructuring
Create multiple variables from the individual components of something. Great for Pairs, Lists, Maps, and data classes.
val (part1, part2) = myString.split(" ,")
for ((key, value) in myMap) { println("$key, $value") }
Code language: Kotlin (kotlin)
collection.chunked
Split a list into smaller lists of a given size (the last list may be smaller).
val words = "up 4 left 5 down 7 left 2".split(' ')
val moves = words.chunked(2)
// You can also transform the resulting chunks immediately
val moves = words.chunked(2) { (direction, distance) -> Move(direction, distance) }
Code language: Kotlin (kotlin)
collection.map
Transform each item in a list
val numsList = listOf(1, 2, 3, 4, 5, 6)
val squares = numsList.map { it * it }
// 1, 4, 9, 16, 25, 36
val cards = listOf(Card(Jack, Diamond), Card(Four, Club))
val cardValues = cards.map { card -> card.value }
Code language: Kotlin (kotlin)
downTo
Creates a range that counts down. Useful for loops. Includes start and end values
for (i in 5 downTo 0) { print(i) }
// 543210
Code language: Kotlin (kotlin)
..< (now preferred to equivalent “until” function)
Create range excluding the end value
for (i in 1..<4) { print(i) }
// 123
for (j in 1..4) { print(j) }
// 1234
Code language: Kotlin (kotlin)
step
Create a range with the given steps between values
for (i in 0..8 step 2) { print(i) }
// 02468
for (j in 8 downTo 0 step 2) print(j)
// 86420
Code language: Kotlin (kotlin)
collection.lastIndex
When list.size
doesn’t do the trick because it starts at zero, list.lastIndex
steps in to save the day.
//skip the first value
for (i in 1..myList.lastIndex) { ... }
for (j in myList.lastIndex downTo 0) { ... }
Code language: Kotlin (kotlin)
operator override
Create custom implementations of standard operators like +
, *
, in
, etc.
data class Card(val attackPoints: Int) {
operator fun plus(other: Card): Card {
return Card(this.attackPoints + other.attackPoints)
}
}
// Then you can do
val result = Card(7) + Card(4)
Code language: Kotlin (kotlin)
The list of all the operators you can override is in the kotlin docs
infix
Add some syntactical flair that feels like you’re creating a new kotlin keyword
infix fun Map<Int, String>.excluding(other: Int): Map<Int, String> { ... }
// Normally a method call would look like this
myMap.excluding(5)
// but with infix it can be changed to
myMap excluding 5
Code language: Kotlin (kotlin)
repeat(n)
Do the thing multiple times. Just shorthand for a 0 based for loop.
repeat(3) { index ->
print("Hello$index")
}
// Hello0Hello1Hello2
Code language: Kotlin (kotlin)
Can also repeat strings
println("Word".repeat(4))
// WordWordWordWord
Code language: JavaScript (javascript)
collection.joinToString
Join elements in list together to form one string
val numbers = listOf(1, 2, 3, 4, 5, 6)
println(numbers.joinToString(
prefix = "<",
postfix = ">",
separator = "•"
))
// <1•2•3•4•5•6>
Code language: Kotlin (kotlin)
Supports transforming objects into strings to be joined
val cars = listOf(ferrari, lamborghini, ford, kia)
println(
cars.joinToString(separator = ", ") { car ->
"${car.brandName} is ${if (car.isCool) "cool" else "lame"}"
}
)
// Ferrari is cool, Lamborghini is cool, Ford is lame, Kia is lame
Code language: Kotlin (kotlin)
collection.reversed
Returns the list with elements in the reversed order
val numbers = listOf(1, 2, 3, 4, 5, 6)
val reversed = numbers.reversed()
println(reversed)
// [6, 5, 4, 3, 2, 1]
Code language: Kotlin (kotlin)
collection.single()
Just a simplified way of checking there is only one element then getting that first element. Returns the single element or throws if there are less/more than one. Also .singleOrNull()
val one = listOf(1,2,3)
val two = listOf(1,6,11)
val commonElement = (one intersect two).single()
println(commonElement)
// 1
Code language: Kotlin (kotlin)
collection.sum/sumOf
sum returns the sum of elements in a collection of numbers
val numbers = listOf(1,2,3,4,5)
println(numbers.sum())
// 15
Code language: Kotlin (kotlin)
sumOf lets you transform elements to be counted
return inputLists.sumOf { list ->
list.size
}
Code language: Kotlin (kotlin)
collection.count
Finds the number of elements matching the predicate
val numbers = listOf(1,2,3,4,5)
println(numbers.count { num -> num % 2 == 0 })
// 2
Code language: Kotlin (kotlin)
collection.all/any
All returns true of all elements match the given predicate. Any returns true if any element matches.
val numbers = listOf(1,2,3,4,5)
println(numbers.all { it % 2 == 0})
// false
println(numbers.any { it % 2 == 0})
// true
Code language: Kotlin (kotlin)
in
Check if element is in the collection
if (count in list) {
print(“Count is present in the list”)
}
Code language: Kotlin (kotlin)
Also used for loops
for (i in list) { ... }
// but probably you want to use list.forEach { ... }
Code language: Kotlin (kotlin)
2023
Named loops
Allows you to break out of a loop early.
list.forEach name@ {
if (...) {
return@name
}
...
}
Code language: Kotlin (kotlin)
collection.windowed
Returns a list of lists captured by sliding a “window” across the list
val numbers = listOf(1,2,3,4,5,6,7,8)
val windows = numbers.windowed(size = 5, step = 1)
println(windows.toList())
// [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8]]
val numbers10 = listOf(1,2,3,4,5,6,7,8,9,10)
val partialWindows = numbers10.windowed(size = 5, step = 3, partialWindows = true)
println(partialWindows.toList())
// [[1, 2, 3, 4, 5], [4, 5, 6, 7, 8], [7, 8, 9, 10], [10]]
Code language: Kotlin (kotlin)
String.findAnyOf/findLastAnyOf
Find the index of the first occurrence of any of the supplied strings
val input = "lluddlrlrrrduu"
val (firstIndex, foundString) = input.findAnyOf(listOf("u", "d"))!!
println("$foundString was found at index $firstIndex")
// u was found at index 2
Code language: Kotlin (kotlin)
Number.coerceAtMost/Least/coerceIn
Similar to maxOf/minOf it ensures the returned value is within the constraints
val points = 73
println(points.coerceAtMost(70))
// 70
println(points.coerceAtLeast(80))
// 80
println(points.coerceIn(0,100))
// 73
Code language: Kotlin (kotlin)
collection.partition
Split a list in two using the given condition
val list = listOf(Person("Tom", 18), Person("Andy", 32), Person("Sarah", 22))
val result = list.partition { it.age < 30 }
println(result)
// ([Tom - 18, Sarah - 22], [Andy - 32])
val (greenApples, notGreenApples) = apples.partition { it.isGreen }
Code language: Kotlin (kotlin)
collection.take/takeLast
Grab the first/last N elements from a list. Just a convenience method for .sublist(0,n)
println(listOf(1,2,3,4,5,6,7,8).take(3))
// 1,2,3
println(listOf(1,2,3,4,5,6,7,8).takeLast(3))
// 6,7,8
Code language: Kotlin (kotlin)
collection.drop/dropLast
Get a sublist excluding the dropped elements
println(listOf(1,2,3,4,5,6,7,8).drop(3))
// 4,5,6,7,8
println(listOf(1,2,3,4,5,6,7,8).dropLast(3))
// 1,2,3,4,5
Code language: Kotlin (kotlin)