From 8e36ef5cef445d2d217c3e41fcf8096df94ff4f3 Mon Sep 17 00:00:00 2001 From: dudaodong Date: Wed, 22 Feb 2023 16:59:01 +0800 Subject: [PATCH] doc: add doc for new map functions --- docs/maputil.md | 509 +++++++++++++++++++++++++++++++++++- docs/maputil_zh-CN.md | 504 ++++++++++++++++++++++++++++++++++- maputil/map_example_test.go | 54 ++++ 3 files changed, 1065 insertions(+), 2 deletions(-) diff --git a/docs/maputil.md b/docs/maputil.md index 6da6fd3b..e70733e3 100644 --- a/docs/maputil.md +++ b/docs/maputil.md @@ -24,11 +24,23 @@ import ( - [ForEach](#ForEach) - [Filter](#Filter) +- [FilterByKeys](#FilterByKeys) +- [FilterByValues](#FilterByValues) +- [OmitBy](#OmitBy) +- [OmitByKeys](#OmitByKeys) +- [OmitByValues](#OmitByValues) - [Intersect](#Intersect) - [Keys](#Keys) +- [Values](#Values) +- [KeysBy](#KeysBy) +- [ValuesBy](#ValuesBy) +- [MapKeys](#MapKeys) +- [MapValues](#MapValues) +- [Entries](#Entries) +- [FromEntries](#FromEntries) +- [Transform](#Transform) - [Merge](#Merge) - [Minus](#Minus) -- [Values](#Values) - [IsDisjoint](#IsDisjoint)
@@ -121,6 +133,205 @@ func main() { } ``` + +### FilterByKeys + +

Iterates over map, return a new map whose keys are all given keys.

+ +Signature: + +```go +func FilterByKeys[K comparable, V any](m map[K]V, keys []K) map[K]V +``` + +Example: + +```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 + +

Iterates over map, return a new map whose values are all given values.

+ +Signature: + +```go +func FilterByValues[K comparable, V comparable](m map[K]V, values []V) map[K]V +``` + +Example: + +```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 + +

OmitBy is the opposite of Filter, removes all the map elements for which the predicate function returns true.

+ +Signature: + +```go +func OmitBy[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V +``` + +Example: + +```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 + +

The opposite of FilterByKeys, extracts all the map elements which keys are not omitted.

+ +Signature: + +```go +func OmitByKeys[K comparable, V any](m map[K]V, keys []K) map[K]V +``` + +Example: + +```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 + +

The opposite of FilterByValues. remov all elements whose value are in the give slice.

+ +Signature: + +```go +func OmitByValues[K comparable, V comparable](m map[K]V, values []V) map[K]V +``` + +Example: + +```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

Iterates over maps, return a new map of key and value pairs in all given maps.

@@ -193,6 +404,7 @@ package main import ( "fmt" + "sort" "github.com/duke-git/lancet/v2/maputil" ) @@ -313,6 +525,7 @@ package main import ( "fmt" + "sort" "github.com/duke-git/lancet/v2/maputil" ) @@ -335,6 +548,300 @@ func main() { } ``` +### KeysBy + +

Creates a slice whose element is the result of function mapper invoked by every map's key.

+ +Signature: + +```go +func KeysBy[K comparable, V any, T any](m map[K]V, mapper func(item K) T) []T +``` + +Example: + +```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 + +

Creates a slice whose element is the result of function mapper invoked by every map's value.

+ +Signature: + +```go +func ValuesBy[K comparable, V any, T any](m map[K]V, mapper func(item V) T) []T +``` + +Example: + +```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 + +

Transforms a map to other type map by manipulating it's keys.

+ +Signature: + +```go +func MapKeys[K comparable, V any, T comparable](m map[K]V, iteratee func(key K, value V) T) map[T]V +``` + +Example: + +```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 + +

Transforms a map to other type map by manipulating it's values.

+ +Signature: + +```go +func MapValues[K comparable, V any, T any](m map[K]V, iteratee func(key K, value V) T) map[K]T +``` + +Example: + +```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 + +

Transforms a map into array of key/value pairs.

+ +Signature: + +```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] +``` + +Example: + +```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 + +

Creates a map based on a slice of key/value pairs.

+ +Signature: + +```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 +``` + +Example: + +```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 + +

Transform a map to another type map.

+ +Signature: + +```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 +``` + +Example: + +```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

Checks two maps are disjoint if they have no keys in common

diff --git a/docs/maputil_zh-CN.md b/docs/maputil_zh-CN.md index 3ffc88ad..12d5950b 100644 --- a/docs/maputil_zh-CN.md +++ b/docs/maputil_zh-CN.md @@ -24,11 +24,23 @@ import ( - [ForEach](#ForEach) - [Filter](#Filter) +- [FilterByKeys](#FilterByKeys) +- [FilterByValues](#FilterByValues) +- [OmitBy](#OmitBy) +- [OmitByKeys](#OmitByKeys) +- [OmitByValues](#OmitByValues) - [Intersect](#Intersect) - [Keys](#Keys) +- [Values](#Values) +- [KeysBy](#KeysBy) +- [ValuesBy](#ValuesBy) +- [MapKeys](#MapKeys) +- [MapValues](#MapValues) +- [Entries](#Entries) +- [FromEntries](#FromEntries) +- [Transform](#Transform) - [Merge](#Merge) - [Minus](#Minus) -- [Values](#Values) - [IsDisjoint](#IsDisjoint)
@@ -121,6 +133,203 @@ func main() { } ``` +### 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的交集操作

@@ -333,6 +542,299 @@ func main() { } ``` +### 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

diff --git a/maputil/map_example_test.go b/maputil/map_example_test.go index c6b42f11..3909a14c 100644 --- a/maputil/map_example_test.go +++ b/maputil/map_example_test.go @@ -343,3 +343,57 @@ func ExampleMapValues() { // Output: // map[1:a1 2:b2 3:c3] } + +func ExampleOmitBy() { + 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 := OmitBy(m, isEven) + + fmt.Println(result) + + // Output: + // map[a:1 c:3 e:5] +} + +func ExampleOmitByKeys() { + m := map[string]int{ + "a": 1, + "b": 2, + "c": 3, + "d": 4, + "e": 5, + } + + result := OmitByKeys(m, []string{"a", "b"}) + + fmt.Println(result) + + // Output: + // map[c:3 d:4 e:5] +} + +func ExampleOmitByValues() { + m := map[string]int{ + "a": 1, + "b": 2, + "c": 3, + "d": 4, + "e": 5, + } + + result := OmitByValues(m, []int{4, 5}) + + fmt.Println(result) + + // Output: + // map[a:1 b:2 c:3] +}