golang自定义数组多条件排序

64 阅读1分钟

背景

在自定义对象中,经常会需要根据对象的多个属性进行排序

举个栗子

某地下拳场,有一批打手。在对外比赛时,会优先选择体重大的打手出去比赛。当两个打手体重一样时,会优先排出个子高的打手。

正例

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

}