使用sort包排序

在程序开发中,不可避免的需要给数据集进行排序,如果在语言级别不提供支持的话,我们则需要自己写算法进行数据的处理,麻烦还不一定高效。
幸好Golang在标准包中,官方有提供sort包中Sort()函数提供排序功能。并且天然支持[]int,[]float64,[]string切片的排序查找功能,并且也能够实现对自定义类型集合的排序。
下面我们先来看下golang中Sort函数的结构是什么样的。

func Sort(data Interface) {
    n := data.Len()
    quickSort(data, 0, n, maxDepth(n))
}

可以看到,该函数接收的唯一的参数就是待排序集合,该集合应是一个Interface,而我们如果需要让自定义类型的集合能够被排序,则需要实现该interface以保证类型一致。该接口中有三个方法:

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)
}

数据集合实现了这三个方法后,就可以使用该包的Sort()函数进行排序。

1.1让我们来看一个以学生年龄排序的小案例:

type Stu []student

func main() {
    var students = make(Stu, 0)
    for i := 0; i < 10; i++ {
        stu := student{
            name: strconv.Itoa(i) + "~~",
            age:  i,
        }
        students = append(students, stu)
    }
    for _, item := range students {
        fmt.Println(item.name, "--", item.age)
    }
    sort.Sort(students)
    fmt.Println("is sorted? ", sort.IsSorted(students)) //可以检测是否已经排序
    for _, item := range students {
        fmt.Println(item.name, "--", item.age)
    }
}

func (s Stu) Len() int { //返回集合的长度
    return len(s)
}

func (s Stu) Less(i, j int) bool { //用来决定是升序还是降序
    return s[i].age > s[j].age
}

func (s Stu) Swap(i, j int) { //改变数据在集合中的位置
    s[i], s[j] = s[j], s[i]
}


type student struct {
    name string
    age  int
}

在Less方法中,我使用的是int类型的年龄来进行降序排列的,如果需要升序只需要变成 < 号即可:

func (s Stu) Less(i, j int) bool {
    return s[i].age < s[j].age
}

1.2最后再来个基本int型的使用案例

在sort包中,给[]int排序的方法是IntSlice,结构如下:

type IntSlice []int

func (p IntSlice) Len() int           { return len(p) }
func (p IntSlice) Less(i, j int) bool { return p[i] < p[j] }
func (p IntSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }

// Sort is a convenience method.
func (p IntSlice) Sort() { Sort(p) }

可以看到,该[]int也实现了Sort函数中的接口,并且有一个Sort()方法,所以我们可以这样使用:

var nums = []int{1, 3, 2, 5, 3, 65, 3}
sort.IntSlice(nums).Sort()

如果我们不想这么麻烦,sort包为我们提供了一个Ints方法,调用该方法可以直接排序:

var nums = []int{1, 3, 2, 5, 3, 65, 3}
sort.Ints(nums)
fmt.Println(nums)

输出结果:
[1 2 3 3 3 5 65]
如果需要改变排序方式的话,包中同样有提供一个Reverse方法:

func Reverse(data Interface) Interface {
    return &reverse{data}
}

我们看到,Reverse函数跟Sort函数接收同样的方法,所以我们的排序时需要使用实现了那三个方法的IntSlice方法,使用方式:

sort.Sort(sort.Reverse(sort.IntSlice(nums)))

剧终!

你可能感兴趣的:(使用sort包排序)