golang 實現自定義結構的排序

    先說明下是什麼場景:業務須要對全部的請求參數按照key的大小進行排序而後將其拼成一個字符串,說到這裏你們可能就明白其實這就是一個驗證請求籤名的東西。那在php中對key-value結構按照key來排序直接使用ksort函數就能夠了,可是在go中並無給定這樣的方法,須要本身來實現。php

事實上,在go的sort包中,只提供了幾種最簡單的數據類型的排序,分別是int  string float64類型的slice,能夠說,基本上全部的排序都須要工程師本身來擴展,好在,在go中擴展這樣的排序方法很簡單。算法

    先來看看sort包源碼是怎麼作的:app

// A type, typically a collection, that satisfies sort.Interface can be
// sorted by the routines in this package. 
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)
}

在源碼go/src/sort/sort.go裏,根據註釋能夠清晰的看到sort包定義了一個interface類型sort.Interface, 只要是實現了Len, Less和Swap三種方法的數據類型就可以直接調用sort.Sort()方法進行排序。而不須要關心sort內部究竟用哪一種算法實現了排序。函數

再細緻的看一下,sort包內部實現了四種排序算法,插入,歸併,堆排序和快速排序。這三種方法都是私有的,在程序調用Sort()函數時,該函數會根據輸入的狀況動態決定使用何種排序算法,即sort包向咱們隱藏了排序具體的實現方式。感興趣的同窗能夠看一下Sort()函數是如何作的。this

接下來就看下如何對一個map結構根據key來進行排序:spa

//map排序,按key排序
type MapSorter []MapItem

func NewMapSorter(m map[string]string) MapSorter {
        ms := make(MapSorter, 0, len(m))
        for k, v := range m { 
                ms = append(ms, MapItem{Key: k, Val: v}) 
        }   

        return ms
}                                                                                                                                                                                                                                                                             

type MapItem struct {
        Key string
        Val string
}

func (ms MapSorter) Len() int {
        return len(ms)
}

func (ms MapSorter) Swap(i, j int) {
        ms[i], ms[j] = ms[j], ms[i]
}

//按鍵排序
func (ms MapSorter) Less(i, j int) bool {
        return ms[i].Key < ms[j].Key
}

 

主要思路就是定義一個struct,它的兩個屬性分別對應於map的key/value,Less函數中對key值進行大小對比。相信看一下上面的代碼,你們就能明白這段代碼該如何寫。。。code

相關文章
相關標籤/搜索