Go語言實(shí)現(xiàn)有規(guī)律的數(shù)字版本號的排序工具
前言
在某些場景,我們可能需要對版本號進(jìn)行排序。版本號的形式有很多種,例如:
- 1.0.0, 1.0.1.1, 2.0.1.1
- v1.0.0, v1.10.1, v2.0
- ······
而本文所介紹的版本號排序工具,是針對有規(guī)律的數(shù)字版本號如 1.0.0, 1, 2.15.0 這種形式。
創(chuàng)作解讀
版本號的大小比較與排序
版本號排序的前提,首先得比較兩個版本號的大小。由于版本號長度可能不一致,所以需要額外做一些處理。對于版本號的比較,我的算法思路是:
1、以 . 為分隔符,將版本號的每段數(shù)字存到切片里,方便后續(xù)比較大小。例如 "1.0" → ["1", "0"],"1.0.1" → ["1", "0", "1"]。
firstVersions := strings.Split(versions[i], ".") secondVersions := strings.Split(versions[j], ".")
2、由于兩個版本號的長度可能不一致,因此需要做 填充0,統(tǒng)一長度 的操作。所以第二步就是獲取兩個版本號中,最大長度,然后對長度最小的版本號切片,填充零,保持兩個版本號的長度一致。例如第一步的兩個版本號 ["1", "0"]、["1", "0", "1"],需要對第一個版本號填充一個零(填充之后的結(jié)果 → ["1", "0", "0"]),才能保持兩個版本號的長度一致,方便后續(xù)比較。
// 0 填充
// 獲取最大長度并向最小長度的切片填充 "0",統(tǒng)一長度
func getMaxAndFillZero(s1 *[]string, s2 *[]string) int {
len1, len2 := len(*s1), len(*s2)
if len1 > len2 {
fillZero(s2, len1-len2)
return len1
}
fillZero(s1, len2-len1)
return len2
}
// 0 填充
func fillZero(s *[]string, size int) {
for i := 0; i < size; i++ {
*s = append(*s, "0")
}
}size 為最大長度 - 最小長度的值,也就是要填充 0 的個數(shù)。
3、遍歷切片,從前依次比較兩個版本號每段數(shù)字的大小。
如果第一個版本號的第一段數(shù)字大于或小于第二個版本號的第二段數(shù)字,則可以根據(jù)排序規(guī)則決定兩個版本號的先后位置。
如果相等,則比較下一段數(shù)字的大小,以此類推。
for k := 0; k < maxLen; k++ {
// 由于上面判斷了版本號的合法性,因此 error 可以忽略
vi, _ := strconv.Atoi(firstVersions[k])
vj, _ := strconv.Atoi(secondVersions[k])
if vi < vj {
if sortRule == DESC {
// 降序排序
// todo 交換操作
}
// 默認(rèn)升序排序,即使 sortRule 不是 ASC
// todo 交換操作
} else if vi > vj {
// 降序排序
if sortRule == DESC {
// todo 交換操作
}
// 默認(rèn)升序排序,即使 sortRule 不是 ASC
// todo 交換操作
}
}對字符串切片的排序,本工具使用的函數(shù)是 SliceStable(x any, less func(i, j int) bool),通過此函數(shù),可以自定義比較大小的規(guī)則。
sort.SliceStable(versions, func(i, j int) bool {
firstVersions := strings.Split(versions[i], ".")
secondVersions := strings.Split(versions[j], ".")
// 判斷版本號格式的合法性
isNormal(firstVersions)
isNormal(secondVersions)
// 獲取最大值并填充 "0", 統(tǒng)一長度
maxLen := getMaxAndFillZero(&firstVersions, &secondVersions)
for k := 0; k < maxLen; k++ {
// 由于上面判斷了版本號的合法性,因此 error 可以忽略
vi, _ := strconv.Atoi(firstVersions[k])
vj, _ := strconv.Atoi(secondVersions[k])
if vi < vj {
if sortRule == DESC {
// 降序排序
return false
}
// 默認(rèn)升序排序,即使 sortRule 不是 ASC
return true
} else if vi > vj {
// 降序排序
if sortRule == DESC {
return true
}
// 默認(rèn)升序排序,即使 sortRule 不是 ASC
return false
}
}
return false
})版本號的合法性校驗(yàn)
由于本工具處理的版本號是有規(guī)律的數(shù)字版本號,如果版本號包含字母或其他特殊字符,會影響到排序的進(jìn)行,因此需要提前對版本號進(jìn)行合法性的校驗(yàn)。
// 判斷版本號的格式是否合法
func isNormal(versions []string) {
for _, v := range versions {
for _, r := range []rune(v) {
if !unicode.IsNumber(r) {
panic(errors.New("版本號格式錯誤:" + string(r)))
}
}
}
}遍歷每段版本號,然后對每段版本號的字符進(jìn)行遍歷,判斷是否是數(shù)字,如果不是,則 panic 掉,結(jié)束排序。
錯誤處理
由于版本號的不合法性,可能會程序運(yùn)行的過程中產(chǎn)生錯誤。因此,有必要人工捕獲錯誤,提高工具的健壯性。
版本號排序函數(shù)提供一個 error 的返回值,用于判斷是否產(chǎn)生錯誤。錯誤的捕獲邏輯如下:
defer func() {
if r := recover(); r != nil {
if er, ok := r.(error); ok {
err = er
} else {
err = errors.New("")
fmt.Println("未知錯誤: ")
fmt.Println(r)
}
}
}()捕獲版本號的合法性校驗(yàn)時(shí)主動 panic 的錯誤,并結(jié)束排序。
總結(jié)
- 本工具實(shí)現(xiàn)了對有規(guī)律的數(shù)字版本號集合進(jìn)行排序。
- 在排序的過程中,由于版本號的長度可能不一致,因此執(zhí)行填充
0操作,統(tǒng)一長度,再進(jìn)行版本號的大小比較; - 除此之外,還對版本號的合法性做了校驗(yàn),捕獲可預(yù)知和不可預(yù)知的
panic錯誤,提高了工具的健壯性。 - 經(jīng)測試,核心功能已實(shí)現(xiàn),但有些地方還能改進(jìn),后續(xù)會對代碼進(jìn)行優(yōu)化。
到此這篇關(guān)于Go語言實(shí)現(xiàn)有規(guī)律的數(shù)字版本號的排序工具的文章就介紹到這了,更多相關(guān)Go語言排序工具內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Gin+Gorm實(shí)現(xiàn)CRUD的實(shí)戰(zhàn)
本文主要介紹了Gin+Gorm實(shí)現(xiàn)CRUD的實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
golang解析json數(shù)據(jù)的4種方法總結(jié)
在日常工作中每一名開發(fā)者,不管是前端還是后端,都經(jīng)常使用 JSON,下面這篇文章主要給大家介紹了關(guān)于golang解析json數(shù)據(jù)的4種方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
300行代碼實(shí)現(xiàn)go語言即時(shí)通訊聊天室
本文主要介紹了300行代碼實(shí)現(xiàn)go語言即時(shí)通訊聊天室,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
golang elasticsearch Client的使用詳解
這篇文章主要介紹了golang elasticsearch Client的使用詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-05-05

