Search code examples
ioskotlinkotlin-multiplatform

Sorting a list with Collator in Kotlin Multiplatform Mobile


Assume I have a list of names with polish diacritics signs:

listOf("Zosia", "Łucja", "Asia")

I want to sort it and achieve the result like:

[Asia, Łucja, Zosia]

I can perform it with Collator in kotlin like this:

listOf.sortedWith { s1, s2 ->
        Collator.getInstance(Locale("pl", "PL")).compare(s1, s2)
    }

Unfortunately, I cannot use the above code in commonMain module, because the Collator and Locale class is unreachable there. So I decided to create expect/actual functions but I don't know how to implement it for the iOS version.

In Swift I could write:

listOf.sorted { $0.localizedCompare($1) == .orderedAscending }

but it's not helpful for kotlin implementation in iosMain module.

So, how to sort a list with Collator for iOS in KMM?


Solution

  • In your iosMain you can use localizedCompare it is method of NSString class. You just need to import it from platform.Foundation

    import platform.Foundation.NSString
    import platform.Foundation.localizedCompare
    
    fun List<String>.sortedLocaleAware(): List<String> {
        return sortedWith { s1, s2 ->
            (s1 as NSString).localizedCompare(s2).toInt()
        }
    }
    

    You'll get compiler warning because of cast to NSString it will tell you that this cast never succeeds. But that's OK, it's recommended way from Kotlin documentation.

    You can suppress it with @Suppress("CAST_NEVER_SUCCEEDS")