參見博客:https://blog.csdn.net/u010983881/article/details/52460998
package main import ( "sort" "fmt" ) /* Go 的排序思路和 C 和 C++ 有些差別。 1.C 默認是對數組進行排序 2.C++ 是對一個序列進行排序 3.Go 待排序的可以是任何對象, 雖然很多情況下是一個 slice (分片, 類似於數組),或是包含 slice 的一個對象。 排序(接口)的三個要素: 1.待排序元素個數 n ; 2.第 i 和第 j 個元素的比較函數 cmp ; 3.第 i 和 第 j 個元素的交換 swap ; 乍一看條件 3 是多余的, c 和 c++ 都不提供 swap 。 c 的 qsort 的用法: qsort(data, n, sizeof(int), cmp_int); data 是起始地址, n 是元素個數, sizeof(int) 是每個元素的大小, cmp_int 是一個比較兩個 int 的函數。 c++ 的 sort 的用法: sort(data, data+n, cmp_int); data 是第一個元素的位置, data+n 是最后一個元素的下一個位置, cmp_int 是比較函數。 */ /* 基本類型排序 */ /* 1.升序排序 說明:對於int、float64、string數組/分片的排序, go分別提供sort.Ints()、sort.Float64s()、sort.Strings()函數(默認從小->大排序) */ func upSort(){ intList := [] int {2, 4, 3, 5, 7, 6, 9, 8, 1, 0} float8List := [] float64 {4.2, 5.9, 12.3, 10.0, 50.4, 99.9, 31.4, 27.81828, 3.14} stringList := [] string {"a", "c", "b", "d", "f", "i", "z", "x", "w", "y"} sort.Ints(intList) sort.Float64s(float8List) sort.Strings(stringList) fmt.Printf("%v\n%v\n%v\n",intList,float8List,stringList) /* 打印結果: [0 1 2 3 4 5 6 7 8 9] [3.14 4.2 5.9 10 12.3 27.81828 31.4 50.4 99.9] [a b c d f i w x y z] */ } /* 2.降序排序 */ func downSort(){ intList := [] int {2, 4, 3, 5, 7, 6, 9, 8, 1, 0} float8List := [] float64 {4.2, 5.9, 12.3, 10.0, 50.4, 99.9, 31.4, 27.81828, 3.14} stringList := [] string {"a", "c", "b", "d", "f", "i", "z", "x", "w", "y"} sort.Sort(sort.Reverse(sort.IntSlice(intList))) sort.Sort(sort.Reverse(sort.Float64Slice(float8List))) sort.Sort(sort.Reverse(sort.StringSlice(stringList))) fmt.Printf("%v\n%v\n%v\n", intList, float8List, stringList) /* 打印結果: [9 8 7 6 5 4 3 2 1 0] [99.9 50.4 31.4 27.81828 12.3 10 5.9 4.2 3.14] [z y x w i f d c b a] */ } /* 3.深度理解排序 sort 包中有一個 sort.Interface 接口,該接口有三個方法 Len() 、 Less(i,j) 和 Swap(i,j) 。 通用排序函數 sort.Sort 可以排序任何實現了 sort.Inferface 接口的對象(變量)。 對於 [] int 、[] float64 和 [] string 除了使用特殊指定的函數外, 還可以使用改裝過的類型 IntSclice 、 Float64Slice 和 StringSlice , 然后直接調用它們對應的 Sort() 方法;因為這三種類型也實現了 sort.Interface 接口, 所以可以通過 sort.Reverse 來轉換這三種類型的 Interface.Less 方法來實現逆向排序, 這就是前面最后一個排序的使用。 下面使用了一個自定義(用戶定義)的 Reverse 結構體, 而不是 sort.Reverse 函數, 來實現逆向排序。 */ // 自定義的 Reverse 類型 type Reverse struct { sort.Interface //這樣,Reverse可以接納任何實現了sort.Interface的對象 } // Reverse 只是將其中的 Inferface.Less 的順序對調了一下 func (r Reverse) Less(i, j int) bool { return r.Interface.Less(j, i) } //自定義排序 func selfDefineSort(){ ints := []int{5, 2, 6, 3, 1, 4} sort.Ints(ints) // 特殊排序函數,升序 fmt.Println("after sort by Ints:\t", ints) doubles := []float64{2.3, 3.2, 6.7, 10.9, 5.4, 1.8} sort.Float64s(doubles) fmt.Println("after sort by Float64s:\t", doubles) // [1.8 2.3 3.2 5.4 6.7 10.9] strings := []string{"hello", "good", "students", "morning", "people", "world"} sort.Strings(strings) fmt.Println("after sort by Strings:\t", strings) // [good hello mornig people students world] ipos := sort.SearchInts(ints, -1) // int 搜索 fmt.Printf("pos of 5 is %d th\n", ipos) dpos := sort.SearchFloat64s(doubles, 20.1) // float64 搜索 fmt.Printf("pos of 5.0 is %d th\n", dpos) fmt.Printf("doubles is asc ? %v\n", sort.Float64sAreSorted(doubles)) doubles = []float64{3.5, 4.2, 8.9, 100.98, 20.14, 79.32} // sort.Sort(sort.Float64Slice(doubles)) // float64 排序方法 2 // fmt.Println("after sort by Sort:\t", doubles) // [3.5 4.2 8.9 20.14 79.32 100.98] (sort.Float64Slice(doubles)).Sort() // float64 排序方法 3 fmt.Println("after sort by Sort:\t", doubles) // [3.5 4.2 8.9 20.14 79.32 100.98] sort.Sort(Reverse{sort.Float64Slice(doubles)}) // float64 逆序排序 fmt.Println("after sort by Reversed Sort:\t", doubles) // [100.98 79.32 20.14 8.9 4.2 3.5] } /* 4.結構體類型排序 結構體類型的排序是通過使用 sort.Sort(slice) 實現的, 只要 slice 實現了 sort.Interface 的三個方法就可以。 */ /* (1)模擬IntSlice排序 缺點: 根據 Age 排序需要重新定義 PersonSlice 方法,綁定 Len 、 Less 和 Swap 方法, 如果需要根據 Name 排序, 又需要重新寫三個函數; 如果結構體有 4 個字段,有四種類型的排序,那么就要寫 3 × 4 = 12 個方法, 即使有一些完全是多余的; 根據不同的標准 Age 或是 Name,真正不同的體現在 Less 方法上,所以可以將 Less 抽象出來, 每種排序的 Less 讓其變成動態的.見(2) */ type Person struct { Name string Age int } //按照Person.Age從大-》小排序(PersonSlice是person[]的模版) type PersonSlice [] Person //重寫len()方法 func(a PersonSlice) Len() int{ return len(a) } //重寫Swap()方法 func (a PersonSlice) Swap(i,j int){ a[i],a[j]=a[j],a[i] } //重寫Less()方法 func (a PersonSlice) Less(i,j int ) bool{ return a[j].Age < a[i].Age } func IntSliceSort(){ people:=[] Person{ {"zhang san", 12}, {"li si", 30}, {"wang wu", 52}, {"zhao liu", 26}, } fmt.Println(people) //[{zhang san 12} {li si 30} {wang wu 52} {zhao liu 26}] sort.Sort(PersonSlice(people)) //按照 Age 的逆序排序 fmt.Println(people) //[{wang wu 52} {li si 30} {zhao liu 26} {zhang san 12}] sort.Sort(sort.Reverse(PersonSlice(people))) //按照 Age 的升序排序 fmt.Println(people)//[{zhang san 12} {zhao liu 26} {li si 30} {wang wu 52}] } /* (2)封裝成 Wrapper */ type Person2 struct { Name string Age int } type PersonWrapper2 struct { //注意此處 people [] Person2 by func(p,q * Person2) bool } func (pw PersonWrapper2) Len() int {//重寫len()方法 return len(pw.people) } func (pw PersonWrapper2) Swap(i,j int){ //重寫Swap()方法 pw.people[i],pw.people[j]=pw.people[j],pw.people[i] } func (pw PersonWrapper2) Less(i,j int) bool{//重寫Less()方法 return pw.by(&pw.people[i], &pw.people[j]) } func wrapperSort(){ people := [] Person2{ {"zhang san", 12}, {"li si", 30}, {"wang wu", 52}, {"zhao liu", 26}, } fmt.Println(people) sort.Sort(PersonWrapper2{people, func (p, q *Person2) bool { return q.Age < p.Age // Age 遞減排序 }}) fmt.Println(people) sort.Sort(PersonWrapper2{people, func (p, q *Person2) bool { return p.Name < q.Name // Name 遞增排序 }}) fmt.Println(people) /* 執行結果: [{zhang san 12} {li si 30} {wang wu 52} {zhao liu 26}] [{wang wu 52} {li si 30} {zhao liu 26} {zhang san 12}] [{li si 30} {wang wu 52} {zhang san 12} {zhao liu 26}] */ } /* (3)進一步封裝 */ type Person3 struct { Name string Age int } type PersonWrapper3 struct { people [] Person3 by func(p, q * Person3) bool } type SortBy func(p, q *Person3) bool func (pw PersonWrapper3) Len() int { // 重寫 Len() 方法 return len(pw.people) } func (pw PersonWrapper3) Swap(i, j int){ // 重寫 Swap() 方法 pw.people[i], pw.people[j] = pw.people[j], pw.people[i] } func (pw PersonWrapper3) Less(i, j int) bool { // 重寫 Less() 方法 return pw.by(&pw.people[i], &pw.people[j]) } // 封裝成 SortPerson 方法 func SortPerson(people [] Person3, by SortBy){ sort.Sort(PersonWrapper3{people, by}) } func wrapperSorts(){ people := [] Person3{ {"zhang san", 12}, {"li si", 30}, {"wang wu", 52}, {"zhao liu", 26}, } fmt.Println(people) sort.Sort(PersonWrapper3{people, func (p, q *Person3) bool { return q.Age < p.Age // Age 遞減排序 }}) fmt.Println(people) SortPerson(people, func (p, q *Person3) bool { return p.Name < q.Name // Name 遞增排序 }) fmt.Println(people) /* 運行結果: [{zhang san 12} {li si 30} {wang wu 52} {zhao liu 26}] [{wang wu 52} {li si 30} {zhao liu 26} {zhang san 12}] [{li si 30} {wang wu 52} {zhang san 12} {zhao liu 26}] */ } func main(){ fmt.Println("升序==========") upSort() //升序 fmt.Println("降序==========") downSort() fmt.Println("模擬IntSlice排序==========") IntSliceSort() fmt.Println("封裝成wrapper排序==========適合項目應用") wrapperSort() fmt.Println("更深層封裝成wrapper排序==========適合項目應用") wrapperSorts() }
項目應用:
對返回的結果按照狀態status(good/revoke)排序
【1】結構體文件xx.go
//utils.go type AuthUserInfo struct{ Status string `json:"status"` ... } //自定義排序 注意大寫,其他文件可訪問 type AuthUserInfoWrapper struct { AuthInfo [] AuthUserInfo By func(p,q * AuthUserInfo) bool } func (au AuthUserInfoWrapper) Len() int{ return len(au.AuthInfo) } func (au AuthUserInfoWrapper) Swap(i,j int) { au.AuthInfo[i],au.AuthInfo[j]=au.AuthInfo[j],au.AuthInfo[i] } func (au AuthUserInfoWrapper) Less(i,j int) bool{ return au.By(&au.AuthInfo[i],&au.AuthInfo[j]) }
【2】業務文件xx.go
//代碼片斷 var authUse []utils.AuthUserInfo authUse = make([]utils.AuthUserInfo, 10) //authUse賦值 //排序 sort.Sort(utils.AuthUserInfoWrapper{authUse, func(p, q *utils.AuthUserInfo) bool { return p.Status<q.Status }})
注意:大寫。上述
type AuthUserInfoWrapper struct { AuthInfo [] AuthUserInfo By func(p,q * AuthUserInfo) bool }
若不大寫。會報錯:implicit assignment of unexported field 。訪問不到異常。
