Golang sort.Strings函数未正确排序字符串切片问题排查
Go Map键排序不符合预期的原因及解决方法
问题说明
编写了如下Go代码:
m := map[string][]string{ "LaptopPro": {"M1-pro", "M2"}, "Speaker": {"klipsch"}, "dev": {"ddd"}, "dv": {"ddd"}, "laptop": {"m1", "m2"}, "laptop99": {"m1", "m2"}, } keys := make([]string, 0, len(m)) for k := range m { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { fmt.Println(k, m[k]) }
得到的输出结果:
LaptopPro [M1-pro M2] Speaker [klipsch] dev [ddd] dv [ddd] laptop [m1 m2] laptop99 [m1 m2]
该排序结果未符合预期,以下是原因分析和解决办法:
原因分析
sort.Strings函数采用ASCII字典序排序,而ASCII编码规则中:
- 大写字母(A-Z)的编码值范围是65-90
- 小写字母(a-z)的编码值范围是97-122
所有大写字母的ASCII值都小于小写字母,因此大写开头的键(LaptopPro、Speaker)会被排在小写开头的键(dev、dv、laptop)之前,这就是当前排序结果的核心原因。
解决方法
如果需要实现不区分大小写的自然排序,可以使用sort.Slice自定义排序逻辑,借助strings.EqualFold实现大小写无关的字符串比较:
sort.Slice(keys, func(i, j int) bool { return strings.EqualFold(keys[i], keys[j]) })
将这段代码替换原代码中的sort.Strings(keys),运行后输出会变成符合常规认知的排序结果:
dev [ddd] dv [ddd] LaptopPro [M1-pro M2] laptop [m1 m2] laptop99 [m1 m2] Speaker [klipsch]
内容的提问来源于stack exchange,提问作者Zeinab Abbasimazar
相关产品推荐
相关产品推荐

