最近用 sort.Slice 方法对 slice 作排序功能的时候遇到了一个小坑架构
先看一段代码less
package main import ( "fmt" "sort" ) func main() { people := []struct { Name string Age int }{ {"Alice", 25}, {"Elizabeth", 75}, {"Alice", 75}, {"Bob", 75}, {"Alice", 75}, {"Bob", 25}, {"Colin", 25}, {"Elizabeth", 25}, } sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name }) fmt.Println("By name:", people) sort.Slice(people, func(i, j int) bool { return people[i].Age < people[j].Age }) fmt.Println("By age:", people) }
输出ide
By name: [{Alice 25} {Alice 75} {Alice 75} {Bob 75} {Bob 25} {Colin 25} {Elizabeth 75} {Elizabeth 25}] By age: [{Alice 25} {Elizabeth 25} {Bob 25} {Colin 25} {Alice 75} {Bob 75} {Elizabeth 75} {Alice 75}]
有没有注意到一个点,按照 Age 排序的地方,相等的元素老的切片中的顺序变了,通常状况下,这种状况没什么影响,可是若是业务需求对顺序有强要求的话,这就有问题了。code
解决方案,用 sort.SliceStable 方法,sort.SliceStable 能够保持元素顺序和以前切片中的同样。排序
SliceStable sorts the provided slice given the provided less function > > while keeping the original order of equal elements.element
The function panics if the provided interface is not a slice.string
新的代码以下io
package main import ( "fmt" "sort" ) func main() { people := []struct { Name string Age int }{ {"Alice", 25}, {"Elizabeth", 75}, {"Alice", 75}, {"Bob", 75}, {"Alice", 75}, {"Bob", 25}, {"Colin", 25}, {"Elizabeth", 25}, } // Sort by name, preserving original order sort.SliceStable(people, func(i, j int) bool { return people[i].Name < people[j].Name }) fmt.Println("By name:", people) // Sort by age preserving name order sort.SliceStable(people, func(i, j int) bool { return people[i].Age < people[j].Age }) fmt.Println("By age,name:", people) }
此次的结果,按照 Age 排序,相等的元素依然保持着和以前同样的排序table
By name: [{Alice 25} {Alice 75} {Alice 75} {Bob 75} {Bob 25} {Colin 25} {Elizabeth 75} {Elizabeth 25}] By age,name: [{Alice 25} {Bob 25} {Colin 25} {Elizabeth 25} {Alice 75} {Alice 75} {Bob 75} {Elizabeth 75}]
更多架构、PHP、GO相关踩坑实践技巧请关注个人公众号 function