umeshbhat
umeshbhat

Reputation: 113

how can i sort elements of a list which are string by using filter in kotlin? whats wrong in my approach?

val spices = listOf("curry", "pepper", "cayenne", "ginger", "red curry", "green curry", "red pepper" )    
spices.filter { it }.sortedBy { it.length }

error: type inference failed: inline fun Iterable.filter(predicate: (T) -> Boolean): List cannot be applied to receiver: List arguments: ((String) -> String)

spices.filter { it }.sortedBy { it.length } ^ error: type mismatch: inferred type is (String) -> String but (String) -> Boolean was expected spices.filter { it }.sortedBy { it.length }

Upvotes: 0

Views: 5082

Answers (5)

Q_D_S
Q_D_S

Reputation: 1

"filter" needs a Boolean expression ,So If you insist on using "filter" to sort the list ,you should make a predicate.

val spices = mutableListOf<String>("curry", "pepper", "cayenne", "ginger", "red curry", "green curry", "red pepper" )    
spices.filter { it.isNotEmpty() }.sortedBy { it.length }

Otherwise you could get rid of "filter" and use "sortedBy" directly

Upvotes: 0

madfree
madfree

Reputation: 141

I'm doing the same course and what worked for me was:

spices.filter { it.contains("curry") }.sortedBy { it.length }.reversed()

It will first look for all the entries with "curry", than sort it by shortest to longest and then you simply reverse the order.

Upvotes: 2

Bertus
Bertus

Reputation: 21

the second line of code should be:

val curry = spices.filter { it.contains("curry", true) }

On top of that we need the curry list to be sorted bij length. Using the (.) operator and sortedBy() gives an error:

val currySorted = spices.filter { it.contains("curry", true) }.sortedBy { it.length }

Is there a way to sort the filtered list in one go?

Update: the .sortedBy method works fine. The display of the result is weird in REPL:

for (i in 0..currySorted.size-1) println(currySorted[i])

gives the following result in REPL: Curryred currygreen curry

Watching more precisely it is ordered! but REPL contatinates the strings in the output: Curry, Red curry, green curry

By the way, this assignment comes from the Kotlin Bootcamp course by Udacity

Upvotes: 2

Zoe - Save the data dump
Zoe - Save the data dump

Reputation: 28238

filter requires a predicate returning a boolean. See the declaration:

public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
    return filterTo(ArrayList<T>(), predicate)
}

(T) -> Boolean means it returns a boolean and takes an input of type T. T is it in this case.

A string is not a boolean. If you actually have a List of Booleans though, you could do this:

val list = listOf(true, true, false, true, true, false )
val sortedList = list.filter{ it }

and it would be valid, because it is a boolean. However, with all other types, you need to convert it to a boolean operation, if you intend to do filtering.

However, since you don't actually seem to do any filtering, just remove it and do this:

val sortedList = spices.sortedBy { it.length }

and if you have to filter it somehow, make sure you get a boolean operation or value.

In order to actually sort it, you have to do something with the value sortedBy. In my example, I assign it to a new field, but you can also assign it to the previous field. However, if you do this, you have to make it a var and not a val.

Upvotes: 3

user8959091
user8959091

Reputation:

Filter needs a predicate inside brackets, it is not a predicate. You don't need filter to sort the list

Just do:

val spices = mutableListOf<String>("curry", "pepper", "cayenne", "ginger", "red curry", "green curry", "red pepper" )
spices.sortBy { it.length }

Also change from listOf to mutableListOf

Upvotes: 1

Related Questions