Skip to content

Maputil

maputil 包包括一些操作 map 的函数。

源码:

用法:

go
import (
    "github.com/duke-git/lancet/v2/maputil"
)

目录:

API 文档:

MapTo

快速将map或者其他类型映射到结构体或者指定类型。

函数签名:

go
func MapTo(src any, dst any) error

示例:运行

go
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函数

函数签名:

go
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V))

示例:运行

go
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。

函数签名:

go
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V

示例:运行

go
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值。

函数签名:

go
func FilterByKeys[K comparable, V any](m map[K]V, keys []K) map[K]V

示例:运行

go
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值。

函数签名:

go
func FilterByValues[K comparable, V comparable](m map[K]V, values []V) map[K]V

示例:运行

go
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。

函数签名:

go
func OmitBy[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V

示例:运行

go
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值。

函数签名:

go
func OmitByKeys[K comparable, V any](m map[K]V, keys []K) map[K]V

示例:运行

go
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值。

函数签名:

go
func OmitByValues[K comparable, V comparable](m map[K]V, values []V) map[K]V

示例:运行

go
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的交集操作

函数签名:

go
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V

示例:运行

go
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的切片

函数签名:

go
func Keys[K comparable, V any](m map[K]V) []K

示例:运行

go
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覆盖

函数签名:

go
func Merge[K comparable, V any](maps ...map[K]V) map[K]V

示例:运行

go
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.

函数签名:

go
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V

示例:运行

go
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的切片

函数签名:

go
func Values[K comparable, V any](m map[K]V) []V

示例:运行

go
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函数的结果。

函数签名:

go
func KeysBy[K comparable, V any, T any](m map[K]V, mapper func(item K) T) []T

示例:运行

go
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函数的结果。

函数签名:

go
func ValuesBy[K comparable, V any, T any](m map[K]V, mapper func(item V) T) []T

示例:运行

go
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。

函数签名:

go
func MapKeys[K comparable, V any, T comparable](m map[K]V, iteratee func(key K, value V) T) map[T]V

示例:运行

go
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。

函数签名:

go
func MapValues[K comparable, V any, T any](m map[K]V, iteratee func(key K, value V) T) map[K]T

示例:运行

go
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转换为键/值对切片。

函数签名:

go
type Entry[K comparable, V any] struct {
    Key   K
    Value V
}
func Entries[K comparable, V any](m map[K]V) []Entry[K, V]

示例:运行

go
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。

函数签名:

go
type Entry[K comparable, V any] struct {
    Key   K
    Value V
}
func FromEntries[K comparable, V any](entries []Entry[K, V]) map[K]V

示例:运行

go
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。

函数签名:

go
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

示例:运行

go
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

函数签名:

go
func IsDisjoint[K comparable, V any](mapA, mapB map[K]V) bool

示例:运行

go
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。用于代替以下样板代码:

函数签名:

go
func HasKey[K comparable, V any](m map[K]V, key K) bool

示例:运行

go
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。

函数签名:

go
func MapToStruct(m map[string]any, structObj any) error

示例:运行

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对应。

函数签名:

go
func ToSortedSlicesDefault[K constraints.Ordered, V any](m map[K]V) ([]K, []V)

示例:运行

go
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对应。

函数签名:

go
func ToSortedSlicesWithComparator[K comparable, V any](m map[K]V, comparator func(a, b K) bool) ([]K, []V)

示例:运行

go
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

创建有序映射。有序映射是键值对的集合,其中键是唯一的,并且保留键插入的顺序。

函数签名:

go
func NewOrderedMap[K comparable, V any]() *OrderedMap[K, V]

示例:运行

go
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

设置给定的键值对。

函数签名:

go
func (om *OrderedMap[K, V]) Set(key K, value V)

示例:运行

go
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

返回给定键的值。

函数签名:

go
func (om *OrderedMap[K, V]) Get(key K) (V, bool)

示例:运行

go
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

删除给定键的键值对。

函数签名:

go
func (om *OrderedMap[K, V]) Delete(key K)

示例:运行

go
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数据。

函数签名:

go
func (om *OrderedMap[K, V]) Clear()

示例:运行

go
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

返回第一个键值对。

函数签名:

go
func (om *OrderedMap[K, V]) Front() (struct {
    Key   K
    Value V
}, bool)

示例:运行

go
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

返回最后一个键值对。

函数签名:

go
func (om *OrderedMap[K, V]) Back() (struct {
    Key   K
    Value V
}, bool)

示例:运行

go
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

为每个键值对调用给定的函数。

函数签名:

go
func (om *OrderedMap[K, V]) Range(iteratee func(key K, value V) bool)

示例:运行

go
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

按顺序返回键的切片。

函数签名:

go
func (om *OrderedMap[K, V]) Keys() []K

示例:运行

go
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

按顺序返回值的切片。

函数签名:

go
func (om *OrderedMap[K, V]) Values() []V

示例:运行

go
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

按顺序返回键值对。

函数签名:

go
func (om *OrderedMap[K, V]) Elements() []struct

示例:运行

go
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

返回键值对的数量。

函数签名:

go
func (om *OrderedMap[K, V]) Len() int

示例:运行

go
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。

函数签名:

go
func (om *OrderedMap[K, V]) Contains(key K) bool

示例:运行

go
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

返回按顺序产生键值对的通道。

函数签名:

go
func (om *OrderedMap[K, V]) Iter() <-chan struct {
    Key   K
    Value V
}

示例:运行

go
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

返回以相反顺序产生键值对的通道。

函数签名:

go
func (om *OrderedMap[K, V]) ReverseIter() <-chan struct {
    Key   K
    Value V
}

示例:运行

go
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。

函数签名:

go
func (om *OrderedMap[K, V]) SortByKey(less func(a, b K) bool)

示例:运行

go
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接口。

函数签名:

go
func (om *OrderedMap[K, V]) MarshalJSON() ([]byte, error)

示例:运行

go
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接口。

函数签名:

go
func (om *OrderedMap[K, V]) UnmarshalJSON(data []byte) error

示例:运行

go
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结构。

函数签名:

go
// NewConcurrentMap create a ConcurrentMap with specific shard count.
func NewConcurrentMap[K comparable, V any](shardCount int) *ConcurrentMap[K, V]

示例:运行

go
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。

函数签名:

go
func (cm *ConcurrentMap[K, V]) Set(key K, value V)

示例:运行

go
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,返回零值。

函数签名:

go
func (cm *ConcurrentMap[K, V]) Get(key K) (V, bool)

示例:运行

go
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并返回给定值。

函数签名:

go
func (cm *ConcurrentMap[K, V]) GetOrSet(key K, value V) (actual V, ok bool)

示例:运行

go
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。

函数签名:

go
func (cm *ConcurrentMap[K, V]) Delete(key K)

示例:运行

go
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,然后删除。

函数签名:

go
func (cm *ConcurrentMap[K, V]) GetAndDelete(key K) (actual V, ok bool)

示例:运行

go
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。

函数签名:

go
func (cm *ConcurrentMap[K, V]) Has(key K) bool

示例:运行

go
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,则停止迭代。

函数签名:

go
func (cm *ConcurrentMap[K, V]) Range(iterator func(key K, value V) bool)

示例:运行

go
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

返回给定键的值,如果不存在则设置该值。

函数签名:

go
func GetOrSet[K comparable, V any](m map[K]V, key K, value V) V

示例:运行

go
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。

函数签名:

go
func SortByKey[K constraints.Ordered, V any](m map[K]V) (sortedKeysMap map[K]V)

示例:运行

go
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

返回给定键的值,如果键不存在,则返回默认值。

函数签名:

go
func GetOrDefault[K comparable, V any](m map[K]V, key K, defaultValue V) V

示例:运行

go
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
}