Home > OS >  Sort items in list alphabetically
Sort items in list alphabetically

Time:09-29

I am trying to sort this list alphabetically, but it's not working. Any ideas?

Here's my code:

items = dataList.groupBy { it.category }
    .map {
        listOf(
            Header(
                "res.Strings.customName${it.key.name}" ?: it.key.name
            )
        ).also {
            it.sortedBy { it.title }
        }
    }

items is a List<Any>

My dataList is a list of object;

data class Object(
val category: Enum,
val list: List<AnotherObject>
)

I try to display a list divided to categories:

Category1
 Item1
 ...
Category2
 Item1
 ... 

etc.

I want to sort Categories alphabetically.

CodePudding user response:

sortedBy does not sort in-place, it returns a new List: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sorted-by.html

also returns the original object (it), not the return value of the lambda, if you use let (https://kotlinlang.org/docs/scope-functions.html#let) it should work as that will return the result of it.sortedBy.

Alternatively you could keep also, map to a MutableMap and sort in-place, but that would probably be needless complication here.

CodePudding user response:

You can sort the list alpabetically like below

val list = mutableListOf<String>()
list.add("c")
list.add("b")
list.add("a")
val sortedList = list.sortedWith(compareBy { it })
print(sortedList)

output:[a,b,c]

For your problem replace compareBy{it} with compareBy{it.category}

CodePudding user response:

EDIT: given your edited question, it seems like you're looking for something much simpler (no Header object here):

val items = dataList.sortedBy { it.category.name }

This will give you an ordered list of your so called Object class. If you want to also convert these elements to Header instances, you can use map afterwards, but remember that you'll need to keep the list of elements as well in your objects (which you are not doing in your original code)


Original answer

There are multiple incorrect things here:

  1. sortedBy is used on a list of one single Header element, so it basically does nothing
  2. sortedBy returns a new sorted list, so even if applied to the correct list, you're not using its result because you use also (which doesn't return the result of the lambda)
  3. you're not using the values of your initial list in any way, just their categories, so you might as well forget groupBy and just extract the categories
items = dataList.groupBy { it.category }
    .map { // here it.key is a category and it.value (the list of items) is never used
        listOf( // creates a list of a single element of type Header
            Header(
                // this elvis operator is never used because the string is never null
                "res.Strings.customName${it.key.name}" ?: it.key.name
            )
        ).also { // will return the "unsorted" list of one Header element
            // returns the "sorted" 1-element list (so the same list) 
            // but the result is ignored anyway by also{}
            it.sortedBy { it.title }
        }
    }

It's a bit difficult to get what you're trying to achieve, but assuming you want to extract categories and build a sorted Headers list out of it, here is what you could do:

items = dataList.map { Header("res.Strings.customName${it.category.name}") }
                .sortedBy { it.title }

  • Related