Maputil
maputil 包包括一些操作 map 的函数。
源码:
- https://github.com/duke-git/lancet/blob/main/maputil/map.go
- https://github.com/duke-git/lancet/blob/main/maputil/concurrentmap.go
- https://github.com/duke-git/lancet/blob/main/maputil/orderedmap.go
用法:
import (
"github.com/duke-git/lancet/v2/maputil"
)
目录:
- MapTo
- ForEach
- Filter
- FilterByKeys
- FilterByValues
- OmitBy
- OmitByKeys
- OmitByValues
- Intersect
- Keys
- Values
- KeysBy
- ValuesBy
- MapKeys
- MapValues
- Entries
- FromEntries
- Transform
- Merge
- Minus
- IsDisjoint
- HasKey
- MapToStruct
- ToSortedSlicesDefault
- ToSortedSlicesWithComparator
- NewOrderedMap
- OrderedMap_Set
- OrderedMap_Get
- OrderedMap_Front
- OrderedMap_Back
- OrderedMap_Delete
- OrderedMap_Clear
- OrderedMap_Len
- OrderedMap_Keys
- OrderedMap_Values
- OrderedMap_Contains
- OrderedMap_Range
- OrderedMap_Elements
- OrderedMap_Iter
- OrderedMap_ReverseIter
- OrderedMap_SortByKey
- OrderedMap_MarshalJSON
- OrderedMap_UnmarshalJSON
- NewConcurrentMap
- ConcurrentMap_Get
- ConcurrentMap_Set
- ConcurrentMap_GetOrSet
- ConcurrentMap_Delete
- ConcurrentMap_GetAndDelete
- ConcurrentMap_Has
- ConcurrentMap_Range
- GetOrSet
- SortByKey
- GetOrDefault
API 文档:
MapTo
快速将map或者其他类型映射到结构体或者指定类型。
函数签名:
func MapTo(src any, dst any) error
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
type (
Person struct {
Name string `json:"name"`
Age int `json:"age"`
Phone string `json:"phone"`
Addr Address `json:"address"`
}
Address struct {
Street string `json:"street"`
Number int `json:"number"`
}
)
personInfo := map[string]interface{}{
"name": "Nothin",
"age": 28,
"phone": "123456789",
"address": map[string]interface{}{
"street": "test",
"number": 1,
},
}
var p Person
err := MapTo(personInfo, &p)
fmt.Println(err)
fmt.Println(p)
// Output:
// <nil>
// {Nothin 28 123456789 {test 1}}
}
ForEach
对map中的每对key和value执行iteratee函数
函数签名:
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V))
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
}
var sum int
maputil.ForEach(m, func(_ string, value int) {
sum += value
})
fmt.Println(sum)
// Output:
// 10
}
Filter
迭代map中的每对key和value, 返回符合predicate函数的key, value。
函数签名:
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
}
isEven := func(_ string, value int) bool {
return value%2 == 0
}
maputil.Filter(m, func(_ string, value int) {
sum += value
})
result := Filter(m, isEven)
fmt.Println(result)
// Output:
// map[b:2 d:4]
}
FilterByKeys
迭代map, 返回一个新map,其key都是给定的key值。
函数签名:
func FilterByKeys[K comparable, V any](m map[K]V, keys []K) map[K]V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
}
result := maputil.FilterByKeys(m, []string{"a", "b"})
fmt.Println(result)
// Output:
// map[a:1 b:2]
}
FilterByValues
迭代map, 返回一个新map,其value都是给定的value值。
函数签名:
func FilterByValues[K comparable, V comparable](m map[K]V, values []V) map[K]V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
}
result := maputil.FilterByValues(m, []int{3, 4})
fmt.Println(result)
// Output:
// map[c:3 d:4]
}
OmitBy
Filter的反向操作, 迭代map中的每对key和value, 删除符合predicate函数的key, value, 返回新map。
函数签名:
func OmitBy[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
}
isEven := func(_ string, value int) bool {
return value%2 == 0
}
result := maputil.OmitBy(m, isEven)
fmt.Println(result)
// Output:
// map[a:1 c:3 e:5]
}
OmitByKeys
FilterByKeys的反向操作, 迭代map, 返回一个新map,其key不包括给定的key值。
函数签名:
func OmitByKeys[K comparable, V any](m map[K]V, keys []K) map[K]V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
}
result := maputil.OmitByKeys(m, []string{"a", "b"})
fmt.Println(result)
// Output:
// map[c:3 d:4 e:5]
}
OmitByValues
FilterByValues的反向操作, 迭代map, 返回一个新map,其value不包括给定的value值。
函数签名:
func OmitByValues[K comparable, V comparable](m map[K]V, values []V) map[K]V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
}
result := maputil.OmitByValues(m, []int{4, 5})
fmt.Println(result)
// Output:
// map[a:1 b:2 c:3]
}
Intersect
多个map的交集操作
函数签名:
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"a": 1,
"b": 2,
"c": 6,
"d": 7,
}
m3 := map[string]int{
"a": 1,
"b": 9,
"e": 9,
}
result1 := maputil.Intersect(m1)
result2 := maputil.Intersect(m1, m2)
result3 := maputil.Intersect(m1, m2, m3)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
// Output:
// map[a:1 b:2 c:3]
// map[a:1 b:2]
// map[a:1]
}
Keys
返回map中所有key的切片
函数签名:
func Keys[K comparable, V any](m map[K]V) []K
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
keys := maputil.Keys(m)
sort.Ints(keys)
fmt.Println(keys)
// Output:
// [1 2 3 4 5]
}
Merge
合并多个maps, 相同的key会被后来的key覆盖
函数签名:
func Merge[K comparable, V any](maps ...map[K]V) map[K]V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m1 := map[int]string{
1: "a",
2: "b",
}
m2 := map[int]string{
1: "1",
3: "2",
}
result := maputil.Merge(m1, m2)
fmt.Println(result)
// Output:
// map[1:c 2:b 3:d]
}
Minus
返回一个map,其中的key存在于mapA,不存在于mapB.
函数签名:
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"a": 11,
"b": 22,
"d": 33,
}
result := maputil.Minus(m1, m2)
fmt.Println(result)
// Output:
// map[c:3]
}
Values
返回map中所有value的切片
函数签名:
func Values[K comparable, V any](m map[K]V) []V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
values := maputil.Values(m)
sort.Strings(values)
// Output:
// [a a b c d]
}
KeysBy
创建一个切片,其元素是每个map的key调用mapper函数的结果。
函数签名:
func KeysBy[K comparable, V any, T any](m map[K]V, mapper func(item K) T) []T
示例:运行
package main
import (
"fmt"
"sort"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
1: "a",
2: "a",
3: "b",
}
keys := maputil.KeysBy(m, func(n int) int {
return n + 1
})
sort.Ints(keys)
fmt.Println(keys)
// Output:
// [2 3 4]
}
ValuesBy
创建一个切片,其元素是每个map的value调用mapper函数的结果。
函数签名:
func ValuesBy[K comparable, V any, T any](m map[K]V, mapper func(item V) T) []T
示例:运行
package main
import (
"fmt"
"sort"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
1: "a",
2: "b",
3: "c",
}
values := maputil.ValuesBy(m, func(v string) string {
switch v {
case "a":
return "a-1"
case "b":
return "b-2"
case "c":
return "c-3"
default:
return ""
}
})
sort.Strings(values)
fmt.Println(values)
// Output:
// [a-1 b-2 c-3]
}
MapKeys
操作map的每个key,然后转为新的map。
函数签名:
func MapKeys[K comparable, V any, T comparable](m map[K]V, iteratee func(key K, value V) T) map[T]V
示例:运行
package main
import (
"fmt"
"strconv"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
1: "a",
2: "b",
3: "c",
}
result := maputil.MapKeys(m, func(k int, _ string) string {
return strconv.Itoa(k)
})
fmt.Println(result)
// Output:
// map[1:a 2:b 3:c]
}
MapValues
操作map的每个value,然后转为新的map。
函数签名:
func MapValues[K comparable, V any, T any](m map[K]V, iteratee func(key K, value V) T) map[K]T
示例:运行
package main
import (
"fmt"
"strconv"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
1: "a",
2: "b",
3: "c",
}
result := maputil.MapValues(m, func(k int, v string) string {
return v + strconv.Itoa(k)
})
fmt.Println(result)
// Output:
// map[1:a1 2:b2 3:c3]
}
Entry
将map转换为键/值对切片。
函数签名:
type Entry[K comparable, V any] struct {
Key K
Value V
}
func Entries[K comparable, V any](m map[K]V) []Entry[K, V]
示例:运行
package main
import (
"fmt"
"sort"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
result := maputil.Entries(m)
sort.Slice(result, func(i, j int) bool {
return result[i].Value < result[j].Value
})
fmt.Println(result)
// Output:
// [{a 1} {b 2} {c 3}]
}
FromEntries
基于键/值对的切片创建map。
函数签名:
type Entry[K comparable, V any] struct {
Key K
Value V
}
func FromEntries[K comparable, V any](entries []Entry[K, V]) map[K]V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
result := maputil.FromEntries([]Entry[string, int]{
{Key: "a", Value: 1},
{Key: "b", Value: 2},
{Key: "c", Value: 3},
})
fmt.Println(result)
// Output:
// map[a:1 b:2 c:3]
}
Transform
将map转换为其他类型的map。
函数签名:
func Transform[K1 comparable, V1 any, K2 comparable, V2 any](m map[K1]V1, iteratee func(key K1, value V1) (K2, V2)) map[K2]V2
示例:运行
package main
import (
"fmt"
"strconv"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
result := Transform(m, func(k string, v int) (string, string) {
return k, strconv.Itoa(v)
})
fmt.Println(result)
// Output:
// map[a:1 b:2 c:3]
}
IsDisjoint
验证两个map是否具有不同的key
函数签名:
func IsDisjoint[K comparable, V any](mapA, mapB map[K]V) bool
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"d": 22,
}
m3 := map[string]int{
"a": 22,
}
result1 := maputil.IsDisjoint(m1, m2)
result2 := maputil.IsDisjoint(m1, m3)
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
HasKey
检查map是否包含某个key。用于代替以下样板代码:
函数签名:
func HasKey[K comparable, V any](m map[K]V, key K) bool
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
}
result1 := maputil.HasKey(m, "a")
result2 := maputil.HasKey(m, "c")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
MapToStruct
将map转成struct。
函数签名:
func MapToStruct(m map[string]any, structObj any) error
示例:运行
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对应。
函数签名:
func ToSortedSlicesDefault[K constraints.Ordered, V any](m map[K]V) ([]K, []V)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
1: "a",
3: "c",
2: "b",
}
keys, values := ToSortedSlicesDefault(m)
fmt.Println(keys)
fmt.Println(values)
// Output:
// [1 2 3]
// [a b c]
}
ToSortedSlicesWithComparator
将map的key和value转化成两个使用比较器函数根据key的值自定义排序规则的切片,value切片中元素的位置与key对应。
函数签名:
func ToSortedSlicesWithComparator[K comparable, V any](m map[K]V, comparator func(a, b K) bool) ([]K, []V)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
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 := 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]
}
NewOrderedMap
创建有序映射。有序映射是键值对的集合,其中键是唯一的,并且保留键插入的顺序。
函数签名:
func NewOrderedMap[K comparable, V any]() *OrderedMap[K, V]
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
val1, ok := om.Get("a")
fmt.Println(val1, ok)
val2, ok := om.Get("d")
fmt.Println(val2, ok)
// Output:
// 1 true
// 0 false
}
OrderedMap_Set
设置给定的键值对。
函数签名:
func (om *OrderedMap[K, V]) Set(key K, value V)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
val1, ok := om.Get("a")
fmt.Println(val1, ok)
val2, ok := om.Get("d")
fmt.Println(val2, ok)
// Output:
// 1 true
// 0 false
}
OrderedMap_Get
返回给定键的值。
函数签名:
func (om *OrderedMap[K, V]) Get(key K) (V, bool)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
val1, ok := om.Get("a")
fmt.Println(val1, ok)
val2, ok := om.Get("d")
fmt.Println(val2, ok)
// Output:
// 1 true
// 0 false
}
OrderedMap_Delete
删除给定键的键值对。
函数签名:
func (om *OrderedMap[K, V]) Delete(key K)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
om.Delete("b")
fmt.Println(om.Keys())
// Output:
// [a c]
}
OrderedMap_Clear
清空map数据。
函数签名:
func (om *OrderedMap[K, V]) Clear()
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
om.Clear()
fmt.Println(om.Keys())
// Output:
// []
}
OrderedMap_Front
返回第一个键值对。
函数签名:
func (om *OrderedMap[K, V]) Front() (struct {
Key K
Value V
}, bool)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
frontElement, ok := om.Front()
fmt.Println(frontElement)
fmt.Println(ok)
// Output:
// {a 1}
// true
}
OrderedMap_Back
返回最后一个键值对。
函数签名:
func (om *OrderedMap[K, V]) Back() (struct {
Key K
Value V
}, bool)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
backElement, ok := om.Back()
fmt.Println(backElement)
fmt.Println(ok)
// Output:
// {c 3}
// true
}
OrderedMap_Range
为每个键值对调用给定的函数。
函数签名:
func (om *OrderedMap[K, V]) Range(iteratee func(key K, value V) bool)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
om.Range(func(key string, value int) bool {
fmt.Println(key, value)
return true
})
// Output:
// a 1
// b 2
// c 3
}
OrderedMap_Keys
按顺序返回键的切片。
函数签名:
func (om *OrderedMap[K, V]) Keys() []K
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
keys := om.Keys()
fmt.Println(keys)
// Output:
// [a b c]
}
OrderedMap_Values
按顺序返回值的切片。
函数签名:
func (om *OrderedMap[K, V]) Values() []V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
values := om.Values()
fmt.Println(values)
// Output:
// [1 2 3]
}
OrderedMap_Elements
按顺序返回键值对。
函数签名:
func (om *OrderedMap[K, V]) Elements() []struct
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
elements := om.Elements()
fmt.Println(elements)
// Output:
// [{a 1} {b 2} {c 3}]
}
OrderedMap_Len
返回键值对的数量。
函数签名:
func (om *OrderedMap[K, V]) Len() int
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
om.Len()
fmt.Println(om.Len())
// Output:
// 3
}
OrderedMap_Contains
如果给定的键存在则返回true。
函数签名:
func (om *OrderedMap[K, V]) Contains(key K) bool
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
result1 := om.Contains("a")
result2 := om.Contains("d")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
OrderedMap_Iter
返回按顺序产生键值对的通道。
函数签名:
func (om *OrderedMap[K, V]) Iter() <-chan struct {
Key K
Value V
}
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
for elem := range om.Iter() {
fmt.Println(elem)
}
// Output:
// {a 1}
// {b 2}
// {c 3}
}
OrderedMap_ReverseIter
返回以相反顺序产生键值对的通道。
函数签名:
func (om *OrderedMap[K, V]) ReverseIter() <-chan struct {
Key K
Value V
}
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
om.Set("a", 1)
om.Set("b", 2)
om.Set("c", 3)
for elem := range om.ReverseIter() {
fmt.Println(elem)
}
// Output:
// {c 3}
// {b 2}
// {a 1}
}
OrderedMap_SortByKey
使用传入的比较函数排序map key。
函数签名:
func (om *OrderedMap[K, V]) SortByKey(less func(a, b K) bool)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[int, string]()
om.Set(3, "c")
om.Set(1, "a")
om.Set(4, "d")
om.Set(2, "b")
om.SortByKey(func(a, b int) bool {
return a < b
})
fmt.Println(om.Elements())
// Output:
// [{1 a} {2 b} {3 c} {4 d}]
}
OrderedMap_MarshalJSON
实现json.Marshaler接口。
函数签名:
func (om *OrderedMap[K, V]) MarshalJSON() ([]byte, error)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[int, string]()
om.Set(3, "c")
om.Set(1, "a")
om.Set(4, "d")
om.Set(2, "b")
b, _ := om.MarshalJSON()
fmt.Println(string(b))
// Output:
// {"a":1,"b":2,"c":3}
}
OrderedMap_UnmarshalJSON
实现json.Unmarshaler接口。
函数签名:
func (om *OrderedMap[K, V]) UnmarshalJSON(data []byte) error
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
om := maputil.NewOrderedMap[string, int]()
data := []byte(`{"a":1,"b":2,"c":3}`)
om.UnmarshalJSON(data)
fmt.Println(om.Elements())
// Output:
// [{a 1} {b 2} {c 3}]
}
NewConcurrentMap
ConcurrentMap协程安全的map结构。
函数签名:
// NewConcurrentMap create a ConcurrentMap with specific shard count.
func NewConcurrentMap[K comparable, V any](shardCount int) *ConcurrentMap[K, V]
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
// create a ConcurrentMap whose key type is string, value type is int
cm := maputil.NewConcurrentMap[string, int](100)
}
ConcurrentMap_Set
在map中设置key和value。
函数签名:
func (cm *ConcurrentMap[K, V]) Set(key K, value V)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
cm := maputil.NewConcurrentMap[string, int](100)
var wg1 sync.WaitGroup
wg1.Add(5)
for i := 0; i < 5; i++ {
go func(n int) {
cm.Set(fmt.Sprintf("%d", n), n)
wg1.Done()
}(i)
}
wg1.Wait()
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()
// output: (order may change)
// 1 true
// 3 true
// 2 true
// 0 true
// 4 true
}
ConcurrentMap_Get
根据key获取value, 如果不存在key,返回零值。
函数签名:
func (cm *ConcurrentMap[K, V]) Get(key K) (V, bool)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
cm := maputil.NewConcurrentMap[string, int](100)
var wg1 sync.WaitGroup
wg1.Add(5)
for i := 0; i < 5; i++ {
go func(n int) {
cm.Set(fmt.Sprintf("%d", n), n)
wg1.Done()
}(i)
}
wg1.Wait()
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()
// output: (order may change)
// 1 true
// 3 true
// 2 true
// 0 true
// 4 true
}
ConcurrentMap_GetOrSet
返回键的现有值(如果存在),否则,设置key并返回给定值。
函数签名:
func (cm *ConcurrentMap[K, V]) GetOrSet(key K, value V) (actual V, ok bool)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
cm := maputil.NewConcurrentMap[string, int](100)
var wg sync.WaitGroup
wg.Add(5)
for i := 0; i < 5; i++ {
go func(n int) {
val, ok := cm.GetOrSet(fmt.Sprintf("%d", n), n)
fmt.Println(val, ok)
wg.Done()
}(i)
}
wg.Wait()
// output: (order may change)
// 1 false
// 3 false
// 2 false
// 0 false
// 4 false
}
ConcurrentMap_Delete
删除key。
函数签名:
func (cm *ConcurrentMap[K, V]) Delete(key K)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
cm := maputil.NewConcurrentMap[string, int](100)
var wg1 sync.WaitGroup
wg1.Add(5)
for i := 0; i < 5; i++ {
go func(n int) {
cm.Set(fmt.Sprintf("%d", n), n)
wg1.Done()
}(i)
}
wg1.Wait()
var wg2 sync.WaitGroup
wg2.Add(5)
for j := 0; j < 5; j++ {
go func(n int) {
cm.Delete(fmt.Sprintf("%d", n))
wg2.Done()
}(i)
}
wg2.Wait()
}
ConcurrentMap_GetAndDelete
获取key,然后删除。
函数签名:
func (cm *ConcurrentMap[K, V]) GetAndDelete(key K) (actual V, ok bool)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
cm := maputil.NewConcurrentMap[string, int](100)
var wg1 sync.WaitGroup
wg1.Add(5)
for i := 0; i < 5; i++ {
go func(n int) {
cm.Set(fmt.Sprintf("%d", n), n)
wg1.Done()
}(i)
}
wg1.Wait()
var wg2 sync.WaitGroup
wg2.Add(5)
for j := 0; j < 5; j++ {
go func(n int) {
val, ok := cm.GetAndDelete(fmt.Sprintf("%d", n))
fmt.Println(val, ok) //n, true
_, ok = cm.Get(fmt.Sprintf("%d", n))
fmt.Println(val, ok) //false
wg2.Done()
}(j)
}
wg2.Wait()
}
ConcurrentMap_Has
验证是否包含key。
函数签名:
func (cm *ConcurrentMap[K, V]) Has(key K) bool
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
cm := maputil.NewConcurrentMap[string, int](100)
var wg1 sync.WaitGroup
wg1.Add(5)
for i := 0; i < 5; i++ {
go func(n int) {
cm.Set(fmt.Sprintf("%d", n), n)
wg1.Done()
}(i)
}
wg1.Wait()
var wg2 sync.WaitGroup
wg2.Add(5)
for j := 0; j < 5; j++ {
go func(n int) {
ok := cm.Has(fmt.Sprintf("%d", n))
fmt.Println(ok) // true
wg2.Done()
}(j)
}
wg2.Wait()
}
ConcurrentMap_Range
为map中每个键和值顺序调用迭代器。 如果iterator返回false,则停止迭代。
函数签名:
func (cm *ConcurrentMap[K, V]) Range(iterator func(key K, value V) bool)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
cm := maputil.NewConcurrentMap[string, int](100)
var wg1 sync.WaitGroup
wg1.Add(5)
for i := 0; i < 5; i++ {
go func(n int) {
cm.Set(fmt.Sprintf("%d", n), n)
wg1.Done()
}(i)
}
wg1.Wait()
cm.Range(func(key string, value int) bool {
fmt.Println(value)
return true
})
}
GetOrSet
返回给定键的值,如果不存在则设置该值。
函数签名:
func GetOrSet[K comparable, V any](m map[K]V, key K, value V) V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
1: "a",
}
result1 := maputil.GetOrSet(m, 1, "1")
result2 := maputil.GetOrSet(m, 2, "b")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// a
// b
}
SortByKey
对传入的map根据key进行排序,返回排序后的map。
函数签名:
func SortByKey[K constraints.Ordered, V any](m map[K]V) (sortedKeysMap map[K]V)
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
3: "c",
1: "a",
4: "d",
2: "b",
}
result := maputil.SortByKey(m, func(a, b int) bool {
return a < b
})
fmt.Println(result)
// Output:
// map[1:a 2:b 3:c 4:d]
}
GetOrDefault
返回给定键的值,如果键不存在,则返回默认值。
函数签名:
func GetOrDefault[K comparable, V any](m map[K]V, key K, defaultValue V) V
示例:运行
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
3: "c",
1: "a",
4: "d",
2: "b",
}
result1 := maputil.GetOrDefault(m, 1, "default")
result2 := maputil.GetOrDefault(m, 6, "default")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// a
// default
}