Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Filtering and Modifying Lists | Control Flow and Collections
Android Development with Kotlin
course content

Course Content

Android Development with Kotlin

Android Development with Kotlin

1. Kotlin Basics
2. Control Flow and Collections
3. Object-Oriented Programming in Kotlin

bookFiltering and Modifying Lists

While studying lists, you might have wondered how to filter or modify a specific collection quickly.

For example, let's say we have a list of numbers, and we want to find the square of each element in the list.

Note

The square of a number is the number multiplied by itself once. For instance, if we have the number 5, the square of that number will be 5 * 5 = 25.

kt

Main

copy
1234567891011
fun main() { val numbers: List<Int> = listOf(2, 1, 5, 6, 7, 3, 4, 8) val squareNumbers: MutableList<Int> = mutableListOf() for (number in numbers) { squareNumbers.add(number * number) } println("Initial list: $numbers") println("List of squares: $squareNumbers") }

You can use a loop to create a new list with the squares of numbers.

But did you know that Kotlin allows you to do this without using a loop and in just one line?

.map() Method

Please don’t confuse this method with a data structure!

The map method in Kotlin is a very handy tool for transforming collections. It can be applied to lists (List), sets (Set), and other collections.

Using it is very simple. Let’s look at an example of creating a list with the squares of numbers, as we did above:

kt

Main

copy
1234567
fun main() { val numbers: List<Int> = listOf(2, 1, 5, 6, 7, 3, 4, 8) val squareNumbers: List<Int> = numbers.map { it * 2 }.toList() println("Initial list: $numbers") println("List of squares: $squareNumbers") }

Let's break down how it works step by step:

Briefly About Lambda Expressions

Lambda expressions in the context of lists are used to easily and quickly define what to do with each element of the list. This allows you to apply the same operation to all elements of the list without creating separate functions.

Let's say you have a list of numbers, and you want to create a new list where each number is increased by 2. Instead of writing a loop or a separate function, you can use a lambda expression with the map method.

kt

Main

copy
12
val numbers = listOf(1, 2, 3, 4) val increasedNumbers = numbers.map { it + 2 }

Here, numbers is the original list of numbers. The map method takes each element from numbers and applies the lambda expression { it + 2 } to it. In this lambda expression, it refers to the current element from the list, and the operation it + 2 increases it by 2. The result is a new list, increasedNumbers, containing [3, 4, 5, 6].

Advantages

Using lambda expressions in these cases allows you to:

  1. Avoid creating intermediate variables and complex loops;
  2. Write code that is easy to read and understand;
  3. Perform operations on list elements directly without creating additional functions.

We can use the .map() method for many operations, and it's very simple to use.

For example, let's transform a list of type Int into a list of type String:

kt

Main

copy
12345678
fun main() { val numbers: List<Int> = listOf(2, 1, 5, 6, 7, 3, 4, 8) val stringNumbers: List<String> = numbers.map { "Number $it" } println("Initial list: $numbers") println("String list: $stringNumbers") }

Here, we've demonstrated a more complex operation on list elements, clearly indicating that we want to see a list of strings in the format "Number \element`"`.

We could do the same with loops or functions, but why bother when we can achieve it in one simple line?

We can perform similar operations with sets and arrays; let's look at an example:

kt

Main

copy
12345678910111213141516171819
fun main() { val numbersList: List<Int> = listOf(2, 1, 5, 6, 7, 3, 4, 8) val doubledNumbers: List<Int> = numbersList.map { it * 2 } val numbersArray: Array<Int> = arrayOf(1, 5, 10, 23, 61) val tripleNumbers: Array<Int> = numbersArray.map { it * 3 }.toTypedArray() val numbersSet: Set<Int> = setOf(38, 19, 22, 41, 20) val stringSet: Set<String> = numbersSet.map { "Number $it" }.toSet() println("Initial list: $numbersList") println("Doubled list: $doubledNumbers") println() println("Initial array: ${numbersArray.joinToString(" ")}") println("Tripled Array: ${tripleNumbers.joinToString (" ")}") println() println("Initial Set: $numbersSet") println("String Set: $stringSet") }

We can also use the map method with a Map, but to do this, we need to convert the map to a list, either by extracting the list of keys using the keys property or the list of values using the values property.

Let's look at an example where the keys are of type Int and the values are of type String, and we'll extract a list of transformed keys and values:

kt

Main

copy
123456789
fun main() { val exampleMap: Map<Int, String> = mapOf(1 to "One", 2 to "Two", 3 to "Three", 4 to "Four") val modifiedKeys: List<Int> = exampleMap.keys.map { it * 2 } val modifiedValues: List<String> = exampleMap.values.map { "Value: $it" } println("Modified keys: $modifiedKeys") println("Modified values: $modifiedValues") }

This way, we can easily modify lists of keys and values in a map using the map method!

Filtration Methods

Filtering lists is also a very useful feature in Kotlin, so let's look at how it works.

Filtering uses the .filter() method, which takes a lambda expression (just like the map method), but these lambda expressions must return a boolean value. So, the expressions should be like "it > 2" or "it.length <= 10" and so on.

Let's look at an example where we filter a list of numbers to keep only those that are divisible by 2 (even numbers only):

kt

Main

copy
1234567
fun main() { val numbersList: List<Int> = listOf(2, 1, 5, 6, 7, 3, 4, 8, 19, 28, 48, 11, 92, 10, 2, 1, 38, 19, 34, 25, 132) val evenNumbersList: List<Int> = numbersList.filter { it % 2 == 0 } println("Initial list: $numbersList") println("Only even numbers list: $evenNumbersList") }

it % 2 == 0 means that the remainder of the division by 2 is 0, meaning the number is evenly divisible by 2.

You can also filter using simpler conditions.

For example, if we want the list to contain numbers that are strictly greater than 30, the filtering in the code would look like this:

kt

Main

copy
1234567
fun main() { val numbersList: List<Int> = listOf(2, 1, 5, 6, 7, 3, 4, 8, 19, 28, 48, 11, 92, 10, 2, 1, 38, 19, 34, 25, 132) val filteredNumbersList: List<Int> = numbersList.filter { it > 30 } println("Initial list: $numbersList") println("Only even numbers list: $filteredNumbersList") }

As you can see, only numbers strictly greater than 30 remain. So our filtering works successfully! Great!

Similar methods work with Sets and arrays. With a Map, we’ll need to complicate the lambda expression a bit, but it’s not difficult and works just like a for loop.

We need to specify both the key and value inside the lambda expression and then indicate what we want to filter:

kt

Main

copy
123456
fun main() { val exampleMap: Map<Int, String> = mapOf(1 to "One", 2 to "Two", 3 to "Three", 4 to "Four", 5 to "Five") val filteredMap: Map<Int, String> = exampleMap.filter { (key, value) -> key % 2 == 0 && value.length > 3} println(filteredMap) }

Here, the lambda expression is a bit more complex because it uses an arrow after defining the parameters.

We specify the key and value in parentheses, and then after the arrow (->), we provide a boolean expression that tells us the key must be even and the value must have a length strictly greater than 3.

In this way, we can use filtering on lists, arrays, sets, and maps. Great!

Note

It's okay if some points are unclear to you right now; with practice, everything will become more accessible, and you'll master all these methods perfectly!

Sorting Collections

For completeness, it's worth mentioning two important methods: sorted() and sortedDescending(). As you can infer from the names, the first method sorts a List, Array, or Set in ascending order, while the second sorts them in descending order.

The operation is incredibly simple! Let's look at an example:

kt

Main

copy
123456789
fun main() { val numbersList: List<Int> = listOf(2, 1, 5, 6, 7, 3, 4, 8, 19, 28, 48, 11, 92, 10, 2, 1, 38, 19, 34, 25, 132) val sortedListAsc: List<Int> = numbersList.sorted() val sortedListDesc: List<Int> = numbersList.sortedDescending() println("Initial list: $numbersList") println("Sorted in Ascending order: $sortedListAsc") println("Sorted in Descending order: $sortedListDesc") }

Summary

This simple approach allows us to modify, filter, and sort various types of collections!

1. What does the `.map()` function in Kotlin do?
2. How can you filter a list in Kotlin to keep only elements that are greater than 10?
What does the `.map()` function in Kotlin do?

What does the .map() function in Kotlin do?

Select the correct answer

How can you filter a list in Kotlin to keep only elements that are greater than 10?

How can you filter a list in Kotlin to keep only elements that are greater than 10?

Select the correct answer

Everything was clear?

How can we improve it?

Thanks for your feedback!

Section 2. Chapter 5
some-alt