go标准库之sort模块

159 阅读3分钟

sort 包提供了排序切片和用户自定义数据集以及相关功能的函数

sort 包主要针对 []int[]float64[]string 、及其他自定义切片的排序

结构体

三种结构体方法都是一样的,只是分别针对 int 切片、 float64 切片、 strings 切片这三种不同的类型

type IntSlice []int
type Float64Slice 
type StringSlice

三种结构体都有五个公开的方法

func (p xxxSlice) Len() int // 切片长度
func (p xxxSlice) Less(i, j int) bool
func (p xxxSlice) Swap(i, j int) 
func (p xxxSlice) Search(x xxx) int
func (p xxxSlice) Sort() 

函数

下面实例有例子

image.png

接口 type interface

type Interface interface {
	Len() int           // Len方法返回集合中的元素个数
	Less(i, j int) boll // i>j,该方法返回索引i的元素是否比索引j元素小
	Swap(i, j int)      // 交换i,j
}

自己实现一个接口实例

只要类型实现了 LenLessSwap 三个方法, NewInts 就实现了排序功能

package main

import (
	"fmt"
	"sort"
)

type NewInts []uint

func (n NewInts) Len() int {
	return len(n)
}

func (n NewInts) Less(i, j int) bool {
	fmt.Println(i, j, n[i] < n[j], n)
	return n[i] < n[j]
}

func (n NewInts) Swap(i, j int) {
	n[i], n[j] = n[j], n[i]
}

func main() {
	n := []uint{1, 3, 2}
	sort.Sort(NewInts(n))
	fmt.Println(n) // [1 2 3]
}

/*
1 0 false [1 3 2]
2 1 true [1 3 2]
1 0 false [1 2 3]
[1 2 3]
*/

实例

[]int :

package main

import (
	"fmt"
	"sort"
)

func main() {
	s := []int{2, 4, 1, 3}
	sort.Ints(s)
	fmt.Printf("s: %v\n", s) // s: [1 2 3 4]
}

[]float64 :

func testFloat64() {
	f := []float64{1.1, 4.4, 5.5, 3.3, 2.2}
	sort.Float64s(f)
	fmt.Printf("f: %v\n", f)
}

string :

func testString() {
	// 数字字符串 根据第一个字符大小排序
	// StringSlice等价于[]string切片
	ls := sort.StringSlice{
		"100",
		"42",
		"41",
		"3",
		"2",
	}
	sort.Strings(ls)
	fmt.Printf("ls: %v\n", ls) // ls: [100 2 3 41 42]

	// 字母字符串 根据第一个字符大小排序
	ls = sort.StringSlice{
		"d",
		"ac",
		"c",
		"ab",
		"e",
	}
	sort.Strings(ls)
	fmt.Printf("ls: %v\n", ls) // ls: ls: [ab ac c d e]

	// 汉字字符串 比较byte大小
	ls = sort.StringSlice{
		"啊",
		"博",
		"次",
		"得",
		"饿",
		"周",
	}
	sort.Strings(ls)
	fmt.Printf("ls: %v\n", ls) // ls: [博 周 啊 得 次 饿]
	for _, v := range ls {
		fmt.Println(v, []byte(v))
	}
	/*
		博 [229 141 154]
		周 [229 145 168]
		啊 [229 149 138]
		得 [229 190 151]
		次 [230 172 161]
		饿 [233 165 191]
	*/
}

复杂结构 [][]int

type testSlice [][]int

func (l testSlice) Len() int           { return len(l) }
func (l testSlice) Swap(i, j int)      { l[i], l[j] = l[j], l[i] }
func (l testSlice) Less(i, j int) bool { return l[i][1] < l[j][1] }

func main() {
	ls := testSlice{
		{1, 4},
		{9, 3},
		{7, 5},
	}
	// 按第二个位置排序
	sort.Sort(ls)
	fmt.Printf("ls: %v\n", ls) // ls: [[9 3] [1 4] [7 5]]
}

复杂结构体 []map[string]int : [{"k": 0}, {"k1": 1}, {"k2": 2}]

type testSlice []map[string]float64

func (l testSlice) Len() int           { return len(l) }
func (l testSlice) Swap(i, j int)      { l[i], l[j] = l[j], l[i] }
func (l testSlice) Less(i, j int) bool { return l[i]["a"] < l[j]["a"] } // 按照"a"对应的值排序

func main() {
	ls := testSlice{
		{"a": 4, "b": 12},
		{"a": 3, "b": 11},
		{"a": 5, "b": 10},
	}
	sort.Sort(ls)
	fmt.Printf("ls: %v\n", ls) // ls: [map[a:3 b:11] map[a:4 b:12] map[a:5 b:10]]
}

复杂结构体 []struct

type People struct {
	Name string
	Age  int
}

type testSlice []People

func (l testSlice) Len() int           { return len(l) }
func (l testSlice) Swap(i, j int)      { l[i], l[j] = l[j], l[i] }
func (l testSlice) Less(i, j int) bool { return l[i].Age < l[j].Age } // 按照年龄排序

func main() {
	ls:= testSlice{
		{Name: "n1", Age: 12},
		{Name: "n2", Age: 11},
		{Name: "n3", Age: 10},
	}
	sort.Sort(ls)
	fmt.Printf("ls: %v\n", ls) // ls: [{n3 10} {n2 11} {n1 12}]
}