type Ranking struct {
UserId int `json:"user_id"`
Score float64 `json:"score"`
}
func RankingAlgorithm(Rankings []Ranking, userId int) float64 {
sort.SliceStable(Rankings, func(i, j int) bool {
return Rankings[j].Score < Rankings[i].Score
})
RankingMaps := make(map[int]map[string]interface{}, len(Rankings))
for key, item := range Rankings {
RankingMaps[item.UserId] = map[string]interface{}{"pointer": item.Score, "position": key}
}
var pointer float64 //得分
var position int //坐标
userRanking, ok := RankingMaps[userId]
if !ok {
return 0
}
pointer = userRanking["pointer"].(float64)
position = userRanking["position"].(int)
//相同分数向下兼容
for position < len(Rankings)-1 && Rankings[position+1].Score == pointer {
position++
}
var transcendCount int
if pointer != 0 && position == 0 { //第一名
transcendCount = len(Rankings)
} else {
transcendCount = len(Rankings[position+1:])
}
percentage,_ := decimal.NewFromFloat(float64(transcendCount) / float64(len(Rankings)) * 100).RoundFloor(0).Float64()
return percentage
}
调用结果:
func main() {
Rankings := make([]Ranking, 0, 5)
Rankings = []Ranking{
{UserId: 1001, Score: 100},
{UserId: 1002, Score: 99},
{UserId: 1003, Score: 99},
{UserId: 1004, Score: 98},
{UserId: 1005, Score: 97},
}
//percentage := RankingAlgorithm(Rankings, 1001) //percentage:100
//percentage := RankingAlgorithm(Rankings, 1002) //percentage:40
//percentage := RankingAlgorithm(Rankings, 1003) //percentage:40
//percentage := RankingAlgorithm(Rankings, 1004) //percentage:20
percentage := RankingAlgorithm(Rankings, 1005) //percentage:0
fmt.Printf("percentage:%v \n", percentage)
}