日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

Golang中Map按照Value大小排序的方法實(shí)例_Golang

作者:IT范兒 ? 更新時間: 2022-05-09 編程語言

Golang中的 map 默認(rèn)是 無序的 。

起因

最近項(xiàng)目中有這樣一個需求:

根據(jù)用戶當(dāng)前的坐標(biāo)點(diǎn),獲取該用戶附近的預(yù)設(shè)城市名稱。

這里有一個注意點(diǎn)是,假設(shè)這些支持的城市名稱是預(yù)設(shè)的,所以就不能直接通過地圖類api根據(jù)坐標(biāo)點(diǎn)獲取所在城市名稱了。

想到的解決思路是:

  1. 獲取這幾個預(yù)設(shè)城市的坐標(biāo)點(diǎn)
  2. App端獲取用戶當(dāng)前坐標(biāo)點(diǎn)
  3. 分別計(jì)算得到該用戶坐標(biāo)點(diǎn)距離各個預(yù)設(shè)城市的坐標(biāo)點(diǎn)距離
  4. 然后計(jì)算得到其中距離最小的一項(xiàng)
  5. 這個坐標(biāo)點(diǎn)對應(yīng)的城市就是所求

探索

經(jīng)過前期計(jì)算,在上面的第 3 步操作后我得到了下面的結(jié)果:

result := map[string]float64{ ?
? ?"城市A": 2334.20, ?
?"城市B": 1992.33, ?
?"城市C": 500.26, ?
?"城市D": 10.39, ?
?"城市E": 333.33, ?
}

我們知道,Golang中 Map 是 無序的 。所以當(dāng)我們使用 for-range 循環(huán)時:

for k, v := range result {  
   fmt.Printf("key: %v value: %v \n", k, v)  
}

結(jié)果可能是:

// 第一種可能結(jié)果:
key: 城市B value: 1992.33?
key: 城市C value: 500.26?
key: 城市D value: 10.39?
key: 城市E value: 333.33?
key: 城市A value: 2334.2?

// 第二種可能結(jié)果:
key: 城市E value: 333.33?
key: 城市A value: 2334.2?
key: 城市B value: 1992.33?
key: 城市C value: 500.26?
key: 城市D value: 10.39?

// 第三種可能結(jié)果:
key: 城市E value: 333.33?
key: 城市A value: 2334.2?
key: 城市B value: 1992.33?
key: 城市C value: 500.26?
key: 城市D value: 10.39

所以,我們不能按照 key 或者 value 來進(jìn)行排序。

實(shí)現(xiàn)

但Golang中切片 Slice 是 有序的。 我們可以結(jié)果使用 Slice 來實(shí)現(xiàn)對 Map 的排序。

第一步

我們先將上面的 map 轉(zhuǎn)換成一個 slice :

type KVPair struct {  
   Key string  
 Val float64  
}  
  
tmpList := make([]KVPair, 0)  
  
for k, v := range result {  
   tmpList = append(tmpList, KVPair{Key: k, Val: v})  
}

上面創(chuàng)建了一個 結(jié)構(gòu)體切片 ,然后將 map 的值添加到切片中。

第二步

在 go1.8 之后,引入了 sort.Slice() 方法,可以實(shí)現(xiàn)對 slice 進(jìn)行排序,我們只需要傳入一個比較函數(shù)即可:

sort.Slice(tmpList, func(i, j int) bool {  
   return tmpList[i].Val < tmpList[j].Val // 升序  
})

第三步

然后,我們對排序后的 slice 進(jìn)行 for-range 遍歷:

for _, pair := range tmpList { ?
? ?fmt.Printf("key: %v value: %v \n", pair.Key, pair.Val) ?
}

// 結(jié)果:
key: 城市D value: 10.39?
key: 城市E value: 333.33?
key: 城市C value: 500.26?
key: 城市B value: 1992.33?
key: 城市A value: 2334.2

可以看到,排序后的 slice 第一項(xiàng)就是我們想要的結(jié)果。

如果我們想要獲取其中 value 值最大的一項(xiàng),只需要更改 sort.Slice 中的比較方法接口:

sort.Slice(tmpList, func(i, j int) bool {  
   return tmpList[i].Val > tmpList[j].Val // 降序  
 //return tmpList[i].Val < tmpList[j].Val // 升序})

總結(jié)

上面測試的完整代碼如下:

package main ?
??
import ( ?
? ?"fmt" ?
?"sort") ?
??
var result = map[string]float64{ ?
? ?"城市A": 2334.20, ?
?"城市B": 1992.33, ?
?"城市C": 500.26, ?
?"城市D": 10.39, ?
?"城市E": 333.33, ?
}

func main() {

? ?type KVPair struct { ?
? ? ? Key string ?
?? ? ?Val float64 ?
? ?} ?
??
? ?tmpList := make([]KVPair, 0) ?
??
? ?for k, v := range result { ?
? ? ? tmpList = append(tmpList, KVPair{Key: k, Val: v}) ?
? ?} ?
??
? ?sort.Slice(tmpList, func(i, j int) bool { ?
? ? ? //return tmpList[i].Val > tmpList[j].Val // 降序 ?
? ? ? return tmpList[i].Val < tmpList[j].Val // 升序?
? ?}) ?
??
? ?for _, pair := range tmpList { ?
? ? ? fmt.Printf("key: %v value: %v \n", pair.Key, pair.Val) ?
? ?} ?
}

總結(jié)

原文鏈接:http://www.itfanr.cc/2022/03/09/golang-map-sorted-by-value/?

欄目分類
最近更新