排序接口
从接口定义来看,要实现某类型的排序 要知道有多少个元素 2个指定索引的元素怎么比较大小,索引i的元素小于索引j的值返回true,反之返回false 如何交换指定索引上的元素 那么自定义类型,要想排序,就要实现sort包中该接口。
结构体排序
假设有N个学生,学生有姓名和年龄,按照年龄排序结构体实例。 学生使用结构体Student,多个学生就使用切片[ ]Student。 参照 sort.Ints() 的实现。
func Ints(x []int) { Sort(IntSlice(x)) } 观察这个方法,它依赖下面的定义 // IntSlice attaches the methods of Interface to []int, sorting in increasing order. type IntSlice []int func (x IntSlice) Len() int { return len(x) } func (x IntSlice) Less(i, j int) bool { return x[i] < x[j] } func (x IntSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
就是要在[]Student上实现Interface接口的Len、Less、Swap方法。为了方便可以定义一个新类型,好实现方法。sort.Slice(待排序切片,less函数) 方法为简化版。
type Student struct { name string age int } func main() { stu := make([]Student, 0, 10) for i := 0; i < 10; i++ { r := rand.Intn(128) stu = append(stu, Student{"Tom" + string(r), r}) } fmt.Printf("%+v\n", stu) sort.Slice(stu, func(i, j int) bool { return stu[i].age < stu[j].age }) fmt.Printf("%+v\n", stu) }
下面是运行结果
map的排序
map是键值对的集合,是无序的hash表。但是排序输出是序列,也就是排序所需的键或值要存入序列 中,然后才能排序。
key排序
提取key为序列,排序后,用有序序列中的key映射value输出
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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) // key排好序,就可以用key找到value了 for _, k := range keys { fmt.Println("Key:", k, "Value:", m[k]) } }示例
value排序
不能使用key排序思路,想象每一个键值对就是一个{key:xxx, value:yyy}的结构体实例,就转换成了结构体序列排序了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" "sort" ) type Entry struct { Key int Value string } func main() { m := make(map[int]string) m[1] = "a" m[2] = "c" m[0] = "b" entries := make([]Entry, len(m)) i := 0 // 为什么用了i for k, v := range m { entries[i] = Entry{k, v} i++ } fmt.Println(entries) sort.Slice(entries, func(i, j int) bool { return entries[i].Value < entries[j].Value }) // Value升序 fmt.Println(entries) }示例
下面为一个题:
实现对圆形、三角形、长方形求面积,并图形按照面积降序排列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" "math" "sort" ) type Area interface { area() float32 } type Graph struct { name string } // 三角形结构体 type Triangle struct { Graph lenth, high float32 } // 圆形结构体 type Round struct { Graph rad float32 } // 长方形结构体 type Rect struct { Graph lenth, wid float32 } func (p *Triangle) area() float32 { area := p.lenth * p.high / 2 return area } func (p *Round) area() float32 { area := float32(math.Pi * math.Pow(float64(p.rad), 2)) return area } func (p *Rect) area() float32 { area := p.lenth * p.wid return area } // 多态实现 func area(a Area) float32 { return a.area() } // 用于map排序结构体 type gras struct { name Area area float32 } func main() { // 三角形初始化实例并赋值 t0 := &Triangle{lenth: 13, high: 16.9} // 圆形初始化实例并赋值 ro0 := new(Round) ro0.rad = 23.5 // 长方形初始化实例并赋值 re0 := &Rect{lenth: 3.6, wid: 17} // 分别求各个图形的面积 fmt.Printf("%v\n", area(t0)) fmt.Printf("%v\n", area(ro0)) fmt.Printf("%v\n", area(re0)) // 对以上图形面积排序 s0 := []gras{gras{t0, t0.area()}, gras{ro0, ro0.area()}, gras{re0, re0.area()}} fmt.Printf("排序前: %v\n", s0) sort.Slice(s0, func(i, j int) bool { return s0[i].area > s0[j].area }) fmt.Printf("排序后: %v\n", s0) }对切片排序
下面为返回结果
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" "math" "sort" ) type Area interface { area() float32 } type Graph struct{} // 三角形结构体 type Triangle struct { Graph lenth, high float32 } // 圆形结构体 type Round struct { Graph rad float32 } // 长方形结构体 type Rect struct { Graph lenth, wid float32 } func (p *Triangle) area() float32 { area := p.lenth * p.high / 2 return area } func (p *Round) area() float32 { area := float32(math.Pi * math.Pow(float64(p.rad), 2)) return area } func (p *Rect) area() float32 { area := p.lenth * p.wid return area } // 多态实现 func area(a Area) float32 { return a.area() } // 用于map排序结构体 type gras struct { name Area area float32 } func main() { // 三角形初始化实例并赋值 t0 := new(Triangle) t0.lenth = 3 t0.high = 6.9 // 圆形初始化实例并赋值 ro0 := new(Round) ro0.rad = 3.5 // 长方形初始化实例并赋值 re0 := new(Rect) re0.lenth = 13.6 re0.wid = 17 // 分别求各个图形的面积 fmt.Printf("%v\n", area(t0)) fmt.Printf("%v\n", area(ro0)) fmt.Printf("%v\n", area(re0)) // 对以上图形面积排序 m0 := make(map[Area]float32, 100) m0[t0] = area(t0) m0[ro0] = area(ro0) m0[re0] = area(re0) slis := make([]gras, 3) i := 0 for k, v := range m0 { slis[i] = gras{k, v} i++ } fmt.Printf("排序前: %v\n", slis) sort.Slice(slis, func(i, j int) bool { return slis[i].area > slis[j].area }) fmt.Printf("排序后: %v\n", slis) }对map排序
下面为返回结果
标签:语言,area,fmt,func,go,排序,type,float32 From: https://www.cnblogs.com/caibao666/p/17529620.html