zoukankan      html  css  js  c++  java
  • go标准库sort之基本使用

    官方抽象出来的排序接口

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

    提供了对int float string三种类型的排序

    使用说明在example里面有详细写到

     总结出来是四种常用的方式

    1 简单的对类型的slice进行排序

    2 使用比较的函数类型封装比较操作

    3 支持多种比较函数

    4 把需要比较的对象作为匿名对象迁移struct里面,通过struct方法进行比较

    官方例子

    1 使用slice进行简单排序

    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 }
    func main() {
    	people := []Person{
    		{"Bob", 31},
    		{"John", 42},
    		{"Michael", 17},
    		{"Jenny", 26},
    	}
    	fmt.Println(people)
    	sort.Sort(ByAge(people))
    	fmt.Println(people)
    	// Output:
    	// [Bob: 31 John: 42 Michael: 17 Jenny: 26]
    	// [Michael: 17 Jenny: 26 Bob: 31 John: 42]
    }
    

    2 使用函数类型封装比较排序的函数

    type Planet struct {
    	name     string
    	mass     earthMass
    	distance au
    }
    // By is the type of a "less" function that defines the ordering of its Planet arguments.
    type By func(p1, p2 *Planet) bool
    // Sort is a method on the function type, By, that sorts the argument slice according to the function.
    func (by By) Sort(planets []Planet) {
    	ps := &planetSorter{
    		planets: planets,
    		by:      by, // The Sort method's receiver is the function (closure) that defines the sort order.
    	}
    	sort.Sort(ps)
    }
    // planetSorter joins a By function and a slice of Planets to be sorted.
    type planetSorter struct {
    	planets []Planet
    	by      func(p1, p2 *Planet) bool // Closure used in the Less method.
    }
    // Len is part of sort.Interface.
    func (s *planetSorter) Len() int {
    	return len(s.planets)
    }
    // Swap is part of sort.Interface.
    func (s *planetSorter) Swap(i, j int) {
    	s.planets[i], s.planets[j] = s.planets[j], s.planets[i]
    }
    // Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
    func (s *planetSorter) Less(i, j int) bool {
    	return s.by(&s.planets[i], &s.planets[j])
    }
    

     

    3  支持多个比较函数

    // A Change is a record of source code changes, recording user, language, and delta size.
    type Change struct {
        user     string
        language string
        lines    int
    }
    type lessFunc func(p1, p2 *Change) bool
    // multiSorter implements the Sort interface, sorting the changes within.
    type multiSorter struct {
        changes []Change
        less    []lessFunc
    }
    // Sort sorts the argument slice according to the less functions passed to OrderedBy.
    func (ms *multiSorter) Sort(changes []Change) {
        ms.changes = changes
        sort.Sort(ms)
    }
    // OrderedBy returns a Sorter that sorts using the less functions, in order.
    // Call its Sort method to sort the data.
    func OrderedBy(less ...lessFunc) *multiSorter {
        return &multiSorter{
            less: less,
        }
    }
    // Len is part of sort.Interface.
    func (ms *multiSorter) Len() int {
        return len(ms.changes)
    }
    // Swap is part of sort.Interface.
    func (ms *multiSorter) Swap(i, j int) {
        ms.changes[i], ms.changes[j] = ms.changes[j], ms.changes[i]
    }
    // Less is part of sort.Interface. It is implemented by looping along the
    // less functions until it finds a comparison that is either Less or
    // !Less. Note that it can call the less functions twice per call. We
    // could change the functions to return -1, 0, 1 and reduce the
    // number of calls for greater efficiency: an exercise for the reader.
    func (ms *multiSorter) Less(i, j int) bool {
        p, q := &ms.changes[i], &ms.changes[j]
        // Try all but the last comparison.
        var k int
        for k = 0; k < len(ms.less)-1; k++ {
            less := ms.less[k]
            switch {
            case less(p, q):
                // p < q, so we have a decision.
                return true
            case less(q, p):
                // p > q, so we have a decision.
                return false
            }
            // p == q; try the next comparison.
        }
        // All comparisons to here said "equal", so just return whatever
        // the final comparison reports.
        return ms.less[k](p, q)
    }

    4 其实是第一种的变种

    type Grams int
    func (g Grams) String() string { return fmt.Sprintf("%dg", int(g)) }
    type Organ struct {
        Name   string
        Weight Grams
    }
    type Organs []*Organ
    func (s Organs) Len() int      { return len(s) }
    func (s Organs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
    // ByName implements sort.Interface by providing Less and using the Len and
    // Swap methods of the embedded Organs value.
    type ByName struct{ Organs }
    func (s ByName) Less(i, j int) bool { return s.Organs[i].Name < s.Organs[j].Name }
    // ByWeight implements sort.Interface by providing Less and using the Len and
    // Swap methods of the embedded Organs value.
    type ByWeight struct{ Organs }
    func (s ByWeight) Less(i, j int) bool { return s.Organs[i].Weight < s.Organs[j].Weight }
  • 相关阅读:
    hibernate注解note
    hibernate的批量删除
    hibernate实现多表联合查询
    hibernate联合主键注解方式
    jsp之radio取值与赋值
    @Transient注解的使用
    工程师如何在工作中提升自己?(公众号)
    HTML中让表单input等文本框为只读不可编辑的方法
    ajax, jQuery, jQueryeasyUI
    关于easyui的问答(来自百度问答)
  • 原文地址:https://www.cnblogs.com/beckbi/p/11530690.html
Copyright © 2011-2022 走看看