1

I'm new to Kotlin and I have the following task. I have a list of objects (Album) which contains fields and a list with another object (Song). I need to sort both album and song lists with their properties. What I tried so far

albumList.onEach { it.songs.sortedByDescending { song -> song.isFavorite} 
.sortedByDescending { it.createDate }

As a result, the album list is sorted by it's createDate property but songs list doesn't. Is there something I'm missing? Thanks

6
  • Is the list of songs property a val or a var? Is it a MutableList or read-only List? Commented Apr 6, 2020 at 19:25
  • sortedBy creates a new sorted list, but does not modify the original list. You need either a MutableList and use sortBy instead of sortedBy. Or you need the songs list to be a var and you set the result of the sortedBy call back to the original property to change it. Commented Apr 6, 2020 at 19:28
  • Thank for a quick reply. My both lists are immutable. In that case why does it sort the album list but not the nested one? Commented Apr 6, 2020 at 19:48
  • I don't know how you're checking that it's sorted, but sortedBy always creates a new List instance. Commented Apr 6, 2020 at 19:49
  • Is field createDate in Album or Song? Are you planning to sort albums by createDate, and songs in EACH of album sort by isFavorite (so favourites first). Commented Apr 6, 2020 at 20:10

2 Answers 2

2

I found some "dirty" solution. I'm not so happy with that, but it works.

val newList: List<Album> = albumList
    // Sort albums
    .sortedWith(compareBy { it.createDate })
    // Sort songs inside each of albums
    .map { album ->
        album.apply {
            // Assign NEW list
            songs = album.songs.sortedWith(compareBy { it.isFavorite })
        }
    }

How it works:

1) Sort albums by date of creation createDate

2) For each of albums:

  • get all songs
  • map them to itself but only with songs sorting (assign sorted songs to songs field, so it has to be var not val)
Sign up to request clarification or add additional context in comments.

Comments

0

You can first sort the parent list, and then create a new list by using map on the first list, and inside it, you can use the copy function to set the sorted inner list.

val tempList: List<Album> = albumList
    .sortedWith(compareBy { it.createDate })
val newList = tempList.map { album ->
    val sortedSongs = album.songs.sortedWith(compareBy { it.isFavorite })
    album.copy(songs = sortedSongs)
}

This way, you can prevent using var instead of val :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.