There is an extension functions
fun List<Track>.sortByTitle(): List<Track> {
return this.sortedBy { it.title }
}
fun List<Track>.sortByArtist(): List<Track> {
return this.sortedBy { it.artists[0].name }
}
What need to write in arguments of sort
function in order to pass an extension function?
fun sortByTitle(owner: String, kind: String) {
sort(owner, kind) // pass List<Track>.sortByTitle
}
fun sortByArtist(owner: String, kind: String) {
sort(owner, kind) // pass List<Track>.sortByArtist
}
private fun sort(owner: String, kind: String) {
val remote = playlist.get(owner, kind)
val tracks = // call extension function: remote.tracks.sortByTitle()
// ...
}
CodePudding user response:
We can pass functions using function types, for example:
fun sortByTitle(owner: String, kind: String) {
sort(owner, kind, List<Track>::sortByTitle)
}
fun sortByArtist(owner: String, kind: String) {
sort(owner, kind, List<Track>::sortByArtist)
}
private fun sort(owner: String, kind: String, sortStrategy: List<Track>.() -> List<Track>) {
val remote = playlist.get(owner, kind)
val tracks = remote.tracks.sortStrategy()
// ...
}
In the above example List<Track>.() -> List<Track>
means: function that is an extension over List<Track>
and returns List<Track>
.
CodePudding user response:
Not really sure, what you want to do there.
I'd suggest to use something like:
val theSortedList = listOfTracks.filter { it.title == "two" }.sortByArtist()
anyway, to pass an extension function as argument to another function and call it from there, here is some example code in your context:
fun List<Track>.sortByTitle(): List<Track> {
return this.sortedBy { it.title }
}
fun List<Track>.sortByArtist(): List<Track> {
return this.sortedBy { it.artists[0].name }
}
fun main() {
println("sortByTitle")
val titleTracks = sort("somebody", "somekind", List<Track>::sortByTitle)
titleTracks.forEach { println("${it.title}: ${it.artists.map { it.name }.joinToString()}") }
println()
println("sortByArtist")
val artistTracks = sort("somebody", "somekind", List<Track>::sortByArtist)
artistTracks.forEach { println("${it.title}: ${it.artists.map { it.name }.joinToString()}") }
}
fun sort(owner: String, kind: String, function: List<Track>.() -> List<Track>): List<Track> {
val listOfTracks = listOf<Track>(
Track("two", listOf(Artist("Madonna"), Artist("Beethoven"))),
Track("one", listOf(Artist("Prince"), Artist("Elvis"))),
)
var sortedTracks: List<Track>
sortedTracks = function.invoke(listOfTracks)
// another way to invoke the function:
sortedTracks = listOfTracks.function()
return sortedTracks
}
data class Playlist(val name: String) {
fun get(artist: Artist, kind: String): List<Artist> = listOf()
fun tracks(): List<Track> = listOf()
}
data class Track(val title: String, val artists: List<Artist>)
data class Artist(val name: String)