Golang中Map按照Value大小排序的方法實例

Golang中的 map 默認是 無序的 。

起因

最近項目中有這樣一個需求:

根據用戶當前的坐標點,獲取該用戶附近的預設城市名稱。

這裡有一個註意點是,假設這些支持的城市名稱是預設的,所以就不能直接通過地圖類api根據坐標點獲取所在城市名稱瞭。

想到的解決思路是:

  1. 獲取這幾個預設城市的坐標點
  2. App端獲取用戶當前坐標點
  3. 分別計算得到該用戶坐標點距離各個預設城市的坐標點距離
  4. 然後計算得到其中距離最小的一項
  5. 這個坐標點對應的城市就是所求

探索

經過前期計算,在上面的第 3 步操作後我得到瞭下面的結果:

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

我們知道,Golang中 Map 是 無序的 。所以當我們使用 for-range 循環時:

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

結果可能是:

// 第一種可能結果:
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 

// 第二種可能結果:
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: 城市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 來進行排序。

實現

但Golang中切片 Slice 是 有序的。 我們可以結果使用 Slice 來實現對 Map 的排序。

第一步

我們先將上面的 map 轉換成一個 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})  
}

上面創建瞭一個 結構體切片 ,然後將 map 的值添加到切片中。

第二步

在 go1.8 之後,引入瞭 sort.Slice() 方法,可以實現對 slice 進行排序,我們隻需要傳入一個比較函數即可:

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

第三步

然後,我們對排序後的 slice 進行 for-range 遍歷:

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

// 結果:
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 第一項就是我們想要的結果。

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

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

總結

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

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)  
   }  
}

總結

到此這篇關於Golang中Map按照Value大小排序的文章就介紹到這瞭,更多相關Golang中Map大小排序內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: