Demystifying Kotlin: A Quick Guide to Filter and Collection Functions
Tags: kotlin, programming
Published: 2024-01-26 01:04:14

Kotlin offers an extensive set of filter and collection functions within its library. Initially, we’ll explore filters, which assist in extracting the needed results from a collection while disregarding unnecessary elements. Subsequently, we’ll delve into collection functions, which are specifically tailored for collections. 

Let's get started.

## The Filter Function
This is the most used filter function in Kotlin. This function takes a lambda expression, with one variable and returns the variable as a result. the filter function applies the lambda expression and returns a list. 
  
Let's see how this works: 
```kotlin
val numbers = listOf(0,1,2,3,4,5,6,7,8,9)
val newList = numbers.filter { i -> i < 5 }
println(newList)
```


We create a list to hold numbers 0 to 9
i represent the elements in the list and i < 5 is the condition that filters out the result which is a list of numbers less than 5

The it keyword can also be used in place of i like so:
```kotlin
val newList = numbers.filter { it < 5 }
```
And we still get the same result:
## The FilterNot Function
The FilterNot function is the opposite of the filter function, it also returns a list, but the opposite of what is in the lambda function, for example:
```kotlin
val numbers = listOf(1,2,3,4,5,6,7,8,9,0)
val newList = numbers.filterNot { it < 5 }
println(newList)
```
This, in turn, returns a list of numbers greater than 5, including 5

## The FilterNotNull function
The FilterNotNull function goes through a list, ignores the null values, and returns a list without the null values. Any null value present in the list is ignored. 

Let's see how it works:
```kotlin
fun main(args: Array<String>) {
   val example = listOf("one", 1, true, null ,55, 66, null ,'A')
   val notNull = example.filterNotNull()
   println(notNull)
}
```
This returns the list: **[one, 1, true, 55, 66, A]**  without the null values.

## The FilterIsInstance<dataType> function
This function allows us to filter out elements of specific data types. We can create a list of different data types and filter out a particular data type:
```kotlin
fun main(args: Array<String>) {
   val example = listOf("one", 1, true, null ,55, 66, null ,'A', 2.0, "food")
   val finalList = example.filterIsInstance<String>()
   println(finalList)
}
```
This returns a list of strings: **[one, food]**

## The Slice Function
This function accepts a list or range as input and produces a new list containing elements from the specified indices of the original list:
```kotlin
fun main(args: Array<String>) {
   val example = listOf(1,2,3,4,5,6,7,8,9,10)
   val finalList = example.slice(0..4)
   println(finalList)
}
```
This “slice” out elements from index 0 to 4 from the initial list. Or you could slice out selected elements using the index like this:
```kotlin
fun main(args: Array<String>) {
   val example = listOf(1,2,3,4,5,6,7,8,9,10)
   val finalList = example.slice(listOf(1,3,5))
   println(finalList)
}
```
And this would print out **[2, 4, 6]**.

## The Take function
This function is quite simple. It takes an argument that specifies the quantity of elements to be extracted from a list.
```kotlin 
fun main(args: Array<String>) {
   val example = listOf(1,2,3,4,5,6,7,8,9,10)
   val finalList = example.take(5)
   println(finalList)
}
```
The take function returns the first 5 elements in the list, in this case: **[1, 2, 3, 4, 5]**.

## The Take Last
This function is like the take function, it takes an argument to return the last element from the list:
```kotlin
fun main(args: Array<String>) {
   val example = listOf(1,2,3,4,5,6,7,8,9,10)
   val finalList = example.takeLast(5)
   println(finalList)
}
```
This returns the last five elements in the list **[6, 7, 8, 9, 10]**.

## Take While Function
This accepts a lambda function and takes elements from the list until a condition is met:
```kotlin
fun main(args: Array<String>) {
   val example = listOf(1,2,3,4,5,6,7,8,9,10)
   val finalList = example.takeWhile { it < 5 }
   println(finalList)
}
```
This returns:**[1, 2, 3, 4]**.

## The TakeLastWhile function
This is similar to the take-while function. It takes elements from the ending of the list till the conditions in the lambda are met:
```kotlin
fun main(args: Array<String>) {
   val example = listOf(1,2,3,4,5,6,7,8,9,10)
   val finalList = example.takeLastWhile { it > 5 }
   println(finalList)
}
```
This would return: **[6, 7, 8, 9, 10]**.

## The Drop function
This is another straightforward function. It takes an argument. Ignores several elements from the main list and returns a new list as a result:
```kotlin 
fun main(args: Array<String>) {
   val example = listOf(1,2,3,4,5,6,7,8,9,10)
   val finalList = example.drop(5)
   println(finalList)
}
```
Your result should be **[6, 7, 8, 9, 10]**.

## The DropLast
This drops the last elements of the lists:
```kotlin
fun main(args: Array<String>) {
   val example = listOf(1,2,3,4,5,6,7,8,9,10)
   val finalList = example.dropLast(5)
   println(finalList)
}
``` 
## The dropWhile
The dropWhile functions accept a lambda expression. This function keeps ignoring the elements until the condition is satisfied and returns a new list:
```kotlin
fun main(args: Array<String>) {
   val example = listOf(1,2,3,4,5,6,7,8,9,10)
   val finalList = example.dropWhile { it < 5 }
   println(finalList)
}
```
## The dropLastWhile
The dropLastWhile function accepts a lambda expression. This function keeps ignoring the elements from the end of the list until the condition is satisfied:
```kotlin
fun main(args: Array<String>) {
   val example = listOf(1,2,3,4,5,6,7,8,9,10)
   val finalList = example.dropLastWhile { it < 5 }
   println(finalList)
}
```
## The Fold Function
This function carries out mathematical operations on every item in a list and delivers an outcome. To grasp the idea of the fold function, we’ll employ addition as the operation. We’ll sum up all the elements in the list and yield a result. The fold function requires an integer argument and a lambda expression. The initial value is represented by the first parameter, while the second parameter accepts a lambda expression for summing two values.
```kotlin
fun main(args: Array<String>) {
   val example = listOf(1,2,3,4,5,6,7,8,9,10)
   val finalList = example.foldRight(0){x,y-> x+y}
   println(finalList)
}
```
## The FoldRightIndexed Function
The function begins with an initial value and then applies a specific operation to each element in the list or array, starting from the end and moving towards the beginning. This operation takes into account the index of each element in the original collection and the current accumulated value. Let's see an example:
```kotlin
fun main(args: Array<String>) {
   val numbers = listOf(1, 2, 3, 4, 5)
   val result = numbers.foldRightIndexed(0) { index, item, acc -> acc + item * index }
   println(result)
}
```
In this code, we have a list of numbers from 1 to 5. We use _foldRightIndexed_ to go through the list from right to left (i.e., starting from the last element). 
The index is the position of the element in the list, the item is the element itself, and acc is the accumulated value.
The lambda function ```{ index, item, acc -> acc + item * index }``` multiplies each element by its index and adds the result to the accumulated value. The initial accumulated value is 0.
When you run this code, it will output 40, which results from the operation 0*5 + 1*4 + 2*3 + 3*2 + 4*1.

## The Reduce Function
To understand the reduce function, let's use an addition operation. The reduce function adds all the elements in a list and returns a result. The difference between the reduce function and the fold function is that it does not need an initial value.
```kotlin
fun main(args: Array<String>) {
   val numbers = listOf(1, 2, 3, 4, 5)
   val result = numbers.reduce{x,y -> x+y}
   println(result)
}
```
## The reduceRight
This takes a lambda expression that takes two variables and returns a result. But the only difference with the reduce function is it starts iterating from the end of the list.
## reduceRightIndexed 
This operates like the foldRightIndexed function, where it accepts a lambda expression with three variables and executes an operation starting from the end of the list. However, in this case, it doesn’t require an initial value. The iteration begins from the last value in the list.
## Conclusion
Kotlin boasts an extensive library brimming with beneficial functions. While it’s impossible to delve into each one within the confines of this article, we aimed to provide a glimpse into the realm of possibilities that Kotlin offers. We strongly encourage you to venture further into this vast library, familiarize yourself with its diverse functions, and discover how they can significantly streamline your programming experience. Harnessing the power of these functions can truly elevate your coding expertise to new heights. Happy exploring!