最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang對自定義類型進行排序的解決方法

 更新時間:2017年12月27日 11:20:00   作者:youyu歲月  
學習一門編程語言,要掌握原子數(shù)據(jù)類型,還需要掌握自定義數(shù)據(jù)類型。下面這篇文章主要給大家介紹了關于golang如何對自定義類型進行排序的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。

前言

Go 語言支持我們自定義類型,我們大家在實際項目中,常常需要根據(jù)一個結構體類型的某個字段進行排序。之前遇到這個問題不知道如何解決,后來在網上搜索了相關問題,找到了一些好的解決方案,此處參考下,做個總結吧。

由于 golang 的 sort 包本身就提供了相應的功能, 我們就沒必要重復的造個輪子了,來看看如何利用 sort 包來實現(xiàn)吧。

sort包淺談

golang中也實現(xiàn)了排序算法的包sort包,sort 包 在內部實現(xiàn)了四種基本的排序算法:插入排序(insertionSort)、歸并排序(symMerge)、堆排序(heapSort)和快速排序(quickSort); sort 包會依據(jù)實際數(shù)據(jù)自動選擇最優(yōu)的排序算法。

所以我們寫代碼時只需要考慮實現(xiàn) sort.Interface 這個類型就可以了。

粗略的看看sort包

func Sort(data Interface) {
 // Switch to heapsort if depth of 2*ceil(lg(n+1)) is reached.
 n := data.Len()
 maxDepth := 0
 for i := n; i > 0; i >>= 1 {
 maxDepth++
 }
 maxDepth *= 2
 quickSort(data, 0, n, maxDepth)
}
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)
}
// 內部實現(xiàn)的四種排序算法
// 插入排序
func insertionSort(data Interface, a, b int)
// 堆排序
func heapSort(data Interface, a, b int)
// 快速排序
func quickSort(data Interface, a, b, maxDepth int)
// 歸并排序
func symMerge(data Interface, a, m, b int)

所以要調用sort.Sort() 來實現(xiàn)自定義類型排序,只需要我們的類型實現(xiàn) Interface 接口類型中的三個方法即可。

先看看 sort 包本身對于 []int 類型如何排序

// 首先定義了一個[]int類型的別名IntSlice 
type IntSlice []int
// 獲取此 slice 的長度
func (p IntSlice) Len() int   { return len(p) }
// 比較兩個元素大小 升序
func (p IntSlice) Less(i, j int) bool { return p[i] < p[j] }
// 交換數(shù)據(jù)
func (p IntSlice) Swap(i, j int)  { p[i], p[j] = p[j], p[i] }
// sort.Ints()內部調用Sort() 方法實現(xiàn)排序
// 注意 要先將[]int 轉換為 IntSlice類型 因為此類型才實現(xiàn)了Interface的三個方法 
func Ints(a []int) { Sort(IntSlice(a)) }

照葫蘆畫瓢 我們來對自定義的結構體類型進行降序排序

package main
import (
 "fmt"
 "sort"
)
type Person struct {
 Name string
 Age int
}
type Persons []Person
// 獲取此 slice 的長度
func (p Persons) Len() int { return len(p) }
// 根據(jù)元素的年齡降序排序 (此處按照自己的業(yè)務邏輯寫) 
func (p Persons) Less(i, j int) bool {
 return p[i].Age > p[j].Age
}
// 交換數(shù)據(jù)
func (p Persons) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func main() {
 persons := Persons{
 {
 Name: "test1",
 Age: 20,
 },
 {
 Name: "test2",
 Age: 22,
 },
 {
 Name: "test3",
 Age: 21,
 },
 }
 fmt.Println("排序前")
 for _, person := range persons {
 fmt.Println(person.Name, ":", person.Age)
 }
 sort.Sort(persons)
 fmt.Println("排序后")
 for _, person := range persons {
 fmt.Println(person.Name, ":", person.Age)
 }
}

其實,一般 Len()Swap() 基本不做改變,只有涉及到元素比較的 Less() 方法會有所改變。

當我們對某一個結構體中多個字段進行排序時怎么辦,難道每排序一個就寫下這三個方法么,當然不是。我們可以利用嵌套結構體來解決這個問題。因為嵌套結構體可以繼承父結構體的所有屬性和方法

比如我想對上面 Person 的 Name 字段和 Age 對要排序,我們可以利用嵌套結構體來改進一下。

package main
import (
 "fmt"
 "sort"
)
type Person struct {
 Name string
 Age int
}
type Persons []Person
// Len()方法和Swap()方法不用變化
// 獲取此 slice 的長度
func (p Persons) Len() int { return len(p) }
// 交換數(shù)據(jù)
func (p Persons) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// 嵌套結構體 將繼承 Person 的所有屬性和方法
// 所以相當于SortByName 也實現(xiàn)了 Len() 和 Swap() 方法
type SortByName struct{ Persons }
// 根據(jù)元素的姓名長度降序排序 (此處按照自己的業(yè)務邏輯寫)
func (p SortByName) Less(i, j int) bool {
 return len(p.Persons[i].Name) > len(p.Persons[j].Name)
}
type SortByAge struct{ Persons }
// 根據(jù)元素的年齡降序排序 (此處按照自己的業(yè)務邏輯寫)
func (p SortByAge) Less(i, j int) bool {
 return p.Persons[i].Age > p.Persons[j].Age
}
func main() {
 persons := Persons{
 {
 Name: "test123",
 Age: 20,
 },
 {
 Name: "test1",
 Age: 22,
 },
 {
 Name: "test12",
 Age: 21,
 },
 }
 fmt.Println("排序前")
 for _, person := range persons {
 fmt.Println(person.Name, ":", person.Age)
 }
 sort.Sort(SortByName{persons})
 fmt.Println("排序后")
 for _, person := range persons {
 fmt.Println(person.Name, ":", person.Age)
 }
}

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • Golang異??刂铺幚沓绦蝈e誤流程

    Golang異常控制處理程序錯誤流程

    這篇文章主要介紹了Golang異??刂铺幚沓绦蝈e誤流程,Golang異常處理機制包括錯誤處理、panic和defer,可控制程序錯誤流程,保證程序穩(wěn)定性和安全性,是Golang編程的關鍵方式
    2023-04-04
  • 使用goland調試遠程代碼的操作步驟

    使用goland調試遠程代碼的操作步驟

    大家都知道如何在goland調試遠程代碼嗎?今天小編給大家分享一篇教程幫助大家學習goland調試遠程代碼的操作步驟,感興趣的朋友跟隨小編一起看看吧
    2021-06-06
  • gin自定義中間件解決requestBody不可重復讀問題(最新推薦)

    gin自定義中間件解決requestBody不可重復讀問題(最新推薦)

    這篇文章主要介紹了gin自定義中間件解決requestBody不可重復讀問題,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • Go標準庫Flag庫和Log庫的使用

    Go標準庫Flag庫和Log庫的使用

    本文主要介紹了Go標準庫Flag庫和Log庫的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-05-05
  • Go語言并發(fā)之WaitGroup的用法詳解

    Go語言并發(fā)之WaitGroup的用法詳解

    這篇文章主要詳細介紹了Go語言并發(fā)中得到WaitGroup,文中有相關的代碼示例供大家參考,對我們的學習或工作有一定的參考價值,感興趣的同學跟著小編一起來學習吧
    2023-06-06
  • Golang中rune和byte的使用與區(qū)別

    Golang中rune和byte的使用與區(qū)別

    rune和byte都是Go語言中表示單個字符的類型,本文就來介紹一下Golang中rune和byte的使用與區(qū)別,具有一定的參考價值,感興趣的可以了解一下
    2025-02-02
  • Go語言中一定要知道的切片使用注意事項總結

    Go語言中一定要知道的切片使用注意事項總結

    了解和掌握切片的使用注意事項,可以避免意外的程序行為,所以本文就來和大家深入探討一下Go語言切片常見的注意事項,希望對大家有所幫助
    2023-06-06
  • Go 并發(fā)控制context實現(xiàn)原理剖析(小結)

    Go 并發(fā)控制context實現(xiàn)原理剖析(小結)

    Golang context是Golang應用開發(fā)常用的并發(fā)控制技術,這篇文章主要介紹了Go 并發(fā)控制context實現(xiàn)原理剖析(小結),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • Go語言實現(xiàn)并發(fā)控制的常見方式詳解

    Go語言實現(xiàn)并發(fā)控制的常見方式詳解

    這篇文章主要為大家詳細介紹了Go語言實現(xiàn)并發(fā)控制的幾種常見方式,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考一下
    2024-03-03
  • GoLang切片相關問題梳理講解

    GoLang切片相關問題梳理講解

    這篇文章主要介紹了GoLang切片相關的七個問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-10-10

最新評論

宜宾县| 丰台区| 翁牛特旗| 天水市| 津南区| 丰台区| 米脂县| 北宁市| 扎赉特旗| 偏关县| 永平县| 新郑市| 康马县| 长子县| 新兴县| 神池县| 左云县| 渭南市| 辽阳市| 阿鲁科尔沁旗| 边坝县| 锡林郭勒盟| 甘孜| 孝义市| 保康县| 牟定县| 定兴县| 长兴县| 沂源县| 太保市| 台湾省| 屏东县| 察雅县| 乐业县| 双流县| 肃宁县| 丰原市| 丽江市| 平昌县| 句容市| 泽库县|