Go 里面在使用结构体切片时,往往我们插入值的顺序,不一定就是我们要使用时的顺序。
这时就需要进行按某个条件进行排序。
map 类型也同样会遇到这么一个问题,那怎么快速对他们进行排序呢?
我们先从 map 类型入手。
先来看一段代码:
type User map[string]string
func (this User) String() string {
rst := ""
for k, v := range this {
rst += fmt.Sprintf("%v=%v \n", k, v)
}
return rst
}
我这里声明了一个 user 的 map,同时实现了 String 方法,这个方法会在 fmt 打印他时被调用。
然后我们在 main 方法里面去初始化打印下:
func main() {
m := User{
"id": "23",
"name": "张三",
"age": "12",
"set": "1",
}
fmt.Println(m)
}
// 执行第一次结果
name=张三
age=12
set=1
id=23
// 执行第二次结果
set=1
id=23
name=张三
age=12
如果没有出现不一样的结果,你就多执行几次,一般 3-4 四次就很大可能出现不一样的排序。
sort 是我们的 go 官方的基础包,是专门用来处理排序的;
它提供了一个方法 sort.Sort
这个方法,我只需要将我们的实例,传入进去就能排序好;
但是传入的实例,必须实现一个接口:
type Interface interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}
也就是上面的这三个方法,即可完成排序。
接下来我们使用官方的 sort 包对他进行排序:
func (this User) Keys() []string {
keys := make([]string, 0)
for k, _ := range this {
keys = append(keys, k)
}
sort.Sort(sort.StringSlice(keys))
return keys
}
我们的思路是,先把所有的 key 取出来进行排序,然后再根据这个排序好的 key 进行取值排序输出。
这里我们用到了 sort.StringSlice
方法,这是将我们的字符串数组,转换成实现了那个接口的实例!
现在我们再打印输出就能看到结果是这样的:
m := User{
"id": "23",
"name": "张三",
"age": "12",
"set": "1",
}
fmt.Println(m.Keys())
// 输出结果
[age id name set]
这回你怎么反复的执行都是一样的结果,首字母都是 a-z 的排序。
如果是对字符串数组,可以直接 sort.StringSlice
方法转换,如果是结构体,就得我们自己手动去实现那接口了。
首先我们先来创建一个我们自定义的结构体:
type User struct {
Name string
Age int
Sex int
}
此时我们去实现一个没有排序的数组:
func main() {
users := []User{
{
Name: "张三",
Age: 10,
Sex: 0,
},
{
Name: "李四",
Age: 40,
Sex: 0,
},
{
Name: "王五",
Age: 20,
Sex: 1,
},
}
fmt.Println(users)
}
// 输出结果
[{张三 10 0} {李四 40 0} {王五 20 1}]
注意 age 这个值,现在是怎么初始化就是怎么样的,10,40,20 的排序。
现在我就需要去做排序工作了,首先我们需要去定义一个 user 切片类型的类型,方便进行扩展,实现 sort 的排序方法:
type Users []User
func (this Users) Len() int {
return len(this)
}
func (this Users) Less(i, j int) bool {
//根据年龄大小
return this[i].Age < this[j].Age
}
func (this Users) Swap(i, j int) {
this[i], this[j] = this[j], this[i]
}
像上面的这样就好了,感觉应该不需要做过多讲解吧,应该都能看懂,如果有疑问,欢迎到我们交流群提问!
接下来我们只需要在需要排序时,调下 sort.Sort
就可以排序好了。
上代码:
func main() {
users := ...//这里和上面一样的初始化
sort.Sort(Users(users))
fmt.Println(users)
}
//输出结果
[{张三 10 0} {王五 20 1} {李四 40 0}]
最后的结果就是按照我们设定的排序规则排序的。
你学废了么?