DEV Community

Cover image for Demystifying Kotlin: A Quick Guide to Filter and Collection Functions
Audu Ephraim
Audu Ephraim

Posted on

Demystifying Kotlin: A Quick Guide to Filter and Collection Functions

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:

val numbers = listOf(0,1,2,3,4,5,6,7,8,9)
val newList = numbers.filter { i -> i < 5 }
println(newList)
Enter fullscreen mode Exit fullscreen mode

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:

val newList = numbers.filter { it < 5 }
Enter fullscreen mode Exit fullscreen mode

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:

val numbers = listOf(1,2,3,4,5,6,7,8,9,0)
val newList = numbers.filterNot { it < 5 }
println(newList)
Enter fullscreen mode Exit fullscreen mode

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:

fun main(args: Array<String>) {
   val example = listOf("one", 1, true, null ,55, 66, null ,'A')
   val notNull = example.filterNotNull()
   println(notNull)
}
Enter fullscreen mode Exit fullscreen mode

This returns the list: [one, 1, true, 55, 66, A] without the null values.

The FilterIsInstance 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:

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)
}
Enter fullscreen mode Exit fullscreen mode

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:

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)
}
Enter fullscreen mode Exit fullscreen mode

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:

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)
}
Enter fullscreen mode Exit fullscreen mode

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.

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)
}
Enter fullscreen mode Exit fullscreen mode

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:

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)
}
Enter fullscreen mode Exit fullscreen mode

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:

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)
}
Enter fullscreen mode Exit fullscreen mode

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:

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)
}
Enter fullscreen mode Exit fullscreen mode

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:

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)
}
Enter fullscreen mode Exit fullscreen mode

Your result should be [6, 7, 8, 9, 10].

The DropLast

This drops the last elements of the lists:

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)
}
Enter fullscreen mode Exit fullscreen mode

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:

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)
}
Enter fullscreen mode Exit fullscreen mode

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:

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)
}
Enter fullscreen mode Exit fullscreen mode

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.

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)
}
Enter fullscreen mode Exit fullscreen mode

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:

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)
}
Enter fullscreen mode Exit fullscreen mode

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.

fun main(args: Array<String>) {
   val numbers = listOf(1, 2, 3, 4, 5)
   val result = numbers.reduce{x,y -> x+y}
   println(result)
}
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (0)