1. Overview

In software development, sorting a String alphabetically is often important, especially in searching and presenting data.

In this tutorial, we’ll discuss some approaches to sorting a String alphabetically in Kotlin with different scenarios and complexities.

2. Using toCharArray() and sorted()

The first way to sort a String alphabetically is the easiest, because we’ll use functions built into Kotlin. We’ll convert the string to a character array to sort it before converting the result back to a String:

private fun sortStringWithCharArrayAndSorted(input : String) : String {
    return input.toCharArray().sorted().joinToString("")
}

First, we use toCharArray() to break the String into a character array. Then, we sort this array with sorted(). Let’s see the result:

[a, b, c, d, e, f, g, h, i, j, k, l]

Next, we use joinToString() to convert the array to a String.

Now, let’s test that this function correctly alphabetizes our string:

@Test
fun `using toCharArray and then sorted`() {
    val inputString = "laibkcedfgjh"
    assertEquals("abcdefghijkl", sortStringWithCharArrayAndSorted(inputString))
}

3. Using toCharArray(), sorted(), and distinct()

Sometimes, we may want to alphabetize a string while also removing duplicate letters. We’ll use distinct(), which is Kotlin’s built-in function for removing duplicate elements from a collection. This approach is useful if the String contains some duplicate characters and we want to remove them:

private fun sortStringWithCharArrayAnddistinct(input : String) : String {
    return input.toCharArray().sorted().distinct().joinToString("")
}

Without distinct(), the output would be:

abcdefgghhhijkkkl

So, after calling toCharArray() and sorted(), we need to call distinct() to remove excess duplicate characters.

Let’s also test this function to verify it works as expected:

@Test
fun `using sorted and distinct`() {
    val inputString = "lakibkcekdghfgjhh"
    assertEquals("abcdefghijkl", sortStringWithCharArrayAnddistinct(inputString))
}

4. Using toCharArray(), sortedWith(), and compareBy()

We might need to alphabetize the vowels and consonants in a string separately. Because this is a unique way to sort, we’ll need to use sortedWith() to supply a special comparator. Then, we’ll use compareBy() to create the comparator that has our sorting criteria. This is a useful approach to sort a String with more complex criteria.

For example, we’ll sort the consonant letters first, followed by the vowels:

private fun sortStringWithtoCharArrayAndCompareBy(input: String) : String {
    val vowels = setOf('a', 'e', 'i', 'o', 'u')
    return input.toCharArray().sortedWith(compareBy<Char> { it in vowels }
            .thenBy { it }
        ).joinToString("")
}

We’ll test our custom sort as well to ensure that the consonants are first and the vowels are last, while still maintaining alphabetical order between those groupings:

@Test
fun `using compareBy`() {
    val inputString = "laibkcedfgjh"
    assertEquals("bcdfghjklaei", sortStringWithtoCharArrayAndCompareBy(inputString))
}

5. Using Extension Functions

We can take any of the approaches that we’ve discussed in the previous section and turn the solution into an extension function. This allows us to add new functions to a class or data type without modifying the original source code of that class.

For example, we can take the first solution and define an extension function named sortAsc() for the String class:

private fun String.sortAsc() = toCharArray().sorted().joinToString("")

This is the interesting thing about Kotlin. Now that we’ve defined a new extension function for a String, we can directly call it from a string literal:

"cdbae".sortAsc()

Finally, we’ll test that our extension function is sorting the string as we expect:

@Test
fun `simplify toCharArray and sorted with extension`() {
    assertEquals("abcde", "cdbae".sortAsc())
}

6. Conclusion

In this article, we’ve discussed several approaches to sorting a string alphabetically by using variations of sorted() and sortedWith(). Of course, any of these can be used based on the needs of our project. Additionally, we explored using extension functions — a powerful and expressive feature of Kotlin — for our solution.

As always, the code from this article is available over on GitHub.