背景
在自定义对象中,经常会需要根据对象的多个属性进行排序
举个栗子
某地下拳场,有一批打手。在对外比赛时,会优先选择体重大的打手出去比赛。当两个打手体重一样时,会优先排出个子高的打手。
正例
采用sort.Slice方法进行排序
type Fighter struct {
Name string
Weight int
Height int
}
func main() {
fighters := []*Fighter{
{"Anderson Silva", 185, 188},
{"Jon Jones", 205, 193},
{"Georges St-Pierre", 170, 178},
{"Jose Aldo", 145, 170},
{"Demetrious Johnson", 125, 160},
{"Cain Velasquez", 265, 185},
{"Junior Dos Santos", 265, 193},
{"Daniel Cormier", 205, 180},
{"Fabricio Werdum", 265, 193},
}
sort.Slice(fighters, func(i, j int) bool {
if fighters[i].Weight == fighters[j].Weight {
return fighters[i].Height < fighters[j].Height
}
return fighters[i].Weight < fighters[j].Weight
})
for _, f := range fighters {
println("weight:", f.Weight, "\t", "height:", f.Height)
}
}
反例
下例中,并不能达到期望。原因思考排序的过程即可得知。
type Fighter struct {
Name string
Weight int
Height int
}
func main() {
fighters := []*Fighter{
{"Anderson Silva", 185, 188},
{"Jon Jones", 205, 193},
{"Georges St-Pierre", 170, 178},
{"Jose Aldo", 145, 170},
{"Demetrious Johnson", 125, 160},
{"Cain Velasquez", 265, 185},
{"Junior Dos Santos", 265, 193},
{"Daniel Cormier", 205, 180},
{"Fabricio Werdum", 265, 193},
}
sort.Slice(fighters, func(i, j int) bool {
if fighters[i].Weight < fighters[j].Weight {
return true
}
if fighters[i].Height < fighters[j].Height {
return true
}
return false
})
for _, f := range fighters {
println("weight:", f.Weight, "\t", "height:", f.Height)
}
}