Let's say I have struct SortableStruct
with 3 fields A
B
C
I want to implement function that consumes sl []SortableStruct
and orderFied string
where orderField
is one of struct's field. This function should retrun slice sorted by orderField
. Is there a way of doing this without huge switch case. It's not ovious for me how to implement sort.Interface
when I want compare structs by different fields.
Well, easiest way is to switch field
type and assign a SORT function. Here is your code:
package main
import (
"fmt"
"sort"
)
type SortableStruct struct {
A int
B int
C int
}
func sortStruct(arr []SortableStruct, field string) {
var less func(i, j int) bool
switch field {
case "B":
less = func(i, j int) bool {
return arr[i].B < arr[j].B
}
case "C":
less = func(i, j int) bool {
return arr[i].C < arr[j].C
}
default:
less = func(i, j int) bool {
return arr[i].A < arr[j].A
}
}
sort.Slice(arr, less)
}
func main() {
arr := []SortableStruct{
{
A: 1,
B: 5,
C: 3,
},
{
A: 2,
B: 3,
C: 20,
},
{
A: -1,
B: -1,
C: 10,
},
}
sortStruct(arr, "C")
fmt.Println(arr)
}
Another idea would be to have 3 defined types, each of them implementing interface sort.Interface
type SortableStructByA []SortableStruct
type SortableStructByB []SortableStruct
type SortableStructByC []SortableStruct
And then, you will have to cast your slice to the wanted type(depending on sort you want) and to do something like this:
sortableSlice := SortableStructByA(arr)
sort.Sort(sortableSlice)