英文:
In Golang, how can I sort a list of strings alphabetically without completely ignoring case?
问题
我希望字符串按字母顺序排序,并且可以控制是否将"A"排在"a"之前。
在Less()函数中使用strings.ToLower()无法实现这一点。有时候"A"会排在"a"之前,有时候会排在之后。
英文:
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.
答案1
得分: 6
而不是使用strings.ToLower
比较整个字符串,可以比较单个符文。
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
}
}
// 如果字符串在最短字符串的长度范围内相同,则较短的字符串排在前面
return len(iRunes) < len(jRunes)
}
你需要翻译的内容已经翻译完毕,请确认是否满意。
英文:
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)
}
答案2
得分: 5
这可能是一个解决方案:
package main
import (
"strings"
"sort"
"fmt"
)
var listOfStrings []string = []string{
"mars bar",
"milk-duds",
"Mars bar",
"milk",
"milky-way",
"Milk",
"Milky-way",
"mars",
}
type Alphabetic []string
func (list Alphabetic) Len() int { return len(list) }
func (list Alphabetic) Swap(i, j int) { list[i], list[j] = list[j], list[i] }
func (list Alphabetic) Less(i, j int) bool {
var si string = list[i]
var sj string = list[j]
var si_lower = strings.ToLower(si)
var sj_lower = strings.ToLower(sj)
if si_lower == sj_lower {
return si < sj
}
return si_lower < sj_lower
}
func main() {
fmt.Println("UNSORTED")
printStrings(listOfStrings)
sort.Sort(Alphabetic(listOfStrings))
fmt.Println()
fmt.Println("SORTED ALPHABETICALLY")
printStrings(listOfStrings)
}
func printStrings(slice []string) {
for i := 0; i < len(slice); i++ {
fmt.Println(slice[i])
}
}
以下是输出结果:
UNSORTED
mars bar
milk-duds
Mars bar
milk
milky-way
Milk
Milky-way
mars
SORTED ALPHABETICALLY
mars
Mars bar
mars bar
Milk
milk
milk-duds
Milky-way
milky-way
英文:
This may be a solution:
package main
import (
"strings"
"sort"
"fmt"
)
var listOfStrings []string = []string{
"mars bar",
"milk-duds",
"Mars bar",
"milk",
"milky-way",
"Milk",
"Milky-way",
"mars",
}
type Alphabetic []string
func (list Alphabetic) Len() int { return len(list) }
func (list Alphabetic) Swap(i, j int) { list[i], list[j] = list[j], list[i] }
func (list Alphabetic) Less(i, j int) bool {
var si string = list[i]
var sj string = list[j]
var si_lower = strings.ToLower(si)
var sj_lower = strings.ToLower(sj)
if si_lower == sj_lower {
return si < sj
}
return si_lower < sj_lower
}
func main() {
fmt.Println("UNSORTED")
printStrings(listOfStrings)
sort.Sort(Alphabetic(listOfStrings))
fmt.Println()
fmt.Println("SORTED ALPHABETICALLY")
printStrings(listOfStrings)
}
func printStrings(slice []string) {
for i := 0; i < len(slice); i++ {
fmt.Println(slice[i])
}
}
Here's the output:
UNSORTED
mars bar
milk-duds
Mars bar
milk
milky-way
Milk
Milky-way
mars
SORTED ALPHABETICALLY
mars
Mars bar
mars bar
Milk
milk
milk-duds
Milky-way
milky-way
答案3
得分: 1
这是一个使用strings.Map
的Unicode友好方法:
package main
import (
"fmt"
"sort"
"strings"
"unicode"
)
type slice struct { sort.StringSlice }
func (s slice) Less(d, e int) bool {
t := strings.Map(unicode.ToUpper, s.StringSlice[d])
u := strings.Map(unicode.ToUpper, s.StringSlice[e])
return t < u
}
func main() {
a := slice{
sort.StringSlice{"a", "b", "A", "B"},
}
sort.Sort(a)
fmt.Println(a.StringSlice) // [a A b B]
}
https://golang.org/pkg/strings#Map
英文:
Heres a Unicode friendly method that utilizes strings.Map
:
package main
import (
"fmt"
"sort"
"strings"
"unicode"
)
type slice struct { sort.StringSlice }
func (s slice) Less(d, e int) bool {
t := strings.Map(unicode.ToUpper, s.StringSlice[d])
u := strings.Map(unicode.ToUpper, s.StringSlice[e])
return t < u
}
func main() {
a := slice{
sort.StringSlice{"a", "b", "A", "B"},
}
sort.Sort(a)
fmt.Println(a.StringSlice) // [a A b B]
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论