Skip to content

Commit

Permalink
✨ feat: support generics,add new feature
Browse files Browse the repository at this point in the history
   - `Reduce`
   - `Chunk`
   - `Map`
   - `Filter`
   -  GroupBy
  • Loading branch information
jingyuexing committed Dec 31, 2023
1 parent fd52422 commit 868682a
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 34 deletions.
33 changes: 23 additions & 10 deletions func.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ import (
// PipeCallback executes a series of functions where the output of each function is passed as input to the next function.
// Returns a function that can be invoked to run the entire execution process.
func PipeCallback[T any](fns ...func(args T) T) func(args T) T {
return func(args T) T {
result := args
for _, fn := range fns {
result = fn(result)
}
return result
}
return func(args T) T {
result := args
for _, fn := range fns {
result = fn(result)
}
return result
}
}

func Times(cb func(...any) any, x int) func(...any) any {
value := any(nil)
func Times[T any](cb func(args ...T) T, x int) func(...T) T {
var value T
times := 0
return func(args ...any) any {
return func(args ...T) T {
if times < x {
defer func() {
if r := recover(); r != nil {
Expand All @@ -38,3 +38,16 @@ func Times(cb func(...any) any, x int) func(...any) any {
return value
}
}

func Compose[T any](funcs ...func(args ...T) T) func(args ...T) T {
callback := func(a func(args ...T) T, b func(args ...T) T) func(args ...T) T {
return func(args ...T) T {
return a(b(args...))
}
}
startFunc := funcs[0]
for i := 1; i < len(funcs); i++ {
startFunc = callback(startFunc, funcs[i])
}
return startFunc
}
90 changes: 90 additions & 0 deletions slice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package utils


func Chunk[T any](slice []T, size int) [][]T {
var chunks [][]T
for i := 0; i < len(slice); i += size {
end := i + size
if end > len(slice) {
end = len(slice)
}
chunks = append(chunks, slice[i:end])
}
return chunks
}


func Reduce[T any](slice []T, reducer func(T, T) T, initialValue T) T {
result := initialValue

for _, val := range slice {
result = reducer(result, val)
}

return result
}

func Map[T any](slice []T, mapper func(T) T) []T {
result := make([]T, len(slice))

for i, val := range slice {
result[i] = mapper(val)
}

return result
}

func Filter[T any](slice []T, predicate func(T) bool) []T {
var result []T

for _, val := range slice {
if predicate(val) {
result = append(result, val)
}
}

return result
}

func PadEnd[T any](slice []T, targetLength int, padValue T) []T {
currentLength := len(slice)
paddingLength := targetLength - currentLength
if paddingLength <= 0 {
return slice
}
newSlice := make([]T, 0,paddingLength)
for i := 0; i < paddingLength; i++ {
newSlice = append(newSlice, padValue)
}
newSlice = append(slice, newSlice...)

return newSlice
}

func PadStart[T any](slice []T, targetLength int, padValue T) []T {
currentLength := len(slice)
paddingLength := targetLength - currentLength
if paddingLength <= 0 {
return slice
}

newSlice := make([]T, 0, paddingLength)
for i := 0; i < paddingLength; i++ {
newSlice = append(newSlice, padValue)
}

newSlice = append(newSlice, slice...)

return newSlice
}

func GroupBy[T any, K comparable](slice []T, getKey func(T) K) map[K][]T {
groups := make(map[K][]T)

for _, item := range slice {
key := getKey(item)
groups[key] = append(groups[key], item)
}

return groups
}
23 changes: 23 additions & 0 deletions toggle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package utils
type Toggler[T any] interface {
Switch() T
Value() T
}

type toggleValue[T any] struct {
values []T
currentIdx int
}

func (t *toggleValue[T]) Switch() T {
t.currentIdx = (t.currentIdx + 1) % len(t.values)
return t.Value()
}

func (t *toggleValue[T]) Value() T {
return t.values[t.currentIdx]
}

func UseToggle[T any](value ...T) Toggler[T] {
return &toggleValue[T]{values: value, currentIdx: 0}
}
24 changes: 0 additions & 24 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,18 +170,6 @@ func Map2Struct(source map[string]any, bindingTarget any) {
}
}

func Compose[T any](funcs ...func(args ...T) T) func(args ...T) T {
callback := func(a func(args ...T) T, b func(args ...T) T) func(args ...T) T {
return func(args ...T) T {
return a(b(args...))
}
}
startFunc := funcs[0]
for i := 1; i < len(funcs); i++ {
startFunc = callback(startFunc, funcs[i])
}
return startFunc
}

func TimeDuration(duration string) (time.Time, error) {
const (
Expand Down Expand Up @@ -214,15 +202,3 @@ func TimeDuration(duration string) (time.Time, error) {
}
return time.Now().Add(time.Duration(durationSecond) * time.Second).UTC(), nil
}

func Chunk(slice []int, size int) [][]int {
var chunks [][]int
for i := 0; i < len(slice); i += size {
end := i + size
if end > len(slice) {
end = len(slice)
}
chunks = append(chunks, slice[i:end])
}
return chunks
}
49 changes: 49 additions & 0 deletions utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,52 @@ func TestMap2Struct(t *testing.T) {
t.Error("Not Pass")
}
}

func TestToggle(t *testing.T) {
toggle1 := utils.UseToggle("on","off")
toggle1.Switch()
if toggle1.Value() != "off" {
t.Error("not pass")
}
if toggle1.Switch() != "on" {
t.Error("not pass")
}

toggle2 := utils.UseToggle(true,false)
if toggle2.Value() != true {
t.Error("not pass")
}

if toggle2.Switch() != false {
t.Error("not pass")
}

toggle3 := utils.UseToggle(1,2,3,4,5,6,7,8,9)
if toggle3.Value() != 1 {
t.Error("not pass")
}
toggle3.Switch()
toggle3.Switch()
toggle3.Switch()
toggle3.Switch()
if toggle3.Value() != 5 {
t.Error("not pass")
}

}


func TestTimes(t *testing.T) {
utils.Times(func(t ...string) string {
return "hello world"
},2)
}

func TestReduce(t *testing.T) {
sum := utils.Reduce([]int{1,2,3,5,6},func(accumulator, currentValue int) int {
return accumulator + currentValue
},0)
if sum != 17 {
t.Error("not pass")
}
}

0 comments on commit 868682a

Please sign in to comment.