diff --git a/README.cn.md b/README.cn.md index f2d8bd4..57335d3 100644 --- a/README.cn.md +++ b/README.cn.md @@ -11,20 +11,21 @@ [English](README.md) | 简体中文 ## 介绍 - 这是一个基于 Go 语言开发的通用数据类型处理工具类,帮助开发者在业务代码实现中处理常见的数据类型和数据操作。可以让您专注于您的业务代码的实现,而免去处理基本数据类型转换和验证的功能。该工具库无侵入式的设计可以让您的业务代码更容易阅读和优雅。 -## 公告 - -如果您的go版本小于v1.18,那么您应该使用 [v1.1.0](https://github.com/jefferyjob/go-easy-utils/tree/v1.1.0) 版本。如果您的go版本大于等于v1.18版本,那么您应该使用 v2.x.x 版本。 - -该扩展包 v2.0 支持泛型和any。 - ## 快速开始 **安装** + +使用 `Go1.18` 及以上版本的用户,建议安装 `v2.x.x`。 因为 `v2.x.x` 应用 `Go1.18` 的泛型重写了大部分函数 ```bash go get -u github.com/jefferyjob/go-easy-utils ``` + +使用 `Go1.18` 以下版本的用户,必须安装 `v1.x.x`。目前最新的 `v1` 版本是 `v1.1.0` +```bash +go get github.com/jefferyjob/go-easy-utils@v1.1.0 +``` + **使用Demo** ```go package main @@ -171,25 +172,25 @@ func StrToBytes(v string) []byte ```go // Chunk 把slice分割为新的数组块 -func ChunkSlice[T any](slice []T, size int) [][]T +func ChunkSlice(slice []T, size int) [][]T // Column 获取slice中某个单一列的值 -func ColumnSlice[T any](slice []T, column string) []any +func ColumnSlice(slice []T, column string) []any // In 判断value是否在slice中 -func InSlice[T comparable](value T, slices []T) bool +func InSlice(value T, slices []T) bool // Is 判断指定值i是否是slice类型 func IsSlice(slice any) bool // Merge 将多个slice合并成一个slice -func MergeSlice[T any](slices ...[]T) []T +func MergeSlice(slices ...[]T) []T // Sum 对slice中的元素求和 -func SumSlice[T Numeric](slice []T) T +func SumSlice(slice []T) T // Unique 移除slice中重复的值 -func UniqueSlice[T comparable](slice []T) []T +func UniqueSlice(slice []T) []T ``` ### mapUtil map类型处理 @@ -202,23 +203,45 @@ func MapValueExists[T comparable](m map[string]T, value T) bool func MapKeyExists(m map[string]any, key string) bool ``` +### mathUtil + +```go +// Abs 返回一个数的绝对值 +func Abs(num T) T + +// Ceil 对float数据向上取整 +func Ceil(num T) int + +// Floor 对float数据向下取整 +func Floor(num T) int + +// Max 返回slice中最大值 +func Max(slice []T) T + +// Min 返回slice中最小值 +func Min(slice []T) T + +// Round 对float数据四舍五入 +func Round(num T) int +``` + ### intUtil 数值型处理 ```go -// IntToString 将int类型转换为string类型 -func IntToString(v int) string +// IntToStr 将int类型转换为string类型 +func IntToStr(v int) string -// Int8ToString 将int8类型转换为string类型 -func Int8ToString(v int8) string +// Int8ToStr 将int8类型转换为string类型 +func Int8ToStr(v int8) string -// Int16ToString 将int16类型转换为string类型 -func Int16ToString(v int16) string +// Int16ToStr 将int16类型转换为string类型 +func Int16ToStr(v int16) string -// Int32ToString 将int32类型转换为string类型 -func Int32ToString(v int32) string +// Int32ToStr 将int32类型转换为string类型 +func Int32ToStr(v int32) string -// Int64ToString 将int64类型转换为string类型 -func Int64ToString(v int64) string +// Int64ToStr 将int64类型转换为string类型 +func Int64ToStr(v int64) string ``` ### floatUtil 浮点型处理 diff --git a/README.md b/README.md index a695d49..298b404 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ English | [简体中文](README.cn.md) ## Introduction - This is a general data type processing tool class based on Go language, which helps developers process common data types and data operations in business code implementation. It allows you to focus on the implementation of your business code without processing the basic data type conversion and validation functions. The non-intrusive design of the tool library can make your business code easier to read and elegant. ## Notice @@ -22,9 +21,17 @@ This extension pack v2.0 supports generics and any. ## Quick Start **Install** + +Use users with `Go1.18` and above, it is recommended to install `v2.x.x`. Because `v2.x.x` app rewritten most functions of `Go1.18` ```bash go get -u github.com/jefferyjob/go-easy-utils ``` + +Users who use `Go1.18` below must install `v1.x.x`. The latest `v1` version is `v1.1.0` +```bash +go get -u github.com/jefferyjob/go-easy-utils +``` + **Use Demo** ```go package main @@ -36,7 +43,7 @@ import ( func main() { var slice = []string{"this", "is", "go", "easy", "utils"} - chunkSlice := sliceUtil.ChunkStr(slice, 2) + chunkSlice := sliceUtil.ChunkSlice(slice, 2) fmt.Printf("%v", chunkSlice) } ``` @@ -44,7 +51,7 @@ func main() { ## Function list | Package name | Function Outline | Document | -| ------------ | ----------------------------------------------------------------------------------------- |----------------------| +|--------------| ----------------------------------------------------------------------------------------- |----------------------| | anyUtil | Convert any type of data to the specified type | [README](anyUtil) | | byteUtil | Conversion of byte array | [README](byteUtil) | | cryptoUtil | Various encryption processing | [README](cryptoUtil) | @@ -53,6 +60,7 @@ func main() { | intUtil | Numerical data processing | [README](intUtil) | | jsonUtil | Json data conversion, support weak type conversion | [README](jsonUtil) | | mapUtil | Map type data processing | [README](mapUtil) | +| mathUtil | The Math function can handle values within the range of integers and floats. | [README](mathUtil) | | randUtil | Random number generation, including: number, string, byte array | [README](randUtil) | | sliceUtil | Slice processing (grouping, summation, transformation, merging, etc.) | [README](sliceUtil) | | strUtil | String conversion processing | [README](strUtil) | diff --git a/intUtil/README.md b/intUtil/README.md index 6a713f5..ba83e5a 100644 --- a/intUtil/README.md +++ b/intUtil/README.md @@ -17,18 +17,18 @@ import ( ## Functions ```go -// IntToString 将int类型转换为string类型 -func IntToString(v int) string +// IntToStr 将int类型转换为string类型 +func IntToStr(v int) string -// Int8ToString 将int8类型转换为string类型 -func Int8ToString(v int8) string +// Int8ToStr 将int8类型转换为string类型 +func Int8ToStr(v int8) string -// Int16ToString 将int16类型转换为string类型 -func Int16ToString(v int16) string +// Int16ToStr 将int16类型转换为string类型 +func Int16ToStr(v int16) string -// Int32ToString 将int32类型转换为string类型 -func Int32ToString(v int32) string +// Int32ToStr 将int32类型转换为string类型 +func Int32ToStr(v int32) string -// Int64ToString 将int64类型转换为string类型 -func Int64ToString(v int64) string +// Int64ToStr 将int64类型转换为string类型 +func Int64ToStr(v int64) string ``` \ No newline at end of file diff --git a/intUtil/int_x_to_str.go b/intUtil/int_x_to_str.go new file mode 100644 index 0000000..5069fcc --- /dev/null +++ b/intUtil/int_x_to_str.go @@ -0,0 +1,28 @@ +package intUtil + +import "strconv" + +// IntToStr 将int类型转换为string类型 +func IntToStr(v int) string { + return strconv.Itoa(v) +} + +// Int8ToStr 将int8类型转换为string类型 +func Int8ToStr(v int8) string { + return strconv.Itoa(int(v)) +} + +// Int16ToString 将int16类型转换为string类型 +func Int16ToStr(v int16) string { + return strconv.Itoa(int(v)) +} + +// Int32ToStr 将int32类型转换为string类型 +func Int32ToStr(v int32) string { + return strconv.Itoa(int(v)) +} + +// Int64ToStr 将int64类型转换为string类型 +func Int64ToStr(v int64) string { + return strconv.FormatInt(v, 10) +} diff --git a/intUtil/int_x_to_string_test.go b/intUtil/int_x_to_str_test.go similarity index 100% rename from intUtil/int_x_to_string_test.go rename to intUtil/int_x_to_str_test.go diff --git a/intUtil/int_x_to_string.go b/intUtil/int_x_to_string.go deleted file mode 100644 index 819c979..0000000 --- a/intUtil/int_x_to_string.go +++ /dev/null @@ -1,28 +0,0 @@ -package intUtil - -import "strconv" - -// IntToString 将int类型转换为string类型 -func IntToString(v int) string { - return strconv.Itoa(v) -} - -// Int8ToString 将int8类型转换为string类型 -func Int8ToString(v int8) string { - return strconv.Itoa(int(v)) -} - -// Int16ToString 将int16类型转换为string类型 -func Int16ToString(v int16) string { - return strconv.Itoa(int(v)) -} - -// Int32ToString 将int32类型转换为string类型 -func Int32ToString(v int32) string { - return strconv.Itoa(int(v)) -} - -// Int64ToString 将int64类型转换为string类型 -func Int64ToString(v int64) string { - return strconv.FormatInt(v, 10) -} diff --git a/mapUtil/README.md b/mapUtil/README.md index 9dca50a..c9e5d8a 100644 --- a/mapUtil/README.md +++ b/mapUtil/README.md @@ -18,7 +18,7 @@ import ( ```go // MapValueExists 判断map中的value是否存在 -func MapValueExists[T comparable](m map[string]T, value T) bool +func MapValueExists(m map[string]T, value T) bool // MapKeyExists 判断map中的key是否存在 func MapKeyExists(m map[string]any, key string) bool diff --git a/mathUtil/README.md b/mathUtil/README.md new file mode 100644 index 0000000..8983b92 --- /dev/null +++ b/mathUtil/README.md @@ -0,0 +1,37 @@ +# mathUtil + +## Install + +```bash +go get -u github.com/jefferyjob/go-easy-utils/mathUtil +``` + +## Import + +```go +import ( + "github.com/jefferyjob/go-easy-utils/mathUtil" +) +``` + +## Functions + +```go +// Abs 返回一个数的绝对值 +func Abs(num T) T + +// Ceil 对float数据向上取整 +func Ceil(num T) int + +// Floor 对float数据向下取整 +func Floor(num T) int + +// Max 返回slice中最大值 +func Max(slice []T) T + +// Min 返回slice中最小值 +func Min(slice []T) T + +// Round 对float数据四舍五入 +func Round(num T) int +``` \ No newline at end of file diff --git a/mathUtil/abs.go b/mathUtil/abs.go new file mode 100644 index 0000000..edd0e78 --- /dev/null +++ b/mathUtil/abs.go @@ -0,0 +1,8 @@ +package mathUtil + +import "math" + +// Abs 返回一个数的绝对值 +func Abs[T Numeric](num T) T { + return T(math.Abs(float64(num))) +} diff --git a/mathUtil/abs_example_test.go b/mathUtil/abs_example_test.go new file mode 100644 index 0000000..3d0e1f9 --- /dev/null +++ b/mathUtil/abs_example_test.go @@ -0,0 +1,15 @@ +package mathUtil + +import "fmt" + +func ExampleAbs() { + res1 := Abs(-6) + res2 := Abs(9) + + fmt.Println(res1) + fmt.Println(res2) + + // Output: + // 6 + // 9 +} diff --git a/mathUtil/abs_test.go b/mathUtil/abs_test.go new file mode 100644 index 0000000..424d0b4 --- /dev/null +++ b/mathUtil/abs_test.go @@ -0,0 +1,21 @@ +package mathUtil + +import "testing" + +func TestAbsInt64(t *testing.T) { + var input int64 = -12 + var expected int64 = 12 + res := Abs(input) + if res != expected { + t.Errorf("abs error") + } +} + +func TestAbsFloat32(t *testing.T) { + var input float32 = -12.4 + var expected float32 = 12.4 + res := Abs(input) + if res != expected { + t.Errorf("abs error") + } +} diff --git a/mathUtil/ceil.go b/mathUtil/ceil.go new file mode 100644 index 0000000..92c0d8e --- /dev/null +++ b/mathUtil/ceil.go @@ -0,0 +1,17 @@ +package mathUtil + +import ( + "math" + "reflect" +) + +// Ceil 对float数据向上取整 +func Ceil[T float32 | float64](num T) int { + switch reflect.ValueOf(num).Kind() { + case reflect.Float32: + return int(math.Ceil(float64(num))) + case reflect.Float64: + return int(math.Ceil(float64(num))) + } + return 0 +} diff --git a/mathUtil/ceil_example_test.go b/mathUtil/ceil_example_test.go new file mode 100644 index 0000000..77c8bc4 --- /dev/null +++ b/mathUtil/ceil_example_test.go @@ -0,0 +1,15 @@ +package mathUtil + +import "fmt" + +func ExampleCeil() { + res1 := Ceil(3.14) + res2 := Ceil(-6.5) + + fmt.Println(res1) + fmt.Println(res2) + + // Output: + // 4 + // -6 +} diff --git a/mathUtil/ceil_test.go b/mathUtil/ceil_test.go new file mode 100644 index 0000000..a7b9d78 --- /dev/null +++ b/mathUtil/ceil_test.go @@ -0,0 +1,23 @@ +package mathUtil + +import ( + "testing" +) + +func TestCeilFloat32(t *testing.T) { + var input float32 = -12.4 + var expected int = -12 + res := Ceil(input) + if res != expected { + t.Errorf("ceil error") + } +} + +func TestCeilFloat64(t *testing.T) { + var input float64 = 12.4 + var expected int = 13 + res := Ceil(input) + if res != expected { + t.Errorf("ceil error") + } +} diff --git a/mathUtil/floor.go b/mathUtil/floor.go new file mode 100644 index 0000000..f250568 --- /dev/null +++ b/mathUtil/floor.go @@ -0,0 +1,17 @@ +package mathUtil + +import ( + "math" + "reflect" +) + +// Floor 对float数据向下取整 +func Floor[T float32 | float64](num T) int { + switch reflect.ValueOf(num).Kind() { + case reflect.Float32: + return int(math.Floor(float64(num))) + case reflect.Float64: + return int(math.Floor(float64(num))) + } + return 0 +} diff --git a/mathUtil/floor_example_test.go b/mathUtil/floor_example_test.go new file mode 100644 index 0000000..a048c17 --- /dev/null +++ b/mathUtil/floor_example_test.go @@ -0,0 +1,15 @@ +package mathUtil + +import "fmt" + +func ExampleFloor() { + res1 := Floor(3.14) + res2 := Floor(-6.5) + + fmt.Println(res1) + fmt.Println(res2) + + // Output: + // 3 + // -7 +} diff --git a/mathUtil/floor_test.go b/mathUtil/floor_test.go new file mode 100644 index 0000000..6ad1d33 --- /dev/null +++ b/mathUtil/floor_test.go @@ -0,0 +1,21 @@ +package mathUtil + +import "testing" + +func TestFloorFloat32(t *testing.T) { + var input float32 = -12.4 + var expected int = -13 + res := Floor(input) + if res != expected { + t.Errorf("floor error %d", res) + } +} + +func TestFloorFloat64(t *testing.T) { + var input float64 = 12.4 + var expected int = 12 + res := Floor(input) + if res != expected { + t.Errorf("floor error %d", res) + } +} diff --git a/mathUtil/max.go b/mathUtil/max.go new file mode 100644 index 0000000..8bb2e69 --- /dev/null +++ b/mathUtil/max.go @@ -0,0 +1,21 @@ +package mathUtil + +type Numeric interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | + ~float32 | ~float64 +} + +// Max 返回slice中最大值 +func Max[T Numeric](slice []T) T { + if len(slice) == 0 { + return 0 + } + max := slice[0] + for _, value := range slice { + if value > max { + max = value + } + } + return max +} diff --git a/mathUtil/max_example_test.go b/mathUtil/max_example_test.go new file mode 100644 index 0000000..0bf0452 --- /dev/null +++ b/mathUtil/max_example_test.go @@ -0,0 +1,15 @@ +package mathUtil + +import "fmt" + +func ExampleMax() { + res1 := Max([]int{5, 8, 9, 2, 1}) + res2 := Max([]float64{3.14, 2.0, -0.1, 2.2, 100.11}) + + fmt.Println(res1) + fmt.Println(res2) + + // Output: + // 9 + // 100.11 +} diff --git a/mathUtil/max_test.go b/mathUtil/max_test.go new file mode 100644 index 0000000..2e958bc --- /dev/null +++ b/mathUtil/max_test.go @@ -0,0 +1,21 @@ +package mathUtil + +import "testing" + +func TestMaxEmpty(t *testing.T) { + s := []int{} + var expected int = 0 + res := Max(s) + if res != expected { + t.Errorf("max error %d", res) + } +} + +func TestMax(t *testing.T) { + s := []int{3, 7, 1, 9, 3, 0, 2, 2} + var expected int = 9 + res := Max(s) + if res != expected { + t.Errorf("max error %d", res) + } +} diff --git a/mathUtil/min.go b/mathUtil/min.go new file mode 100644 index 0000000..412dd16 --- /dev/null +++ b/mathUtil/min.go @@ -0,0 +1,15 @@ +package mathUtil + +// Min 返回slice中最小值 +func Min[T Numeric](slice []T) T { + if len(slice) == 0 { + return 0 + } + min := slice[0] + for _, value := range slice { + if value < min { + min = value + } + } + return min +} diff --git a/mathUtil/min_example_test.go b/mathUtil/min_example_test.go new file mode 100644 index 0000000..880ace8 --- /dev/null +++ b/mathUtil/min_example_test.go @@ -0,0 +1,15 @@ +package mathUtil + +import "fmt" + +func ExampleMin() { + res1 := Min([]int{5, 8, 9, 2, 1}) + res2 := Min([]float64{3.14, 2.0, -0.1, 2.2, 100.11}) + + fmt.Println(res1) + fmt.Println(res2) + + // Output: + // 1 + // -0.1 +} diff --git a/mathUtil/min_test.go b/mathUtil/min_test.go new file mode 100644 index 0000000..2af232b --- /dev/null +++ b/mathUtil/min_test.go @@ -0,0 +1,21 @@ +package mathUtil + +import "testing" + +func TestMinEmpty(t *testing.T) { + s := []int{} + var expected int = 0 + res := Min(s) + if res != expected { + t.Errorf("min error %d", res) + } +} + +func TestMin(t *testing.T) { + s := []int{3, 7, 1, 9, 3, 0, 2, 2} + var expected int = 0 + res := Min(s) + if res != expected { + t.Errorf("min error %d", res) + } +} diff --git a/mathUtil/rand.go b/mathUtil/rand.go new file mode 100644 index 0000000..8cef111 --- /dev/null +++ b/mathUtil/rand.go @@ -0,0 +1,12 @@ +package mathUtil + +import ( + "math/rand" + "time" +) + +// Rand 生成随机整数 +func Rand[T Numeric](min, max T) T { + rand.Seed(time.Now().UnixNano()) + return T(rand.Intn(int(max)-int(min)+1) + int(min)) +} diff --git a/mathUtil/rand_example_test.go b/mathUtil/rand_example_test.go new file mode 100644 index 0000000..643002e --- /dev/null +++ b/mathUtil/rand_example_test.go @@ -0,0 +1,23 @@ +package mathUtil + +import "fmt" + +func ExampleRand() { + minInt := 1 + maxInt := 100 + res1 := Rand(minInt, maxInt) + if res1 >= 1 && res1 < 100 { + fmt.Println("ok") + } + + minFloat := 1.0 + maxFloat := 10.0 + res2 := Rand(minFloat, maxFloat) + if res2 >= 1.0 && res2 < 10.0 { + fmt.Println("ok") + } + + // Output: + // ok + // ok +} diff --git a/mathUtil/rand_test.go b/mathUtil/rand_test.go new file mode 100644 index 0000000..5277ad5 --- /dev/null +++ b/mathUtil/rand_test.go @@ -0,0 +1,14 @@ +package mathUtil + +import "testing" + +func TestRand(t *testing.T) { + min := 1 + max := 100 + for i := 0; i < 1000; i++ { + num := Rand(min, max) + if num < min || num > max { + t.Errorf("randRange() returned %d, which is outside the range of [%d, %d]", num, min, max) + } + } +} diff --git a/mathUtil/round.go b/mathUtil/round.go new file mode 100644 index 0000000..f11036c --- /dev/null +++ b/mathUtil/round.go @@ -0,0 +1,17 @@ +package mathUtil + +import ( + "math" + "reflect" +) + +// Round 对float数据四舍五入 +func Round[T float32 | float64](num T) int { + switch reflect.ValueOf(num).Kind() { + case reflect.Float32: + return int(math.Round(float64(num))) + case reflect.Float64: + return int(math.Round(float64(num))) + } + return 0 +} diff --git a/mathUtil/round_example_test.go b/mathUtil/round_example_test.go new file mode 100644 index 0000000..f87ec65 --- /dev/null +++ b/mathUtil/round_example_test.go @@ -0,0 +1,15 @@ +package mathUtil + +import "fmt" + +func ExampleRound() { + res1 := Round(3.14) + res2 := Round(3.56) + + fmt.Println(res1) + fmt.Println(res2) + + // Output: + // 3 + // 4 +} diff --git a/mathUtil/round_test.go b/mathUtil/round_test.go new file mode 100644 index 0000000..07fa55b --- /dev/null +++ b/mathUtil/round_test.go @@ -0,0 +1,21 @@ +package mathUtil + +import "testing" + +func TestRoundFloat32(t *testing.T) { + var input float32 = -12.4 + var expected int = -12 + res := Round(input) + if res != expected { + t.Errorf("Round error %d", res) + } +} + +func TestRoundFloat64(t *testing.T) { + var input float64 = 12.5 + var expected int = 13 + res := Round(input) + if res != expected { + t.Errorf("Round error %d", res) + } +} diff --git a/sliceUtil/README.md b/sliceUtil/README.md index 400aa11..c209a36 100644 --- a/sliceUtil/README.md +++ b/sliceUtil/README.md @@ -18,23 +18,23 @@ import ( ```go // Chunk 把slice分割为新的数组块 -func ChunkSlice[T any](slice []T, size int) [][]T +func ChunkSlice(slice []T, size int) [][]T // Column 获取slice中某个单一列的值 -func ColumnSlice[T any](slice []T, column string) []any +func ColumnSlice(slice []T, column string) []any // In 判断value是否在slice中 -func InSlice[T comparable](value T, slices []T) bool +func InSlice(value T, slices []T) bool // Is 判断指定值i是否是slice类型 func IsSlice(slice any) bool // Merge 将多个slice合并成一个slice -func MergeSlice[T any](slices ...[]T) []T +func MergeSlice(slices ...[]T) []T // Sum 对slice中的元素求和 -func SumSlice[T Numeric](slice []T) T +func SumSlice(slice []T) T // Unique 移除slice中重复的值 -func UniqueSlice[T comparable](slice []T) []T +func UniqueSlice(slice []T) []T ``` \ No newline at end of file