From e94165f63cf0168de36a97aee441620601521e18 Mon Sep 17 00:00:00 2001 From: xing Date: Sat, 28 Jan 2023 21:38:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=20=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- helper/number/number.go | 17 ++++++ helper/number/number_test.go | 27 +++++++++ helper/slice/slice.go | 11 +++- helper/slice/slice_test.go | 16 +++--- helper/slice/slices.go | 24 ++++++++ helper/slice/slices_test.go | 57 +++++++++++++++++++ .../theme/twentyseventeen/twentyseventeen.go | 4 +- 7 files changed, 143 insertions(+), 13 deletions(-) diff --git a/helper/number/number.go b/helper/number/number.go index fc4fa0c..7198d30 100644 --- a/helper/number/number.go +++ b/helper/number/number.go @@ -3,8 +3,14 @@ package number import ( "fmt" "math/rand" + "time" ) +var _ = func() any { + rand.Seed(time.Now().UnixNano()) + return nil +}() + type IntNumber interface { ~int | ~int64 | ~int32 | ~int8 | ~int16 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 @@ -70,6 +76,9 @@ func Sum[T Number](a ...T) T { func Add[T Number](i, j T) T { return i + j } +func Sub[T Number](i, j T) T { + return i - j +} func ToString[T Number](n T) string { return fmt.Sprintf("%v", n) @@ -81,3 +90,11 @@ func Abs[T Number](n T) T { } return -n } + +func Mul[T Number](i, j T) T { + return i * j +} + +func Divide[T Number](i, j T) T { + return i / j +} diff --git a/helper/number/number_test.go b/helper/number/number_test.go index 5c44cda..5cc7a94 100644 --- a/helper/number/number_test.go +++ b/helper/number/number_test.go @@ -1,6 +1,7 @@ package number import ( + "fmt" "reflect" "testing" ) @@ -187,6 +188,32 @@ func TestRand(t *testing.T) { if got > tt.args.end || got < tt.args.start { t.Errorf("RandNum() = %v, range error", got) } + fmt.Println(got) + } + }) + } +} + +func TestAbs(t *testing.T) { + type args[T Number] struct { + n T + } + type testCase[T Number] struct { + name string + args args[T] + want T + } + tests := []testCase[int]{ + { + name: "t1", + args: args[int]{-1}, + want: 1, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Abs(tt.args.n); got != tt.want { + t.Errorf("Abs() = %v, want %v", got, tt.want) } }) } diff --git a/helper/slice/slice.go b/helper/slice/slice.go index 4c5c2ca..0cb7366 100644 --- a/helper/slice/slice.go +++ b/helper/slice/slice.go @@ -29,7 +29,7 @@ func Walk[T any](arr []T, fn func(*T)) { } } -func First[T any](arr []T, fn func(T) bool) (int, T) { +func SearchFirst[T any](arr []T, fn func(T) bool) (int, T) { for i, t := range arr { if fn(t) { return i, t @@ -39,7 +39,7 @@ func First[T any](arr []T, fn func(T) bool) (int, T) { return -1, r } -func Last[T any](arr []T, fn func(T) bool) (int, T) { +func SearchLast[T any](arr []T, fn func(T) bool) (int, T) { for i := len(arr) - 1; i > 0; i-- { if fn(arr[i]) { return i, arr[i] @@ -194,6 +194,7 @@ func ToAnySlice[T any](a []T) []any { return Map(a, helper.ToAny[T]) } +// Fill 用指定值填充一个切片 func Fill[T any](start, len int, v T) []T { r := make([]T, start+len) for i := 0; i < len; i++ { @@ -202,7 +203,7 @@ func Fill[T any](start, len int, v T) []T { return r } -// Pad returns a copy of the array padded to size specified by length with value. If length is positive then the array is padded on the right, if it's negative then on the left. If the absolute value of length is less than or equal to the length of the array then no padding takes place. +// Pad 以指定长度将一个值填充进切片 returns a copy of the array padded to size specified by length with value. If length is positive then the array is padded on the right, if it's negative then on the left. If the absolute value of length is less than or equal to the length of the array then no padding takes place. func Pad[T any](a []T, length int, v T) []T { l := len(a) if length > l { @@ -213,6 +214,7 @@ func Pad[T any](a []T, length int, v T) []T { return a } +// Pop 弹出最后一个元素 func Pop[T any](a *[]T) T { arr := *a v := arr[len(arr)-1] @@ -221,11 +223,13 @@ func Pop[T any](a *[]T) T { return v } +// Rand 随机取一个元素 func Rand[T any](a []T) (int, T) { i := number.Rand(0, len(a)-1) return i, a[i] } +// RandPop 随机弹出一个元素并返回那个剩余长度 func RandPop[T any](a *[]T) (T, int) { arr := *a if len(arr) == 0 { @@ -242,6 +246,7 @@ func RandPop[T any](a *[]T) (T, int) { return v, len(arr) - 1 } +// Shift 将切片的第一个单元移出并作为结果返回 func Shift[T any](a *[]T) (T, int) { arr := *a l := len(arr) diff --git a/helper/slice/slice_test.go b/helper/slice/slice_test.go index 71dd85b..e4b9968 100644 --- a/helper/slice/slice_test.go +++ b/helper/slice/slice_test.go @@ -529,7 +529,7 @@ func TestToAnySlice(t *testing.T) { } } -func TestFirst(t *testing.T) { +func TestSearchFirst(t *testing.T) { type args[T int] struct { arr []T fn func(T) bool @@ -565,18 +565,18 @@ func TestFirst(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, got1 := First(tt.args.arr, tt.args.fn) + got, got1 := SearchFirst(tt.args.arr, tt.args.fn) if got != tt.want { - t.Errorf("First() got = %v, want %v", got, tt.want) + t.Errorf("SearchFirst() got = %v, want %v", got, tt.want) } if !reflect.DeepEqual(got1, tt.want1) { - t.Errorf("First() got1 = %v, want %v", got1, tt.want1) + t.Errorf("SearchFirst() got1 = %v, want %v", got1, tt.want1) } }) } } -func TestLast(t *testing.T) { +func TestSearchLast(t *testing.T) { type args[T int] struct { arr []T fn func(T) bool @@ -612,12 +612,12 @@ func TestLast(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, got1 := Last(tt.args.arr, tt.args.fn) + got, got1 := SearchLast(tt.args.arr, tt.args.fn) if got != tt.want { - t.Errorf("Last() got = %v, want %v", got, tt.want) + t.Errorf("SearchLast() got = %v, want %v", got, tt.want) } if !reflect.DeepEqual(got1, tt.want1) { - t.Errorf("Last() got1 = %v, want %v", got1, tt.want1) + t.Errorf("SearchLast() got1 = %v, want %v", got1, tt.want1) } }) } diff --git a/helper/slice/slices.go b/helper/slice/slices.go index 5c95c9d..8fb1af0 100644 --- a/helper/slice/slices.go +++ b/helper/slice/slices.go @@ -33,3 +33,27 @@ func Splice[T any](a *[]T, offset, length int, replacement []T) []T { } return nil } + +func Shuffle[T any](a *[]T) { + if len(*a) < 1 { + return + } + b := make([]T, 0, len(*a)) + for { + v, l := RandPop(a) + b = append(b, v) + if l < 1 { + break + } + + } + *a = b +} + +func Delete[T any](a *[]T, index int) { + if index >= len(*a) || index < 0 { + return + } + arr := *a + *a = append(arr[:index], arr[index+1:]...) +} diff --git a/helper/slice/slices_test.go b/helper/slice/slices_test.go index e7f19bd..cdc150a 100644 --- a/helper/slice/slices_test.go +++ b/helper/slice/slices_test.go @@ -77,3 +77,60 @@ func TestSplice(t *testing.T) { fmt.Println(c) fmt.Println(d) } + +func TestShuffle(t *testing.T) { + type args[T int] struct { + a *[]T + } + type testCase[T int] struct { + name string + args args[T] + } + a := number.Range(1, 10, 1) + tests := []testCase[int]{ + { + name: "t1", + args: args[int]{&a}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for i := 0; i < 20; i++ { + Shuffle(tt.args.a) + fmt.Println(a) + } + }) + } +} + +func TestDelete(t *testing.T) { + type args[T int] struct { + a *[]T + index int + } + type testCase[T int] struct { + name string + args args[T] + } + a := number.Range(1, 5, 1) + b := number.Range(1, 5, 1) + fmt.Println(a) + fmt.Println(b) + tests := []testCase[int]{ + { + name: "t1", + args: args[int]{&a, 0}, + }, + { + name: "t2", + args: args[int]{&b, 2}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + Delete(tt.args.a, tt.args.index) + }) + } + fmt.Println(a) + fmt.Println(b) +} diff --git a/internal/theme/twentyseventeen/twentyseventeen.go b/internal/theme/twentyseventeen/twentyseventeen.go index 942c893..728d44a 100644 --- a/internal/theme/twentyseventeen/twentyseventeen.go +++ b/internal/theme/twentyseventeen/twentyseventeen.go @@ -65,7 +65,7 @@ func Hook(status int, c *gin.Context, h gin.H, scene, stats int) { } } else if scene == plugins.Category { cat := c.Param("category") - _, cate := slice.First(cache.Categories(c), func(my models.TermsMy) bool { + _, cate := slice.SearchFirst(cache.Categories(c), func(my models.TermsMy) bool { return my.Name == cat }) d = int(cate.Terms.TermId) @@ -74,7 +74,7 @@ func Hook(status int, c *gin.Context, h gin.H, scene, stats int) { } } else if scene == plugins.Tag { cat := c.Param("tag") - _, cate := slice.First(cache.Tags(c), func(my models.TermsMy) bool { + _, cate := slice.SearchFirst(cache.Tags(c), func(my models.TermsMy) bool { return my.Name == cat }) d = int(cate.Terms.TermId)