Skip to content

Instantly share code, notes, and snippets.

@tmr232
Created December 8, 2024 20:00
Show Gist options
  • Save tmr232/e6321d0e025d34d6c8831c1cb300b3e0 to your computer and use it in GitHub Desktop.
Save tmr232/e6321d0e025d34d6c8831c1cb300b3e0 to your computer and use it in GitHub Desktop.
By-Field comparator in Go using reflection
package blogpost
func CmpByFields[T any](names ...string) func(a, b T) int {
cmp := func(a, b T) int {
aVal := reflect.ValueOf(a)
bVal := reflect.ValueOf(b)
for _, name := range names {
aField := aVal.FieldByName(name)
bField := bVal.FieldByName(name)
if aField.CanInt() {
aInt := aField.Int()
bInt := bField.Int()
if aInt == bInt {
continue
} else if aInt < bInt {
return -1
} else {
return 1
}
} else if aField.CanUint() {
aUint := aField.Uint()
bUint := bField.Uint()
if aUint == bUint {
continue
} else if aUint < bUint {
return -1
} else {
return 1
}
} else if aField.CanFloat() {
aFloat := aField.Float()
bFloat := bField.Float()
if aFloat == bFloat {
continue
} else if aFloat < bFloat {
return -1
} else {
return 1
}
} else if aField.Kind() == reflect.String {
aString := aField.String()
bString := bField.String()
if aString == bString {
continue
} else if aString < bString {
return -1
} else {
return 1
}
}
}
return 0
}
return cmp
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment