=Start=
缘由:
在用Python和Shell进行日志分析的时候,很常见的一个需求就是——先把某个字段作为key进行去重/计数统计,然后按次数或是内容进行排序统计。刚好最近在学习Go语言,所以想着看能不能学习一下如何用Go语言进行实现,方便以后快速参考改写。
正文:
参考解答:
// 针对「整数」切片的排序
func Ints(a []int) // 针对整型切片 a 进行就地排序(升序)
s := []int{5, 2, 6, 3, 1, 4} // unsorted
sort.Ints(s)
fmt.Println(s) // [1 2 3 4 5 6]
// 针对「字符串」切片的排序
func Strings(a []string) // 针对字符串切片 a 进行就地排序(升序)
s := []string{"5", "2", "6", "3", "1", "4"} // unsorted
sort.Strings(s)
fmt.Println(s) // [1 2 3 4 5 6]
// 针对「浮点型」切片的排序
func Float64s(a []float64)
// 「降序/逆序」该如何实现?
func Reverse(data Interface) Interface // 对 data 进行逆序后返回
s := []int{5, 2, 6, 3, 1, 4} // unsorted
sort.Sort(sort.Reverse(sort.IntSlice(s))) // 先用 sort.IntSlice 进行类型转换,然后调用类型 IntSlice 下的 Reverse 方法进行逆序,然后再 Sort 一下(其他类型的也需要先转换成实现了sort方法的对应类型才行)
fmt.Println(s) // [6 5 4 3 2 1]
// 根据 keys 对 map 进行排序
先建立一个 slice 用于存放单纯针对 keys 的排序结果,然后在打印或使用的时候借助这个额外的 slice来进行升序或降序排列。
package main
import (
"fmt"
"sort"
)
func main() {
// To create a map as input
m := make(map[int]string)
m[1] = "a"
m[2] = "c"
m[0] = "b"
// To store the keys in slice in sorted order
var keys []int
for k := range m {
keys = append(keys, k)
}
sort.Ints(keys)
// To perform the opertion you want
for _, k := range keys {
fmt.Println("Key:", k, "Value:", m[k])
}
}
// 根据 values 对 map 进行排序
// 要对Go 语言的map按照value进行排序,思路是直接不用map,用struct存放key和value,实现对应类型的sort接口(需实现Swap/Len/Less这3个方法),然后就可以调用sort.Sort进行排序了。
/* 根据 value 进行排序 */
http://localhost:8080/pkg/sort/#example_
/* 根据多个 value 中的其中一个进行排序 */
http://localhost:8080/pkg/sort/#example__sortKeys
/* 根据多个 value 的组合进行排序 */
http://localhost:8080/pkg/sort/#example__sortMultiKeys
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 }
type ByName []Person
func (a ByName) Len() int { return len(a) }
func (a ByName) Less(i, j int) bool { return a[i].Name < a[j].Name }
func (a ByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func main() {
people := []Person{
{"Bob", 31},
{"John", 42},
{"Michael", 17},
{"Jenny", 26},
}
fmt.Println(people) // [Bob: 31 John: 42 Michael: 17 Jenny: 26]
fmt.Println(ByAge(people)) // [Bob: 31 John: 42 Michael: 17 Jenny: 26]
sort.Sort(ByAge(people))
fmt.Println(people) // [Michael: 17 Jenny: 26 Bob: 31 John: 42]
// To create a map as input
m := make(map[int]string)
m[1] = "a"
m[2] = "c"
m[0] = "b"
fmt.Println()
fmt.Printf("Original: %v\n", m)
p := make([]Person, len(m))
i := 0
for k, v := range m {
// fmt.Printf("k: %d, v: %s\n", k, v)
p[i] = Person{v, k}
i++
}
fmt.Printf("Original(v:k): %v\n", p)
fmt.Println()
// sort.Sort([]Person(p)) // cannot use ([]Person)(p) (type []Person) as type sort.Interface in argument to sort.Sort: []Person does not implement sort.Interface (missing Len method)
sort.Sort(ByAge(p)) // sort.Sort() 中的参数必须要实现相关的接口,所以需要用实现了接口的类型进行转换
fmt.Printf("Sorted(by value): %v\n", p)
sort.Sort(ByName(p)) // sort.Sort() 中的参数必须要实现相关的接口,所以需要用实现了接口的类型进行转换
fmt.Printf("Sorted(by key): %v\n", p)
// // To store the keys in slice in sorted order
// var keys []int
// for k := range m {
// keys = append(keys, k)
// }
// sort.Ints(keys)
// // To perform the opertion you want
// for _, k := range keys {
// fmt.Println("Key:", k, "Value:", m[k])
// }
}
参考链接:
=END=
《“Go语言学习#6-如何进行sort排序”》 有 1 条评论
Go实战–golang中各种排序算法实现以及生成随机数
https://blog.csdn.net/wangshubo1989/article/details/75135119
使用 Go 实现快速排序
http://colobu.com/2018/06/26/implement-quick-sort-in-golang/
golang实现常用排序算法(一)
https://blog.csdn.net/benben_2015/article/details/79231929
go语言十大排序算法总结
https://blog.csdn.net/guoer9973/article/details/51924715
Golang实现七大排序(2)
https://blog.csdn.net/suiban7403/article/details/78699229