I want the strings to be sorted alphabetically with control over whether "A" comes before "a".
In the Less() function using strings.ToLower() doesn't achieve this. Sometimes "A" comes before "a", and sometimes after.
instead of comparing the entire string using strings.ToLower
, compare the individual runes.
https://play.golang.org/p/RUMlmrb7C3g
type ByCase []string
func (s ByCase) Len() int { return len(s) }
func (s ByCase) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s ByCase) Less(i, j int) bool {
iRunes := []rune(s[i])
jRunes := []rune(s[j])
max := len(iRunes)
if max > len(jRunes) {
max = len(jRunes)
}
for idx := 0; idx < max; idx++ {
ir := iRunes[idx]
jr := jRunes[idx]
lir := unicode.ToLower(ir)
ljr := unicode.ToLower(jr)
if lir != ljr {
return lir < ljr
}
// the lowercase runes are the same, so compare the original
if ir != jr {
return ir < jr
}
}
// If the strings are the same up to the length of the shortest string,
// the shorter string comes first
return len(iRunes) < len(jRunes)
}