https://kotlinlang.org logo
Title
k

KotlinLeaner

04/27/2023, 1:09 PM
Hi guys, I have a data which is coming from the server and it can be
null
or
empty
. I tried to filter basic to avoid null code and replace with
empty
1️⃣
fun filterMovieItemList(unfilteredList: List<MovieItem>): List<MovieItemModel> {
    val movieItemModelList = mutableListOf<MovieItemModel>()
    if (unfilteredList.isNotEmpty()) {
        unfilteredList.forEachIndexed { _, movieItem ->
            val movieDetails = movieItem.movieDetails
            if (movieDetails != null && !movieDetails.name.isNullOrEmpty()) {
                val icon = movieDetails.iconUrl ?: "xyz"
                movieItemModelList.add(
                    MovieItemModel(
                        movieDetails.name,
                        icon,
                        movieDetails.summary ?: "",
                    )
                )
            }
        }
    }
    return movieItemModelList
}
Now I am trying to make more readable to use
map
, but I am not sure this is correct way so please free to suggest new and improve version
2️⃣
fun filterMapMovieItemList(unfilteredList: List<MovieItem>): List<MovieItemModel> {
    return unfilteredList.mapNotNull { data ->
        data.movieDetails?.name?.let {
            data.movieDetails
        }
    }.map { movieItem ->
        val icon = movieItem.iconUrl ?: "xyz"
        MovieItemModel(
            name = movieItem.name ?: "",
            icon = icon,
            summary = movieItem.summary ?: ""
        )
    }
}
Thanks
l

Luke

04/27/2023, 1:20 PM
I would do something like this:
return unfilteredList.asSequence()
        .mapNotNull { it.movieDetails }
        .filterNot { it.name.isNullOrEmpty() }
        .map { movieDetails ->
            MovieItemModel(
                movieDetails.name.orEmpty(),
                movieDetails.iconUrl ?: "xyz",
                movieDetails.summary.orEmpty(),
            )
        }
        .toList()
k

KotlinLeaner

04/27/2023, 1:21 PM
As for general knowledge what is the
asSequence()
do? what are the benefits will get?
f

franztesca

04/27/2023, 1:22 PM
To avoid the fact that we have to account for a nullable name when it is already filtered out, I'd do:
fun filterMovieItemList(unfilteredList: List<MovieItem>): List<MovieItemModel> =
    unfilteredList.mapNotNull { it.movieDetails?.toMovieItemModelOrNull() }

fun MovieItemDetails.toMovieItemModelOrNull(): MovieItemModel? = 
    if (name.isNullOrEmpty()) {
        null 
    } else {
        MovieItemModel(
            name,
            iconUrl ?: "xyz",
            summary ?: "",
        )
    }
l

Luke

04/27/2023, 1:23 PM
It transform the
List
in a
Sequence
. It's not mandatory but the difference with
List
is that, when chaining calls (.filter, .map, etc), you don't intanciate a new
List
at each step
More info here
k

KotlinLeaner

04/27/2023, 1:27 PM
when we convert the
List
to
Sequence
. Does it will impact on performances?
l

Luke

04/27/2023, 1:36 PM
No, it just uses its iterator
k

KotlinLeaner

04/27/2023, 1:37 PM
perfect thanks...
Another thing
.mapNotNull { it.movieDetails }
        .filterNot { it.name.isNullOrEmpty() }
how does it work ?
.mapNotNull { it.movieDetails }
i.e. First it loop in all items that
movieDetails
is not null and convert into
Sequence
. Second
.filterNot { it.name.isNullOrEmpty() }
this will again go to whole list to find
name
is not
null
or
empty
and create a sequence.
or just when
iterator
it will do together?
I know this is very dump question...
l

Luke

04/27/2023, 2:37 PM
1. `unfilteredList.asSequence()`: Transform the List in a Sequence 2. `.mapNotNull { it.movieDetails }`: Iterate only over movieDetails, ignore those who are null 3. `filterNot { it.name.isNullOrEmpty() }`: Ignore values (movieDetails) with null names or empty names. 4. `.map { ... }`: Convert values (movieDetails with a name) to a MovieItemModel instance 5. `.toList()`: Execute the Sequence iteration an save each items that went through all steps in a list
k

KotlinLeaner

04/27/2023, 2:43 PM
perfect thanks a million. I got it now...