Skip to content

Commit

Permalink
refactor map sorting functions
Browse files Browse the repository at this point in the history
- renamed MapSorter to ValueSort
- renamed MapCompare to ValueCmp
- added a function ValueLt to check if a value is less than the other. This function was internally used in ValueSort and is now exposed independently
  • Loading branch information
sarvalabs-manish committed Mar 19, 2024
1 parent 7b98ddb commit 0148468
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 35 deletions.
60 changes: 32 additions & 28 deletions mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,59 @@ package polo

import "reflect"

// MapSorter is used by the sort package to sort a slice of reflect.Value objects.
// ValueSort is used by the sort package to sort a slice of reflect.Value objects.
// Assumes that the reflect.Value objects can only be types which are comparable
// i.e, can be used as a map key. (will panic otherwise)
func MapSorter(keys []reflect.Value) func(int, int) bool {
func ValueSort(keys []reflect.Value) func(int, int) bool {
return func(i int, j int) bool {
a, b := keys[i], keys[j]
if a.Kind() == reflect.Interface {
a, b = a.Elem(), b.Elem()
}

switch a.Kind() {
case reflect.Bool:
return b.Bool()
return ValueLt(a, b)
}
}

case reflect.String:
return a.String() < b.String()
func ValueLt(a, b reflect.Value) bool {
switch a.Kind() {
case reflect.Bool:
return b.Bool()

case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return a.Int() < b.Int()
case reflect.String:
return a.String() < b.String()

case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return a.Uint() < b.Uint()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return a.Int() < b.Int()

case reflect.Float32, reflect.Float64:
return a.Float() < b.Float()
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return a.Uint() < b.Uint()

case reflect.Array:
if a.Len() != b.Len() {
panic("array length must equal")
}
case reflect.Float32, reflect.Float64:
return a.Float() < b.Float()

for i := 0; i < a.Len(); i++ {
result := MapCompare(a.Index(i), b.Index(i))
if result == 0 {
continue
}
case reflect.Array:
if a.Len() != b.Len() {
panic("array length must equal")
}

return result < 0
for i := 0; i < a.Len(); i++ {
result := ValueCmp(a.Index(i), b.Index(i))
if result == 0 {
continue
}
}

panic("unsupported key compare")
return result < 0
}
}

panic("unsupported key compare")
}

// MapCompare returns an integer representing the comparison between two reflect.Value objects.
// ValueCmp returns an integer representing the comparison between two reflect.Value objects.
// Assumes that a and b can only have a type that is comparable. (will panic otherwise).
// Returns 1 (a > b); 0 (a == b); -1 (a < b)
func MapCompare(a, b reflect.Value) int {
func ValueCmp(a, b reflect.Value) int {
if a.Kind() == reflect.Interface {
a, b = a.Elem(), b.Elem()
}
Expand Down Expand Up @@ -110,7 +114,7 @@ func MapCompare(a, b reflect.Value) int {
}

for i := 0; i < a.Len(); i++ {
result := MapCompare(a.Index(i), b.Index(i))
result := ValueCmp(a.Index(i), b.Index(i))
if result == 0 {
continue
}
Expand Down
12 changes: 6 additions & 6 deletions mapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
"github.com/stretchr/testify/assert"
)

func TestMapSorter_Panics(t *testing.T) {
func TestValueSort_Panics(t *testing.T) {
t.Run("Array Length", func(t *testing.T) {
a := [4]string{}
b := [3]string{}

assert.PanicsWithValue(t, "array length must equal", func() {
MapSorter([]reflect.Value{reflect.ValueOf(a), reflect.ValueOf(b)})(0, 1)
ValueSort([]reflect.Value{reflect.ValueOf(a), reflect.ValueOf(b)})(0, 1)
})
})

Expand All @@ -22,18 +22,18 @@ func TestMapSorter_Panics(t *testing.T) {
b := make([]string, 4)

assert.PanicsWithValue(t, "unsupported key compare", func() {
MapSorter([]reflect.Value{reflect.ValueOf(a), reflect.ValueOf(b)})(0, 1)
ValueSort([]reflect.Value{reflect.ValueOf(a), reflect.ValueOf(b)})(0, 1)
})
})
}

func TestMapCompare_Panics(t *testing.T) {
func TestValueCmp_Panics(t *testing.T) {
t.Run("Array Length", func(t *testing.T) {
a := [4]string{}
b := [3]string{}

assert.PanicsWithValue(t, "array length must equal", func() {
MapCompare(reflect.ValueOf(a), reflect.ValueOf(b))
ValueCmp(reflect.ValueOf(a), reflect.ValueOf(b))
})
})

Expand All @@ -42,7 +42,7 @@ func TestMapCompare_Panics(t *testing.T) {
b := make([]string, 4)

assert.PanicsWithValue(t, "unsupported key compare", func() {
MapCompare(reflect.ValueOf(a), reflect.ValueOf(b))
ValueCmp(reflect.ValueOf(a), reflect.ValueOf(b))
})
})
}
2 changes: 1 addition & 1 deletion polorizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ func (polorizer *Polorizer) polorizeMapValue(value reflect.Value) error {

// Sort the map keys
keys := value.MapKeys()
sort.Slice(keys, MapSorter(keys))
sort.Slice(keys, ValueSort(keys))

// Create a new polorizer for the map elements
mapping := NewPolorizer(inheritCfg(polorizer.cfg))
Expand Down

0 comments on commit 0148468

Please sign in to comment.