diff --git a/README.md b/README.md index d2e74fe..7f608d4 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,10 @@ Inspiration source: ByteDance code.byted.org/lang/gg This package was not yet open source at the time of the author's resignation, and also cannot find a similar repository, so some ideas from lang/gg were used to create this package. If lang/gg plans to open source it in the future, please feel free to contact me so that ownership of this repository can be transferred -致力于提供一个不引入任何额外依赖以及只带来极小额外性能成本的 go lamda 表达式库 +致力于提供一个不引入任何额外依赖以及只带来极小额外性能成本的 go lamda 表达式库,涵盖面向 go 的一些 lamda 常用表达式 灵感来源:字节跳动 code.byted.org/lang/gg 此包在作者离职时仍未开源,也未找到一个类似的仓库,因此基于 lang/gg 的一些思想做了此包,若后续 lang/gg 计划开源,欢迎联系我,可以转移此仓库的所有权 + +注:所有代码均为手写,个人理解不存在侵权问题,如果 lang/gg 愿意开源自然更好 diff --git a/gconv/conv.go b/gconv/conv.go new file mode 100644 index 0000000..9b05405 --- /dev/null +++ b/gconv/conv.go @@ -0,0 +1,32 @@ +// Package gconv +// Author: hyphen +// Copyright 2023 hyphen. All rights reserved. +// Create-time: 2023/12/20 +package gconv + +import ( + "github.com/hyphennn/glamda/internal" + "github.com/hyphennn/glamda/internal/constraints" +) + +func ToPtr[T constraints.UnPtrAble](t T) *T { + return &t +} + +func FromPtr[T constraints.UnPtrAble](t *T) T { + if t == nil { + return internal.Zero[T]() + } + return *t +} + +func StringPtr(s string) *string { + return &s +} + +func Ptr2String(s *string) string { + if s == nil { + return "" + } + return *s +} diff --git a/gconv/conv_test.go b/gconv/conv_test.go new file mode 100644 index 0000000..b4b516a --- /dev/null +++ b/gconv/conv_test.go @@ -0,0 +1,22 @@ +// Package gconv +// Author: hyphen +// Copyright 2023 hyphen. All rights reserved. +// Create-time: 2023/12/20 +package gconv_test + +import ( + "testing" + + "github.com/hyphennn/glamda/gconv" + "github.com/hyphennn/glamda/internal/assert" +) + +func TestToPtr(t *testing.T) { + s := gconv.ToPtr("123") + assert.Equal(t, "123", *s) +} + +func TestFromPtr(t *testing.T) { + s := "123" + assert.Equal(t, "123", gconv.FromPtr(&s)) +} diff --git a/gstream/gstream_test.go b/gstream/gstream_test.go new file mode 100644 index 0000000..21c861a --- /dev/null +++ b/gstream/gstream_test.go @@ -0,0 +1,13 @@ +// Package gstream +// Author: hyphen +// Copyright 2023 hyphen. All rights reserved. +// Create-time: 2023/12/11 +package gstream + +import ( + "testing" +) + +func Test0(t *testing.T) { + +} diff --git a/gstream/map.go b/gstream/map.go new file mode 100644 index 0000000..a35fde4 --- /dev/null +++ b/gstream/map.go @@ -0,0 +1,33 @@ +// Package gstream +// Author: hyphen +// Copyright 2023 hyphen. All rights reserved. +// Create-time: 2023/12/11 +package gstream + +type MapStream[K comparable, V any] struct { + m map[K]V + s *SliceStream[K] +} + +func AsMapStream[K comparable, V any, M ~map[K]V](m M) *MapStream[K, V] { + return &MapStream[K, V]{m, nil} +} + +func ToSliceStream[K comparable, T, V any](m *MapStream[K, V], fc func(K, V) T) *SliceStream[T] { + s := make([]T, 0, len(m.m)) + m.ForEach(func(k K, v V) { + s = append(s, fc(k, v)) + }) + return AsSliceStream(s) +} + +func (m *MapStream[K, V]) ForEach(fc func(K, V)) *MapStream[K, V] { + for k, v := range m.m { + fc(k, v) + } + return m +} + +func (m *MapStream[K, V]) Collect() map[K]V { + return m.m +} diff --git a/gstream/slice.go b/gstream/slice.go new file mode 100644 index 0000000..caebf43 --- /dev/null +++ b/gstream/slice.go @@ -0,0 +1,36 @@ +// Package gstream +// Author: hyphen +// Copyright 2023 hyphen. All rights reserved. +// Create-time: 2023/12/11 +package gstream + +type SliceStream[T any] struct { + s []T +} + +func AsSliceStream[T any](s []T) *SliceStream[T] { + return &SliceStream[T]{s} +} + +func ToMapStream[K comparable, T, V any](s *SliceStream[T], fc func(T) (K, V)) *MapStream[K, V] { + m := make(map[K]V, len(s.s)) + s.ForEach(func(t T) { + k, v := fc(t) + m[k] = v + }) + return AsMapStream(m) +} + +func (s *SliceStream[T]) ForEach(fc func(T)) { + for _, v := range s.s { + fc(v) + } +} + +func (s *SliceStream[T]) Count() int { + return len(s.s) +} + +func (s *SliceStream[T]) Collect() []T { + return s.s +} diff --git a/internal/constraints/constraints.go b/internal/constraints/constraints.go index aac4278..25138f1 100644 --- a/internal/constraints/constraints.go +++ b/internal/constraints/constraints.go @@ -61,3 +61,7 @@ type Number interface { type Addable interface { Number | Complex | ~string } + +type UnPtrAble interface { + Number | Complex | ~string +} diff --git a/lmap/lmap.go b/lmap/lmap.go index f974938..c02c93b 100644 --- a/lmap/lmap.go +++ b/lmap/lmap.go @@ -14,3 +14,18 @@ func ForEach[K comparable, V any](m map[K]V, fc func(K, V)) { fc(k, v) } } + +func Reverse[K, V comparable](m map[K]V) map[V]K { + ret := make(map[V]K, len(m)) + for k, v := range m { + ret[v] = k + } + return ret +} + +func SafeStore[K comparable, V any, M ~map[K]V](m M, k K, v V) { + if m == nil { + m = make(map[K]V) + } + m[k] = v +}