'How one can do case insensitive sorting using sort.Strings() in Golang?

Is there any way to pass the custom function in the sort.Strings() to do the case-insensitive sorting on the list of strings?

data := []string{"A", "b", "D", "c"}

The output should be: A, b, c, D

The equivalent of the above requirement in Python is like :

li = sorted(data, key=lambda s: s.lower())

Do we have something like that in golang?



Solution 1:[1]

You need a type that implements sort.Interface.

https://play.golang.org/p/JTm0AjuxCRV

Solution 2:[2]

The solution below is more verbose and more performant. The main difference is that in the other answers, using strings.ToLower at each comparison allocates some memory, and the code below takes care of comparing runes without creating any new string.

// lessCaseInsensitive compares s, t without allocating
func lessCaseInsensitive(s, t string) bool {
    for {
        if len(t) == 0 {
            return false
        }
        if len(s) == 0 {
            return true
        }
        c, sizec := utf8.DecodeRuneInString(s)
        d, sized := utf8.DecodeRuneInString(t)

        lowerc := unicode.ToLower(c)
        lowerd := unicode.ToLower(d)

        if lowerc < lowerd {
            return true
        }
        if lowerc > lowerd {
            return false
        }

        s = s[sizec:]
        t = t[sized:]
    }
}

sort.Slice(data, func(i, j int) bool { return lessCaseInsensitive(data[i], data[j]) })

You can see in this benchmark for example that avoiding allocs makes the case-insensitive sorting 5x faster.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nirmal Agrawal
Solution 2 Deleplace