How to sort struct with multiple sort parameters?
Use the newer sort.Slice
function as such:
sort.Slice(members, func(i, j int) bool {
switch strings.Compare(members[i].FirstName, members[j].FirstName) {
case -1:
return true
case 1:
return false
}
return members[i].LastName > members[j].LastName
})
or something like that.
Use the sort.Slice (available since Go 1.8) or the sort.Sort function to sort a slice of values.
With both functions, the application provides a function that tests if one slice element is less than another slice element. To sort by last name and then first name, compare last name and then first name:
// If last names are different, then use last
// name to determine whether element i is less than
// element j.
if members[i].LastName != members[j].LastName {
return members[i].LastName < members[j].LastName
}
// Otherwise, use first name to determine whether
// element i is less than element j.
return members[i].FirstName < members[j].FirstName
The less function is specified using an anonymous function with sort.Slice:
var members []Member
sort.Slice(members, func(i, j int) bool {
if members[i].LastName != members[j].LastName {
return members[i].LastName < members[j].LastName
}
return members[i].FirstName < members[j].FirstName
})
The less function is specified with through an interface with the sort.Sort function:
type byLastFirst []Member
func (members byLastFirst) Len() int { return len(members) }
func (members byLastFirst) Swap(i, j int) { members[i], members[j] = members[j], members[i] }
func (members byLastFirst) Less(i, j int) bool {
if members[i].LastName != members[j].LastName {
return members[i].LastName < members[j].LastName
}
return members[i].FirstName < members[j].FirstName }
sort.Sort(byLastFirst(members))
Unless performance analysis shows that sorting is a hot spot, use the function that's most convenient for your application.
Another pattern, which I find slightly cleaner:
if members[i].LastName != members[j].LastName {
return members[i].LastName < members[j].LastName
}
return members[i].FirstName < members[j].FirstName