testivanivan
testivanivan

Reputation: 1514

Kotlin. How to map only non null values of list?

I need to make some operations with my list.

For example I have list of TestData:

data class TestData (
    val value: Int?,
    val name: String
)

I need to map list of TestData to list of String. Here is my code:

 val names = listOfTestData
              .map { data -> getName(data.value) } <- Type mismatch. Required: Int, found Int?
              .distinct()

The problem is that the function getName(value: Int) accepts only a non nullable type. Can I somehow skip elements from listOfTestData whose value is null ?

I could filter the values before making a map, but I'll have to use inside the map !!, I'd like a more elegant solution.

 val names = listOfTestData
                  .filter { it.value != null }
                  .map { data -> getName(data.value!!) } 
                  .distinct()

Please tell me how can this be done without using !!

Upvotes: 0

Views: 2101

Answers (1)

Sweeper
Sweeper

Reputation: 271625

Instead of filter, you can mapNotNull to the values. This is basically a map, but if the mapping function you provide returns null, the element is filtered out.

listOfTestData.mapNotNull { it.value }
    .map { getName(it) }
    .distinct()

This will go over the list 3 times. You can combine the mapNotNull and map by using a ?.let on the value:

listOfTestData.mapNotNull { data -> data.value?.let { getName(it) } }.distinct()

Alternatively, use a sequence:

listOfTestData.asSequence()
    .mapNotNull { it.value }
    .map { getName(it) }
    .distinct()
    .toList()

Upvotes: 5

Related Questions