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

golang對(duì)自定義類(lèi)型進(jìn)行排序的解決方法

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

前言

Go 語(yǔ)言支持我們自定義類(lèi)型,我們大家在實(shí)際項(xiàng)目中,常常需要根據(jù)一個(gè)結(jié)構(gòu)體類(lèi)型的某個(gè)字段進(jìn)行排序。之前遇到這個(gè)問(wèn)題不知道如何解決,后來(lái)在網(wǎng)上搜索了相關(guān)問(wèn)題,找到了一些好的解決方案,此處參考下,做個(gè)總結(jié)吧。

由于 golang 的 sort 包本身就提供了相應(yīng)的功能, 我們就沒(méi)必要重復(fù)的造個(gè)輪子了,來(lái)看看如何利用 sort 包來(lái)實(shí)現(xiàn)吧。

sort包淺談

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

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

粗略的看看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)
}
// 內(nèi)部實(shí)現(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)

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

先看看 sort 包本身對(duì)于 []int 類(lèi)型如何排序

// 首先定義了一個(gè)[]int類(lèi)型的別名IntSlice 
type IntSlice []int
// 獲取此 slice 的長(zhǎng)度
func (p IntSlice) Len() int   { return len(p) }
// 比較兩個(gè)元素大小 升序
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()內(nèi)部調(diào)用Sort() 方法實(shí)現(xiàn)排序
// 注意 要先將[]int 轉(zhuǎn)換為 IntSlice類(lèi)型 因?yàn)榇祟?lèi)型才實(shí)現(xiàn)了Interface的三個(gè)方法 
func Ints(a []int) { Sort(IntSlice(a)) }

照葫蘆畫(huà)瓢 我們來(lái)對(duì)自定義的結(jié)構(gòu)體類(lèi)型進(jìn)行降序排序

package main
import (
 "fmt"
 "sort"
)
type Person struct {
 Name string
 Age int
}
type Persons []Person
// 獲取此 slice 的長(zhǎng)度
func (p Persons) Len() int { return len(p) }
// 根據(jù)元素的年齡降序排序 (此處按照自己的業(yè)務(wù)邏輯寫(xiě)) 
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)
 }
}

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

當(dāng)我們對(duì)某一個(gè)結(jié)構(gòu)體中多個(gè)字段進(jìn)行排序時(shí)怎么辦,難道每排序一個(gè)就寫(xiě)下這三個(gè)方法么,當(dāng)然不是。我們可以利用嵌套結(jié)構(gòu)體來(lái)解決這個(gè)問(wèn)題。因?yàn)榍短捉Y(jié)構(gòu)體可以繼承父結(jié)構(gòu)體的所有屬性和方法

比如我想對(duì)上面 Person 的 Name 字段和 Age 對(duì)要排序,我們可以利用嵌套結(jié)構(gòu)體來(lái)改進(jìn)一下。

package main
import (
 "fmt"
 "sort"
)
type Person struct {
 Name string
 Age int
}
type Persons []Person
// Len()方法和Swap()方法不用變化
// 獲取此 slice 的長(zhǎng)度
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] }
// 嵌套結(jié)構(gòu)體 將繼承 Person 的所有屬性和方法
// 所以相當(dāng)于SortByName 也實(shí)現(xiàn)了 Len() 和 Swap() 方法
type SortByName struct{ Persons }
// 根據(jù)元素的姓名長(zhǎng)度降序排序 (此處按照自己的業(yè)務(wù)邏輯寫(xiě))
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è)務(wù)邏輯寫(xiě))
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)
 }
}

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Golang異常控制處理程序錯(cuò)誤流程

    Golang異??刂铺幚沓绦蝈e(cuò)誤流程

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

    使用goland調(diào)試遠(yuǎn)程代碼的操作步驟

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

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

    這篇文章主要介紹了gin自定義中間件解決requestBody不可重復(fù)讀問(wèn)題,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • Go標(biāo)準(zhǔn)庫(kù)Flag庫(kù)和Log庫(kù)的使用

    Go標(biāo)準(zhǔn)庫(kù)Flag庫(kù)和Log庫(kù)的使用

    本文主要介紹了Go標(biāo)準(zhǔn)庫(kù)Flag庫(kù)和Log庫(kù)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • Go語(yǔ)言并發(fā)之WaitGroup的用法詳解

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

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

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

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

    Go語(yǔ)言中一定要知道的切片使用注意事項(xiàng)總結(jié)

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

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

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

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

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

    GoLang切片相關(guān)問(wèn)題梳理講解

    這篇文章主要介紹了GoLang切片相關(guān)的七個(gè)問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-10-10

最新評(píng)論

宁强县| 吉林省| 安顺市| 汉沽区| 文登市| 周口市| 洞头县| 融水| 滦平县| 元谋县| 沅江市| 蓬莱市| 枣强县| 丹江口市| 九龙县| 土默特左旗| 滨海县| 贵定县| 嵊泗县| 固始县| 江永县| 靖边县| 连山| 大城县| 新昌县| 石楼县| 曲周县| 文安县| 大厂| 瓮安县| 龙口市| 吉林省| 温宿县| 屏边| 琼海市| 镇赉县| 环江| 济阳县| 泊头市| 南丰县| 蒙自县|