Golang 使用 sort 對切片排序須要注意的一個點

最近用 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

相關文章
相關標籤/搜索