go-sort排序

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()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章