1. Overview
Package sort provides primitives for sorting slices and user-defined collections.
切片排序,或者是自定義集合的排序。
例子的話我覺得還是儘量看官方的,認準pkg.go.dev ,其他家博客的話例子舉得不是很恰當。
我的話基本就是抄官方,加入一些自己的理解。
2. 實現
package main
import (
"fmt"
"sort"
)
type Person struct {
Name string
Age int
}
func (p Person) String() string {
return fmt.Sprintf("%s: %d", p.Name, p.Age)
}
// ByAge implements sort.Interface for []Person based on
// the Age field.
type ByAge []Person
func (a ByAge) Len() int { return len(a) }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func main() {
people := []Person{
{"Bob", 31},
{"John", 42},
{"Michael", 17},
{"Jenny", 26},
}
fmt.Println(people)
// There are two ways to sort a slice. First, one can define
// a set of methods for the slice type, as with ByAge, and
// call sort.Sort. In this first example we use that technique.
sort.Sort(ByAge(people))
fmt.Println(people)
// The other way is to use sort.Slice with a custom Less
// function, which can be provided as a closure. In this
// case no methods are needed. (And if they exist, they
// are ignored.) Here we re-sort in reverse order: compare
// the closure with ByAge.Less.
sort.Slice(people, func(i, j int) bool {
return people[i].Age > people[j].Age
})
fmt.Println(people)
}
主要是利用sort.Sort ,
// Sort sorts data.
// It makes one call to data.Len to determine n, and O(n*log(n)) calls to
// data.Less and data.Swap. The sort is not guaranteed to be stable.
func Sort(data Interface) {
n := data.Len()
quickSort(data, 0, n, maxDepth(n))
}
主要是接收一個data interface的,然後調用quickSort(這裏的quickSort並不是純的quicksort ,高度優化過的quicksort,跟自己實現那種還是要複雜上好幾倍,就不展開了)
// A type, typically a collection, that satisfies sort.Interface can be
// sorted by the routines in this package. The methods require that the
// elements of the collection be enumerated by an integer index.
type Interface interface {
// Len is the number of elements in the collection.
Len() int
// Less reports whether the element with
// index i should sort before the element with index j.
Less(i, j int) bool
// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}
要現實三個函數,分別是Len(),Less(i,j) bool, Swap(i,j int),
完了之後調用就把切片,轉換成排序的數據,強制轉換一下,然後放入sort.Sort中即可。
sort.Sort(ByAge(people))
當然你可以定義ByOther。
這個例子後面還舉了一個sort.Slice 直接跟一個匿名函數的用法
// The other way is to use sort.Slice with a custom Less
// function, which can be provided as a closure. In this
// case no methods are needed. (And if they exist, they
// are ignored.) Here we re-sort in reverse order: compare
// the closure with ByAge.Less.
sort.Slice(people, func(i, j int) bool {
return people[i].Age > people[j].Age
})
我覺得這種更接近java中的Arrays.sort(xxx,xxx),也不用寫Swap和Len函數了,更實用一些,個人感覺。
3. 基礎類型
比如int ,float64,String 這種有現成的函數就不用自己寫了。
sort.Ints()
sort.Float64s()
sort.Strings()