Home > Blockchain >  Kotlin sort one List with key and Enum with key and order
Kotlin sort one List with key and Enum with key and order

Time:05-07

I receive data from Request information as list data (List) below code. That data has a "key" parameter by which I want to sort it.

data class ApplianceSetting(
    @SerializedName("key") val key: String,
    @SerializedName("value") var value: Any,
    (...)

I have the required order in the SettingsUtilEnum and want to sort items by that.

After that, I can convert the list using map{} the data and use the function of Enum getSettingByMode() and get the list of Enum values. Then I will sort them and convert them again to List. But that sounds too inefficient. Is there a better way.

enum class SettingsUtilEnum(
   var settingKey: String,
   override val order: Int = 99,
   var settingName: String = "",
) : AbstractOrderEnum {

FIRST_MODE("first.mode", 0),
SECOND_MODE("second.mode", 1),
(...)
UNKNOWN_MODE("", 99);

companion object {
    @JvmStatic
    fun getSettingByMode(settingKey: String): SettingsUtilEnum? {
        return values().find { it.settingKey == settingKey }
    }

k

 private fun initDataObserver() {
    (activity as FavouriteActivity).viewModel.applianceSettings.observe(activity as FavouriteActivity
    ) { data ->
        (controlRecyclerView.adapter as FavouriteAdditionalControlsAdapter)
        val adapter = (controlRecyclerView.adapter as FavouriteAdditionalControlsAdapter)
        // public final var data: List<ApplianceSetting>

        // old code:
            // data.settings
        adapter.data = sortAndGetControlModes(data)

        adapter.notifyDataSetChanged()
    }
}

// TODO: sortAndGetControlModes
private fun sortAndGetControlModes(data: ApplianceSettingsList) =
    data.settings.map {
        getSettingByMode(it.key)
            ?: UNKNOWN_MODE.apply {
                // If in future new modes are added -> put them as tail
                settingKey = it.key
            }
    }.sortedBy { it.order }
    // error i need to return again List<ApplianceSetting>

enter image description here

CodePudding user response:

I fixed it using sortedBy and as comparator I am using received value from getSettingByMode(), if item is not found (null) I give him order value of 99:

    private fun sortAndGetControlModes(data: ApplianceSettingsList) =
         data.settings.sortedBy { 
             getSettingByMode(it.key)?.order ?:99 
         }

CodePudding user response:

If you want to compare keys with theirs ASCII values you can just use sortBy { it.key }

If you want to expand possibilities of comparison you can use function sortedWith with passing custom comparator as argument.

Comparator used to compare its two arguments for order. Returns zero if the arguments are equal, a negative number if the first argument is less than the second, or a positive number if the first argument is greater than the second.

Example: You can use it like that if you want to sort by integer value of key parameter:

data.settings.sortedWith { a, b ->
      when {
            a.key.toInt() < b.key.toInt() -> -1
            a.key.toInt() > b.key.toInt() -> 1
            else -> 0
      }
}
  • Related