golang学习笔记-排序

前言

这一段时间用到了一个对一组类型的数据排序,由于golang没有提供类似c++中set的内置数据结构,这里需要对一个slice中的元素进行排序,由浅到深学习golang中的排序。

1. 基础数据类型

golang提供了一个名为sort的包,里面提供了基础数据类型的排序:int,float64,string,其他的类型,比如:int32,int64,float32等并没有实现,但是只要使用者实现了sort包中Interface接口的三个函数就可以实现这些类型的排序,sort包中Interface的接口:

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

1.1 内置类型

以一个int切片为例:

func test2() {
	nums := []int{8, 9, 1, 3, 5, 7, 11, 52, 2, -1}
	show("origin", nums...)
	// 调用sort包中的Ints函数排序
	sort.Ints(nums) 
	show("inner", nums...)
}

结果
在这里插入图片描述
其他的float64,string两种也是一样的,调用提供的函数即可排序。

1.2 非内置的基础类型

我们以int64为例,定义一个int64的切片,对其排序。整体的思路就是定一个类型,实现sort中Interface接口的三个函数,完成int64类型的排序。
实现接口

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

func main() {
	// 定义一组int64的slice
	i64 := []int64{4, 5, 7, 8, 9, 0, 7, 65, 5, 4, 34, 3, 3}
	fmt.Println("int64排序前:", i64)
	sort.Sort(int64Slice(i64))
	fmt.Println("int64排序后:", i64)
}

结果
在这里插入图片描述

2. 自定义数据类型

对于一些自定义的类型来说,也存在需要根据某些字段排序的可能性。我们以学生信息为例,对自定义的学生数据类型排序。
学生类型如下:

type Student struct {
	Name  string  // 姓名
	Age   int32   // 年龄
	Score float64 // 成绩
}

我们想通过不同的字段对一组学生排序,比如根据学生的姓名,学生的年龄或者学生的成绩排序,分为三部分实施:

2.1 比较的类型

定义一个函数,入参为*Student的两个变量,返回值为bool,通过这个函数可以实现根据学生的多种信息对学生排序,实现如下:

type By func(p1, p2 *Student) bool

func (by By) SortStudent(name string, sutdents []Student) {
	ss := &StudentSorter{
		students: sutdents,
		by:       by,
	}
	// 调用sort包中的内置的排序方法
	sort.Sort(ss)
	// 自定义的打印排序后的切片内容
	ss.Show(name)
}

2.2 学生的排序的实例

在学生的排序实例里,我们要实现sort包的三个接口函数,然后通过将比较的类型的函数传递进去,就可以实现学生变量的排序,实现:


// 学生的排序对象
type StudentSorter struct {
	students []Student
	by       func(p1, p2 *Student) bool
}

func (s *StudentSorter) Len() int {
	return len(s.students)
}

func (s *StudentSorter) Less(i, j int) bool {
	return s.by(&s.students[i], &s.students[j])
}

func (s *StudentSorter) Swap(i, j int) {
	s.students[i], s.students[j] = s.students[j], s.students[i]
}

// 为了打印排序后的数据
func (s StudentSorter) Show(name string) {
	fmt.Println(">> ", name)
	for _, s := range s.students {
		fmt.Printf("name=%v,age=%v, score=%v\n", s.Name, s.Age, s.Score)
	}
}

2.3 自定义排序的函数

在根据学生的信息排序时,要定义By类型的比较函数,根据比较函数方可实现具体的排序,实现:

package main

func main() {
	ss := []Student{
		Student{Name: "Andy", Age: 18, Score: 99.5},
		Student{Name: "Tim", Age: 78, Score: 90.5},
		Student{Name: "John", Age: 55, Score: 80.5},
		Student{Name: "Jam", Age: 32, Score: 49.5},
	}
	name := func(s1, s2 *Student) bool {
		return s1.Name < s2.Name
	}
	// 成绩升序
	score := func(s1, s2 *Student) bool {
		return s1.Score < s2.Score
	}
	// 专门用了倒叙,排序后的年龄应该是降序
	age := func(s1, s2 *Student) bool {
		return s1.Age > s2.Age
	}

	By(name).SortStudent("按姓名排序", ss)
	By(score).SortStudent("按成绩排序", ss)
	By(age).SortStudent("按年龄排序", ss)
}

结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值