diff --git a/collections/generics/concurrent_map_test.go b/collections/generics/concurrent_map_test.go index 6d46495..b38c94f 100644 --- a/collections/generics/concurrent_map_test.go +++ b/collections/generics/concurrent_map_test.go @@ -13,8 +13,8 @@ import ( func TestConcurrentMap(t *testing.T) { t.Log(runtime.GOMAXPROCS(runtime.NumCPU())) - key := "abc" - value := "bcd" + key := "aaabc" + value := "aabcd" m := generics.NewConcurrnetMap[string, string]() m.Set(key, value) diff --git a/collections/generics/sort_map.go b/collections/generics/sort_map.go new file mode 100644 index 0000000..0a8ab04 --- /dev/null +++ b/collections/generics/sort_map.go @@ -0,0 +1,86 @@ +package generics + +import ( + "fmt" + "sort" + "strings" + + "golang.org/x/exp/constraints" + "golang.org/x/exp/slices" +) + +type mapSorter[K constraints.Ordered, V any] struct { + keys []K + m map[K]V +} + +func NewSortMap[K constraints.Ordered, V any](m map[K]V) *mapSorter[K, V] { + return &mapSorter[K, V]{ + m: m, + keys: keys(m), + } +} + +func (s *mapSorter[K, V]) Asc() *mapSorter[K, V] { + keys := s.keys + slices.Sort(keys) + + return &mapSorter[K, V]{ + m: s.m, + keys: keys, + } +} + +func (s *mapSorter[K, V]) Desc() *mapSorter[K, V] { + keys := s.keys + + // slices.SortFunc(keys, func(a, b E) bool { + // return a > b + // }) + + sort.Slice(keys, func(i, j int) bool { + return keys[i] > keys[j] + }) + + return &mapSorter[K, V]{ + m: s.m, + keys: keys, + } +} + +func (s *mapSorter[K, V]) Join(sep string, f func(k K, v V) string) string { + slice := make([]string, 0, len(s.m)) + for _, k := range s.keys { + slice = append(slice, f(k, s.m[k])) + } + + return strings.Join(slice, sep) +} + +func (s *mapSorter[K, V]) Keys() []K { + return s.keys +} + +func (s *mapSorter[K, V]) Values() []V { + ret := make([]V, 0, len(s.m)) + for _, k := range s.keys { + ret = append(ret, s.m[k]) + } + + return ret +} + +func (s *mapSorter[K, V]) String() string { + return fmt.Sprintf("map[%s]", s.Join(" ", func(k K, v V) string { + return fmt.Sprintf("%v:%v", k, v) + })) +} + +func keys[K comparable, V any](m map[K]V) []K { + keys := make([]K, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + + return keys +} diff --git a/collections/generics/sort_map_test.go b/collections/generics/sort_map_test.go new file mode 100644 index 0000000..cbf84c7 --- /dev/null +++ b/collections/generics/sort_map_test.go @@ -0,0 +1,45 @@ +package generics + +import ( + "fmt" + "testing" +) + +func TestSort(t *testing.T) { + m := map[string]any{ + "Bcd": "bcd", + "Abc": "abc", + } + + t.Log(NewSortMap(m).Values()) + t.Log(NewSortMap(m).Desc().Values()) + t.Log(NewSortMap(m).Asc().Values()) +} + +func TestMapSortInt(t *testing.T) { + m := map[string]int{ + "Bcd": 8, + "Abc": 4, + } + + ret := NewSortMap(m).Desc().Values() + t.Log(NewSortMap(m).Desc()) + t.Log(NewSortMap(m).Asc()) + + t.Log(ret) +} + +func TestJoin(t *testing.T) { + m := map[string]any{ + "Bcd": "bcd", + "Abc": "abc", + "Efg": "efg", + } + t.Log(m) + + j := NewSortMap(m).Asc().Join("&", func(k string, v any) string { + return fmt.Sprintf("%s=%v", k, v) + }) + + t.Log(j) +}