diff --git a/README.md b/README.md index 02332e6d..7d9a3d03 100644 --- a/README.md +++ b/README.md @@ -901,10 +901,15 @@ import "github.com/duke-git/lancet/v2/maputil" - **HasKey** : checks if map has key or not. [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#HasKey)] [[play](https://go.dev/play/p/isZZHOsDhFc)] +- **MapToStruct** : converts map to struct. + [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#MapToStruct)] + [[play](https://go.dev/play/p/7wYyVfX38Dp)] - **ToSortedSlicesDefault** : converts a map to two slices sorted by key: one for the keys and another for the values. [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#ToSortedSlicesDefault)] + [[play](https://go.dev/play/p/43gEM2po-qy)] - **ToSortedSlicesWithComparator** : converts a map to two slices sorted by key and using a custom comparison function: one for the keys and another for the values. [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#ToSortedSlicesWithComparator)] + [[play](https://go.dev/play/p/0nlPo6YLdt3)] - **NewConcurrentMap** : creates a ConcurrentMap with specific shard count. [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#NewConcurrentMap)] [[play](https://go.dev/play/p/3PenTPETJT0)] @@ -1440,9 +1445,10 @@ import "github.com/duke-git/lancet/v2/slice" [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Break)] - **RightPadding** : adds padding to the right end of a slice. [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#RightPadding)] + [[play](https://go.dev/play/p/0_2rlLEMBXL)] - **LeftPadding** : adds padding to the left begin of a slice. [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#LeftPadding)] - + [[play](https://go.dev/play/p/jlQVoelLl2k)]
检查map是否包含某个key。用于代替以下样板代码:
-```go -_, haskey := amap["baz"]; - -if haskey { - fmt.Println("map has key baz") -} -``` - 函数签名: ```go @@ -990,6 +982,49 @@ func main() { } ``` +### MapToStruct + +将map转成struct。
+ +函数签名: + +```go +func MapToStruct(m map[string]any, structObj any) error +``` + +示例:[运行](https://go.dev/play/p/7wYyVfX38Dp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/maputil" +) + +func main() { + personReqMap := map[string]any{ + "name": "Nothin", + "max_age": 35, + "page": 1, + "pageSize": 10, + } + + type PersonReq struct { + Name string `json:"name"` + MaxAge int `json:"max_age"` + Page int `json:"page"` + PageSize int `json:"pageSize"` + } + var personReq PersonReq + _ = maputil.MapToStruct(personReqMap, &personReq) + fmt.Println(personReq) + + // Output: + // {Nothin 35 1 10} +} +``` + ### ToSortedSlicesDefault将map的key和value转化成两个根据key的值从小到大排序的切片,value切片中元素的位置与key对应。
@@ -1000,7 +1035,7 @@ func main() { func ToSortedSlicesDefault[K constraints.Ordered, V any](m map[K]V) ([]K, []V) ``` -示例:[运行](todo) +示例:[运行](https://go.dev/play/p/43gEM2po-qy) ```go package main @@ -1012,19 +1047,19 @@ import ( func main() { m := map[int]string{ - 1: "a", - 3: "c", - 2: "b", - } + 1: "a", + 3: "c", + 2: "b", + } - keys, values := ToSortedSlicesDefault(m) + keys, values := ToSortedSlicesDefault(m) - fmt.Println(keys) - fmt.Println(values) + fmt.Println(keys) + fmt.Println(values) - // Output: - // [1 2 3] - // [a b c] + // Output: + // [1 2 3] + // [a b c] } ``` @@ -1038,7 +1073,7 @@ func main() { func ToSortedSlicesWithComparator[K comparable, V any](m map[K]V, comparator func(a, b K) bool) ([]K, []V) ``` -示例:[运行](todo) +示例:[运行](https://go.dev/play/p/0nlPo6YLdt3) ```go package main @@ -1050,35 +1085,35 @@ import ( func main() { m1 := map[time.Time]string{ - time.Date(2024, 3, 31, 0, 0, 0, 0, time.UTC): "today", - time.Date(2024, 3, 30, 0, 0, 0, 0, time.UTC): "yesterday", - time.Date(2024, 4, 1, 0, 0, 0, 0, time.UTC): "tomorrow", - } - - keys1, values1 := ToSortedSlicesWithComparator(m1, func(a, b time.Time) bool { - return a.Before(b) - }) - - m2 := map[int]string{ - 1: "a", - 3: "c", - 2: "b", - } - keys2, values2 := ToSortedSlicesWithComparator(m2, func(a, b int) bool { - return a > b - }) - - fmt.Println(keys2) - fmt.Println(values2) - - fmt.Println(keys1) - fmt.Println(values1) - - // Output: - // [2024-03-30 00:00:00 +0000 UTC 2024-03-31 00:00:00 +0000 UTC 2024-04-01 00:00:00 +0000 UTC] - // [yesterday today tomorrow] - // [3 2 1] - // [c b a] + time.Date(2024, 3, 31, 0, 0, 0, 0, time.UTC): "today", + time.Date(2024, 3, 30, 0, 0, 0, 0, time.UTC): "yesterday", + time.Date(2024, 4, 1, 0, 0, 0, 0, time.UTC): "tomorrow", + } + + keys1, values1 := maputil.ToSortedSlicesWithComparator(m1, func(a, b time.Time) bool { + return a.Before(b) + }) + + m2 := map[int]string{ + 1: "a", + 3: "c", + 2: "b", + } + keys2, values2 := maputil.ToSortedSlicesWithComparator(m2, func(a, b int) bool { + return a > b + }) + + fmt.Println(keys2) + fmt.Println(values2) + + fmt.Println(keys1) + fmt.Println(values1) + + // Output: + // [3 2 1] + // [c b a] + // [2024-03-30 00:00:00 +0000 UTC 2024-03-31 00:00:00 +0000 UTC 2024-04-01 00:00:00 +0000 UTC] + // [yesterday today tomorrow] } ``` @@ -1144,15 +1179,15 @@ func main() { wg1.Wait() var wg2 sync.WaitGroup - wg2.Add(5) + wg2.Add(5) for j := 0; j < 5; j++ { go func(n int) { val, ok := cm.Get(fmt.Sprintf("%d", n)) fmt.Println(val, ok) - wg2.Done() + wg2.Done() }(j) } - wg2.Wait() + wg2.Wait() // output: (order may change) // 1 true @@ -1198,15 +1233,15 @@ func main() { wg1.Wait() var wg2 sync.WaitGroup - wg2.Add(5) + wg2.Add(5) for j := 0; j < 5; j++ { go func(n int) { val, ok := cm.Get(fmt.Sprintf("%d", n)) fmt.Println(val, ok) - wg2.Done() + wg2.Done() }(j) } - wg2.Wait() + wg2.Wait() // output: (order may change) // 1 true @@ -1296,7 +1331,7 @@ func main() { wg1.Wait() var wg2 sync.WaitGroup - wg2.Add(5) + wg2.Add(5) for j := 0; j < 5; j++ { go func(n int) { cm.Delete(fmt.Sprintf("%d", n)) @@ -1342,7 +1377,7 @@ func main() { wg1.Wait() var wg2 sync.WaitGroup - wg2.Add(5) + wg2.Add(5) for j := 0; j < 5; j++ { go func(n int) { val, ok := cm.GetAndDelete(fmt.Sprintf("%d", n)) @@ -1392,7 +1427,7 @@ func main() { wg1.Wait() var wg2 sync.WaitGroup - wg2.Add(5) + wg2.Add(5) for j := 0; j < 5; j++ { go func(n int) { diff --git a/docs/api/packages/slice.md b/docs/api/packages/slice.md index d43a66d6..8004227f 100644 --- a/docs/api/packages/slice.md +++ b/docs/api/packages/slice.md @@ -2615,7 +2615,7 @@ func main() { func Break[T any](values []T, predicate func(T) bool) ([]T, []T) ``` -示例: +示例:[运行](https://go.dev/play/p/yLYcBTyeQIz) ```go import ( @@ -2648,7 +2648,7 @@ func main() { func RightPadding[T any](slice []T, paddingValue T, paddingLength int) []T ``` -示例: +示例:[运行](https://go.dev/play/p/0_2rlLEMBXL) ```go import ( @@ -2675,7 +2675,7 @@ func main() { func LeftPadding[T any](slice []T, paddingValue T, paddingLength int) []T ``` -示例: +示例:[运行](https://go.dev/play/p/jlQVoelLl2k) ```go import ( diff --git a/docs/en/api/packages/maputil.md b/docs/en/api/packages/maputil.md index 894803e9..5a8e69bc 100644 --- a/docs/en/api/packages/maputil.md +++ b/docs/en/api/packages/maputil.md @@ -44,6 +44,7 @@ import ( - [Minus](#Minus) - [IsDisjoint](#IsDisjoint) - [HasKey](#HasKey) +- [MapToStruct](#MapToStruct) - [ToSortedSlicesDefault](#ToSortedSlicesDefault) - [ToSortedSlicesWithComparator](#ToSortedSlicesWithComparator) - [NewConcurrentMap](#NewConcurrentMap) @@ -994,6 +995,49 @@ func main() { } ``` +### MapToStruct + +Converts map to struct
+ +Signature: + +```go +func MapToStruct(m map[string]any, structObj any) error +``` + +Example:[Run](https://go.dev/play/p/7wYyVfX38Dp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/maputil" +) + +func main() { + personReqMap := map[string]any{ + "name": "Nothin", + "max_age": 35, + "page": 1, + "pageSize": 10, + } + + type PersonReq struct { + Name string `json:"name"` + MaxAge int `json:"max_age"` + Page int `json:"page"` + PageSize int `json:"pageSize"` + } + var personReq PersonReq + _ = maputil.MapToStruct(personReqMap, &personReq) + fmt.Println(personReq) + + // Output: + // {Nothin 35 1 10} +} +``` + ### ToSortedSlicesDefault@@ -1005,7 +1049,7 @@ Translate the key and value of the map into two slices that are sorted in ascend func ToSortedSlicesDefault[K constraints.Ordered, V any](m map[K]V) ([]K, []V) ``` -Example:[Run](Todo) +Example:[Run](https://go.dev/play/p/43gEM2po-qy) ```go package main @@ -1017,19 +1061,19 @@ import ( func main() { m := map[int]string{ - 1: "a", - 3: "c", - 2: "b", - } + 1: "a", + 3: "c", + 2: "b", + } - keys, values := ToSortedSlicesDefault(m) + keys, values := maputil.ToSortedSlicesDefault(m) - fmt.Println(keys) - fmt.Println(values) + fmt.Println(keys) + fmt.Println(values) - // Output: - // [1 2 3] - // [a b c] + // Output: + // [1 2 3] + // [a b c] } ``` @@ -1045,7 +1089,7 @@ Translate the key and value of the map into two slices that are sorted according func ToSortedSlicesWithComparator[K comparable, V any](m map[K]V, comparator func(a, b K) bool) ([]K, []V) ``` -Example:[Run](Todo) +Example:[Run](https://go.dev/play/p/0nlPo6YLdt3) ```go package main @@ -1057,35 +1101,35 @@ import ( func main() { m1 := map[time.Time]string{ - time.Date(2024, 3, 31, 0, 0, 0, 0, time.UTC): "today", - time.Date(2024, 3, 30, 0, 0, 0, 0, time.UTC): "yesterday", - time.Date(2024, 4, 1, 0, 0, 0, 0, time.UTC): "tomorrow", - } - - keys1, values1 := ToSortedSlicesWithComparator(m1, func(a, b time.Time) bool { - return a.Before(b) - }) - - m2 := map[int]string{ - 1: "a", - 3: "c", - 2: "b", - } - keys2, values2 := ToSortedSlicesWithComparator(m2, func(a, b int) bool { - return a > b - }) - - fmt.Println(keys2) - fmt.Println(values2) - - fmt.Println(keys1) - fmt.Println(values1) - - // Output: - // [2024-03-30 00:00:00 +0000 UTC 2024-03-31 00:00:00 +0000 UTC 2024-04-01 00:00:00 +0000 UTC] - // [yesterday today tomorrow] + time.Date(2024, 3, 31, 0, 0, 0, 0, time.UTC): "today", + time.Date(2024, 3, 30, 0, 0, 0, 0, time.UTC): "yesterday", + time.Date(2024, 4, 1, 0, 0, 0, 0, time.UTC): "tomorrow", + } + + keys1, values1 := maputil.ToSortedSlicesWithComparator(m1, func(a, b time.Time) bool { + return a.Before(b) + }) + + m2 := map[int]string{ + 1: "a", + 3: "c", + 2: "b", + } + keys2, values2 := maputil.ToSortedSlicesWithComparator(m2, func(a, b int) bool { + return a > b + }) + + fmt.Println(keys2) + fmt.Println(values2) + + fmt.Println(keys1) + fmt.Println(values1) + + // Output: // [3 2 1] // [c b a] + // [2024-03-30 00:00:00 +0000 UTC 2024-03-31 00:00:00 +0000 UTC 2024-04-01 00:00:00 +0000 UTC] + // [yesterday today tomorrow] } ``` @@ -1152,15 +1196,15 @@ func main() { var wg2 sync.WaitGroup - wg2.Add(5) - for j := 0; j < 5; j++ { - go func(n int) { - val, ok := cm.Get(fmt.Sprintf("%d", n)) - fmt.Println(val, ok) - wg2.Done() - }(j) - } - wg2.Wait() + wg2.Add(5) + for j := 0; j < 5; j++ { + go func(n int) { + val, ok := cm.Get(fmt.Sprintf("%d", n)) + fmt.Println(val, ok) + wg2.Done() + }(j) + } + wg2.Wait() // output: (order may change) // 1 true @@ -1207,15 +1251,15 @@ func main() { var wg2 sync.WaitGroup - wg2.Add(5) - for j := 0; j < 5; j++ { - go func(n int) { - val, ok := cm.Get(fmt.Sprintf("%d", n)) - fmt.Println(val, ok) - wg2.Done() - }(j) - } - wg2.Wait() + wg2.Add(5) + for j := 0; j < 5; j++ { + go func(n int) { + val, ok := cm.Get(fmt.Sprintf("%d", n)) + fmt.Println(val, ok) + wg2.Done() + }(j) + } + wg2.Wait() // output: (order may change) // 1 true @@ -1305,7 +1349,7 @@ func main() { wg1.Wait() var wg2 sync.WaitGroup - wg2.Add(5) + wg2.Add(5) for j := 0; j < 5; j++ { go func(n int) { cm.Delete(fmt.Sprintf("%d", n)) @@ -1352,7 +1396,7 @@ func main() { wg1.Wait() var wg2 sync.WaitGroup - wg2.Add(5) + wg2.Add(5) for j := 0; j < 5; j++ { go func(n int) { val, ok := cm.GetAndDelete(fmt.Sprintf("%d", n)) @@ -1404,7 +1448,7 @@ func main() { wg1.Wait() var wg2 sync.WaitGroup - wg2.Add(5) + wg2.Add(5) for j := 0; j < 5; j++ { go func(n int) { ok := cm.Has(fmt.Sprintf("%d", n)) diff --git a/docs/en/api/packages/slice.md b/docs/en/api/packages/slice.md index 381152a1..f8b38a0c 100644 --- a/docs/en/api/packages/slice.md +++ b/docs/en/api/packages/slice.md @@ -2612,7 +2612,7 @@ func main() { func Break[T any](values []T, predicate func(T) bool) ([]T, []T) ``` -Example: +Example:[Run](https://go.dev/play/p/yLYcBTyeQIz) ```go import ( @@ -2645,7 +2645,7 @@ func main() { func RightPadding[T any](slice []T, paddingValue T, paddingLength int) []T ``` -Example: +Example:[Run](https://go.dev/play/p/0_2rlLEMBXL) ```go import ( @@ -2655,7 +2655,7 @@ import ( func main() { nums := []int{1, 2, 3, 4, 5} - padded := RightPadding(nums, 0, 3) + padded := slice.RightPadding(nums, 0, 3) fmt.Println(padded) // Output: // [1 2 3 4 5 0 0 0] @@ -2672,7 +2672,7 @@ func main() { func LeftPadding[T any](slice []T, paddingValue T, paddingLength int) []T ``` -Example: +Example:[Run](https://go.dev/play/p/jlQVoelLl2k) ```go import ( @@ -2682,7 +2682,7 @@ import ( func main() { nums := []int{1, 2, 3, 4, 5} - padded := LeftPadding(nums, 0, 3) + padded := slice.LeftPadding(nums, 0, 3) fmt.Println(padded) // Output: // [0 0 0 1 2 3 4 5] diff --git a/maputil/map.go b/maputil/map.go index b8cd70af..6cb9f6a6 100644 --- a/maputil/map.go +++ b/maputil/map.go @@ -310,7 +310,7 @@ func HasKey[K comparable, V any](m map[K]V, key K) bool { } // MapToStruct converts map to struct -// Play: todo +// Play: https://go.dev/play/p/7wYyVfX38Dp func MapToStruct(m map[string]any, structObj any) error { for k, v := range m { err := setStructField(structObj, k, v) @@ -389,6 +389,7 @@ func getFieldNameByJsonTag(structObj any, jsonTag string) string { } // ToSortedSlicesDefault converts a map to two slices sorted by key: one for the keys and another for the values. +// Play: https://go.dev/play/p/43gEM2po-qy func ToSortedSlicesDefault[K constraints.Ordered, V any](m map[K]V) ([]K, []V) { keys := make([]K, 0, len(m)) @@ -413,6 +414,7 @@ func ToSortedSlicesDefault[K constraints.Ordered, V any](m map[K]V) ([]K, []V) { // ToSortedSlicesWithComparator converts a map to two slices sorted by key and using a custom comparison function: // one for the keys and another for the values. +// Play: https://go.dev/play/p/0nlPo6YLdt3 func ToSortedSlicesWithComparator[K comparable, V any](m map[K]V, comparator func(a, b K) bool) ([]K, []V) { keys := make([]K, 0, len(m)) diff --git a/slice/slice.go b/slice/slice.go index 6cf9e717..3c0066a6 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -1254,7 +1254,7 @@ func Partition[T any](slice []T, predicates ...func(item T) bool) [][]T { } // Breaks a list into two parts at the point where the predicate for the first time is true. -// Play: Todo +// Play: https://go.dev/play/p/yLYcBTyeQIz func Break[T any](values []T, predicate func(T) bool) ([]T, []T) { a := make([]T, 0) b := make([]T, 0) @@ -1289,7 +1289,7 @@ func Random[T any](slice []T) (val T, idx int) { } // RightPadding adds padding to the right end of a slice. -// Play: Todo +// Play: https://go.dev/play/p/0_2rlLEMBXL func RightPadding[T any](slice []T, paddingValue T, paddingLength int) []T { if paddingLength == 0 { return slice @@ -1301,7 +1301,7 @@ func RightPadding[T any](slice []T, paddingValue T, paddingLength int) []T { } // LeftPadding adds padding to the left begin of a slice. -// Play: Todo +// Play: https://go.dev/play/p/jlQVoelLl2k func LeftPadding[T any](slice []T, paddingValue T, paddingLength int) []T { if paddingLength == 0 { return slice