完善 函数

This commit is contained in:
xing 2023-01-28 21:38:34 +08:00
parent 0832d679a3
commit e94165f63c
7 changed files with 143 additions and 13 deletions

View File

@ -3,8 +3,14 @@ package number
import ( import (
"fmt" "fmt"
"math/rand" "math/rand"
"time"
) )
var _ = func() any {
rand.Seed(time.Now().UnixNano())
return nil
}()
type IntNumber interface { type IntNumber interface {
~int | ~int64 | ~int32 | ~int8 | ~int16 | ~int | ~int64 | ~int32 | ~int8 | ~int16 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
@ -70,6 +76,9 @@ func Sum[T Number](a ...T) T {
func Add[T Number](i, j T) T { func Add[T Number](i, j T) T {
return i + j return i + j
} }
func Sub[T Number](i, j T) T {
return i - j
}
func ToString[T Number](n T) string { func ToString[T Number](n T) string {
return fmt.Sprintf("%v", n) return fmt.Sprintf("%v", n)
@ -81,3 +90,11 @@ func Abs[T Number](n T) T {
} }
return -n return -n
} }
func Mul[T Number](i, j T) T {
return i * j
}
func Divide[T Number](i, j T) T {
return i / j
}

View File

@ -1,6 +1,7 @@
package number package number
import ( import (
"fmt"
"reflect" "reflect"
"testing" "testing"
) )
@ -187,6 +188,32 @@ func TestRand(t *testing.T) {
if got > tt.args.end || got < tt.args.start { if got > tt.args.end || got < tt.args.start {
t.Errorf("RandNum() = %v, range error", got) 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)
} }
}) })
} }

View File

@ -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 { for i, t := range arr {
if fn(t) { if fn(t) {
return i, t return i, t
@ -39,7 +39,7 @@ func First[T any](arr []T, fn func(T) bool) (int, T) {
return -1, r 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-- { for i := len(arr) - 1; i > 0; i-- {
if fn(arr[i]) { if fn(arr[i]) {
return i, arr[i] return i, arr[i]
@ -194,6 +194,7 @@ func ToAnySlice[T any](a []T) []any {
return Map(a, helper.ToAny[T]) return Map(a, helper.ToAny[T])
} }
// Fill 用指定值填充一个切片
func Fill[T any](start, len int, v T) []T { func Fill[T any](start, len int, v T) []T {
r := make([]T, start+len) r := make([]T, start+len)
for i := 0; i < len; i++ { for i := 0; i < len; i++ {
@ -202,7 +203,7 @@ func Fill[T any](start, len int, v T) []T {
return r 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 { func Pad[T any](a []T, length int, v T) []T {
l := len(a) l := len(a)
if length > l { if length > l {
@ -213,6 +214,7 @@ func Pad[T any](a []T, length int, v T) []T {
return a return a
} }
// Pop 弹出最后一个元素
func Pop[T any](a *[]T) T { func Pop[T any](a *[]T) T {
arr := *a arr := *a
v := arr[len(arr)-1] v := arr[len(arr)-1]
@ -221,11 +223,13 @@ func Pop[T any](a *[]T) T {
return v return v
} }
// Rand 随机取一个元素
func Rand[T any](a []T) (int, T) { func Rand[T any](a []T) (int, T) {
i := number.Rand(0, len(a)-1) i := number.Rand(0, len(a)-1)
return i, a[i] return i, a[i]
} }
// RandPop 随机弹出一个元素并返回那个剩余长度
func RandPop[T any](a *[]T) (T, int) { func RandPop[T any](a *[]T) (T, int) {
arr := *a arr := *a
if len(arr) == 0 { if len(arr) == 0 {
@ -242,6 +246,7 @@ func RandPop[T any](a *[]T) (T, int) {
return v, len(arr) - 1 return v, len(arr) - 1
} }
// Shift 将切片的第一个单元移出并作为结果返回
func Shift[T any](a *[]T) (T, int) { func Shift[T any](a *[]T) (T, int) {
arr := *a arr := *a
l := len(arr) l := len(arr)

View File

@ -529,7 +529,7 @@ func TestToAnySlice(t *testing.T) {
} }
} }
func TestFirst(t *testing.T) { func TestSearchFirst(t *testing.T) {
type args[T int] struct { type args[T int] struct {
arr []T arr []T
fn func(T) bool fn func(T) bool
@ -565,18 +565,18 @@ func TestFirst(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { 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 { 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) { 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 { type args[T int] struct {
arr []T arr []T
fn func(T) bool fn func(T) bool
@ -612,12 +612,12 @@ func TestLast(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { 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 { 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) { 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)
} }
}) })
} }

View File

@ -33,3 +33,27 @@ func Splice[T any](a *[]T, offset, length int, replacement []T) []T {
} }
return nil 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:]...)
}

View File

@ -77,3 +77,60 @@ func TestSplice(t *testing.T) {
fmt.Println(c) fmt.Println(c)
fmt.Println(d) 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)
}

View File

@ -65,7 +65,7 @@ func Hook(status int, c *gin.Context, h gin.H, scene, stats int) {
} }
} else if scene == plugins.Category { } else if scene == plugins.Category {
cat := c.Param("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 return my.Name == cat
}) })
d = int(cate.Terms.TermId) 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 { } else if scene == plugins.Tag {
cat := c.Param("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 return my.Name == cat
}) })
d = int(cate.Terms.TermId) d = int(cate.Terms.TermId)