diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..d8f0939e
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,3 @@
+# These are supported funding model platforms
+liberapay: Duke_Du
+patreon: DukeDu
diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml
index 9c657fb2..526728eb 100644
--- a/.github/workflows/codecov.yml
+++ b/.github/workflows/codecov.yml
@@ -3,11 +3,11 @@ on:
push:
branches:
- main
- # - v2
+ - rc
pull_request:
branches:
- main
- # - v2
+ - rc
jobs:
build:
runs-on: ubuntu-latest
@@ -17,8 +17,10 @@ jobs:
fetch-depth: 2
- uses: actions/setup-go@v2
with:
- go-version: "1.16"
+ go-version: "1.20"
- name: Run coverage
run: go test -v ./... -coverprofile=coverage.txt -covermode=atomic
+ - name: Run govet
+ run: go vet -v ./...
- name: Upload coverage to Codecov
run: bash <(curl -s https://codecov.io/bash)
diff --git a/.gitignore b/.gitignore
index fce5a7c3..a4d5b55b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,10 @@ fileutil/*.txt
fileutil/*.zip
fileutil/*.link
fileutil/unzip/*
-cryptor/*.pem
\ No newline at end of file
+fileutil/tempdir/*
+slice/testdata/*
+# cryptor/*.pem
+test
+docs/node_modules
+docs/.vitepress/cache
+docs/.vitepress/dist
diff --git a/CONTRIBUTION.md b/CONTRIBUTION.md
new file mode 100644
index 00000000..f16cfb2a
--- /dev/null
+++ b/CONTRIBUTION.md
@@ -0,0 +1,37 @@
+# Lancet Contribution Guide
+
+Hi! Thank you for choosing Lancet.
+
+Lancet is a powerful, efficient, and reusable util function library of go. It makes Go dev easier by taking the hassle out of working with concurrency, net, math, slice, string, etc.
+
+We are excited that you are interested in contributing to lancet. Before submitting your contribution though, please make sure to take a moment and read through the following guidelines.
+
+## Issue Guidelines
+
+- Issues are exclusively for bug reports, feature requests and design-related topics. Other questions may be closed directly.
+
+- Before submitting an issue, please check if similar problems have already been issued.
+
+- Please specify which version of Lancet and Go you are using, and provide OS information. [Go Playground](https://go.dev/play/) is recommended to build a live demo so that your issue can be reproduced clearly.
+
+## Pull Request Guidelines
+
+- Fork this repository to your own account. Do not create branches here.
+
+- Commit info should be formatted as `type(scope): info about commit`. eg. `fix(package): [scrollbar] fix xxx bug`.
+
+ 1. type: type must be one of [chore, docs, feat, fix, refactor, release, test].
+
+ 2. scope: scope must be one of [package, file, internal].
+
+ 3. header: header must not be longer than 72 characters.
+
+- Rebase before creating a PR to keep commit history clear.
+
+- Before submitting a PR, please execute the unit test command: `go test -v ./...` to ensure that all unit test tasks should pass.
+
+- Make sure PRs are created to `rc` branch instead of other branch.
+
+- If your PR fixes a bug, please provide a description about the related bug.
+
+- If the PR is for a new feature, make sure to complete the relevant documentation (/lancet/docs/en/api/packages).
diff --git a/CONTRIBUTION.zh-CN.md b/CONTRIBUTION.zh-CN.md
new file mode 100644
index 00000000..c2afda26
--- /dev/null
+++ b/CONTRIBUTION.zh-CN.md
@@ -0,0 +1,37 @@
+# Lancet 贡献指南
+
+Hi! 首先感谢你使用 Lancet。
+
+lancet(柳叶刀)是一个功能强大、全面、高效、可复用的go语言工具函数库。它消除了处理并发、网络、数学、切片、字符串等的麻烦,使 Go 开发变得更容易。
+
+Lancet 的成长离不开大家的支持,如果你愿意为 Lancet 贡献代码或提供建议,请阅读以下内容。
+
+## Issue 规范
+
+- issue 仅用于提交 Bug 或 Feature 以及设计相关的内容,其它内容可能会被直接关闭。
+
+- 在提交 issue 之前,请搜索相关内容是否已被提出。
+
+- 请说明 Lancet 和 Go 的版本号,并提供操作系统信息。推荐使用 [Go Playground](https://go.dev/play/) 生成在线 demo,这能够更直观地重现问题。
+
+## Pull Request 规范
+
+- 请先 fork 一份到自己的项目下,不要直接在仓库下建分支。
+
+- commit 信息要以 `type(scope): 描述信息` 的形式填写,例如 `fix(package): [scrollbar] fix xxx bug`。
+
+ 1. type: 必须是 chore, docs, feat, fix, refactor, release, test 其中的一个。
+
+ 2. scope: 必须是 package, file, internal 其中的一个。
+
+ 3. header: 描述信息不要超过 72 个字符。
+
+- 提交 PR 前请 rebase,确保 commit 记录的整洁。
+
+- 提交 PR 前请执行单元测试命令:go test -v ./...,确保所有单元测试任务通过。
+
+- 确保 PR 是提交到 `rc` 分支,而不是其他分支。
+
+- 如果是修复 bug,请在 PR 中给出描述信息。
+
+- 如果PR是新功能,确保完成相关文档(/lancet/docs/api/packages)。
\ No newline at end of file
diff --git a/README.md b/README.md
index b9ed128d..bf6d5df7 100644
--- a/README.md
+++ b/README.md
@@ -3,13 +3,14 @@
- +``` + +示例:[运行](https://go.dev/play/p/GNdv7Jg2Taj) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + algorithm.BubbleSort(numbers, comparator) + + fmt.Println(numbers) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### InsertionSort + +插入排序,参数comparator需要实现包constraints.Comparator。
+ +函数签名: + +```go +func InsertionSort[T any](slice []T, comparator constraints.Comparator) +``` + +示例:[运行](https://go.dev/play/p/G5LJiWgJJW6) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type people struct { + Name string + Age int +} + +// PeopleAageComparator sort people slice by age field +type peopleAgeComparator struct{} + +// Compare implements github.com/duke-git/lancet/constraints/constraints.go/Comparator +func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int { + p1, _ := v1.(people) + p2, _ := v2.(people) + + //ascending order + if p1.Age < p2.Age { + return -1 + } else if p1.Age > p2.Age { + return 1 + } + + return 0 +} + +func main() { + peoples := []people{ + {Name: "a", Age: 20}, + {Name: "b", Age: 10}, + {Name: "c", Age: 17}, + {Name: "d", Age: 8}, + {Name: "e", Age: 28}, + } + + comparator := &peopleAgeComparator{} + + algorithm.InsertionSort(peoples, comparator) + + fmt.Println(peoples) + + // Output: + // [{d 8} {b 10} {c 17} {a 20} {e 28}] +} +``` + +### SelectionSort + +选择排序,参数comparator需要实现包constraints.Comparator。
+ +函数签名: + +```go +func SelectionSort[T any](slice []T, comparator constraints.Comparator) +``` + +示例:[运行](https://go.dev/play/p/oXovbkekayS) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + algorithm.SelectionSort(numbers, comparator) + + fmt.Println(numbers) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### ShellSort + +希尔排序,参数comparator需要实现包constraints.Comparator。
+ +函数签名: + +```go +func ShellSort[T any](slice []T, comparator constraints.Comparator) +``` + +示例:[运行](https://go.dev/play/p/3ibkszpJEu3) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + algorithm.ShellSort(numbers, comparator) + + fmt.Println(numbers) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### QuickSort + +快速排序,参数comparator需要实现包constraints.Comparator。
+ +函数签名: + +```go +func QuickSort[T any](slice []T comparator constraints.Comparator) +``` + +示例:[运行](https://go.dev/play/p/7Y7c1Elk3ax) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + algorithm.QuickSort(numbers, comparator) + + fmt.Println(numbers) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### HeapSort + +堆排序,参数comparator需要实现包constraints.Comparator。
+ +函数签名: + +```go +func HeapSort[T any](slice []T, comparator constraints.Comparator) +``` + +示例:[运行](https://go.dev/play/p/u6Iwa1VZS_f) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + algorithm.HeapSort(numbers, comparator) + + fmt.Println(numbers) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### MergeSort + +归并排序,参数comparator需要实现包constraints.Comparator。
+ +函数签名: + +```go +func MergeSort[T any](slice []T, comparator constraints.Comparator) +``` + +示例:[运行](https://go.dev/play/p/ydinn9YzUJn) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + algorithm.MergeSort(numbers, comparator) + + fmt.Println(numbers) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### CountSort + +计数排序,参数comparator需要实现包constraints.Comparator。
+ +函数签名: + +```go +func CountSort[T any](slice []T, comparator constraints.Comparator) []T +``` + +示例:[运行](https://go.dev/play/p/tB-Umgm0DrP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + sortedNums := algorithm.CountSort(numbers, comparator) + + fmt.Println(sortedNums) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### BinarySearch + +二分递归查找,返回元素索引,未找到元素返回-1,参数comparator需要实现包constraints.Comparator。
+ +函数签名: + +```go +func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator constraints.Comparator) int +``` + +示例: [运行](https://go.dev/play/p/t6MeGiUSN47) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{1, 2, 3, 4, 5, 6, 7, 8} + comparator := &intComparator{} + + result1 := algorithm.BinarySearch(numbers, 5, 0, len(numbers)-1, comparator) + result2 := algorithm.BinarySearch(numbers, 9, 0, len(numbers)-1, comparator) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 4 + // -1 +} +``` + +### BinaryIterativeSearch + +二分迭代查找,返回元素索引,未找到元素返回-1,参数comparator需要实现包constraints.Comparator。
+ +函数签名: + +```go +func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator constraints.Comparator) int +``` + +示例: [运行](https://go.dev/play/p/Anozfr8ZLH3) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{1, 2, 3, 4, 5, 6, 7, 8} + comparator := &intComparator{} + + result1 := algorithm.BinaryIterativeSearch(numbers, 5, 0, len(numbers)-1, comparator) + result2 := algorithm.BinaryIterativeSearch(numbers, 9, 0, len(numbers)-1, comparator) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 4 + // -1 +} +``` + +### LinearSearch + +基于传入的相等函数线性查找元素,返回元素索引,未找到元素返回-1。
+ +函数签名: + +```go +func LinearSearch[T any](slice []T, target T, equal func(a, b T) bool) int +``` + +示例: [运行](https://go.dev/play/p/IsS7rgn5s3x) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +func main() { + numbers := []int{3, 4, 5, 3, 2, 1} + + equalFunc := func(a, b int) bool { + return a == b + } + + result1 := algorithm.LinearSearch(numbers, 3, equalFunc) + result2 := algorithm.LinearSearch(numbers, 6, equalFunc) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // -1 +} +``` + +### LRUCache + +lru算法实现缓存。
+ +函数签名: + +```go +func NewLRUCache[K comparable, V any](capacity int) *LRUCache[K, V] +func (l *LRUCache[K, V]) Get(key K) (V, bool) +func (l *LRUCache[K, V]) Put(key K, value V) +func (l *LRUCache[K, V]) Delete(key K) bool +func (l *LRUCache[K, V]) Len() int +``` + +示例:[运行](https://go.dev/play/p/-EZjgOURufP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +func main() { + cache := algorithm.NewLRUCache[int, int](2) + + cache.Put(1, 1) + cache.Put(2, 2) + + result1, ok1 := cache.Get(1) + result2, ok2 := cache.Get(2) + result3, ok3 := cache.Get(3) + + fmt.Println(result1, ok1) + fmt.Println(result2, ok2) + fmt.Println(result3, ok3) + + fmt.Println(cache.Len()) + + ok := cache.Delete(2) + fmt.Println(ok) + + + // Output: + // 1 true + // 2 true + // 0 false + // 2 + // true +} +``` diff --git a/docs/api/packages/compare.md b/docs/api/packages/compare.md new file mode 100644 index 00000000..773506ff --- /dev/null +++ b/docs/api/packages/compare.md @@ -0,0 +1,375 @@ +# Compare + +compare包提供几个轻量级的类型比较函数。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/compare/compare.go](https://github.com/duke-git/lancet/blob/main/compare/compare.go) + +- [https://github.com/duke-git/lancet/blob/main/compare/compare_internal.go](https://github.com/duke-git/lancet/blob/main/compare/compare_internal.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/condition" +) +``` + + + +## 目录 + +- [Equal](#Equal) +- [EqualValue](#EqualValue) +- [LessThan](#LessThan) +- [GreaterThan](#GreaterThan) +- [LessOrEqual](#LessOrEqual) +- [GreaterOrEqual](#GreaterOrEqual) +- [InDelta](#InDelta) + + + + +## 文档 + +### Equal + +检查两个值是否相等(检查类型和值)
+ +函数签名: + +```go +func Equal(left, right any) bool +``` + +示例: [运行](https://go.dev/play/p/wmVxR-to4lz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := compare.Equal(1, 1) + result2 := compare.Equal("1", "1") + result3 := compare.Equal([]int{1, 2, 3}, []int{1, 2, 3}) + result4 := compare.Equal(map[int]string{1: "a", 2: "b"}, map[int]string{1: "a", 2: "b"}) + + result5 := compare.Equal(1, "1") + result6 := compare.Equal(1, int64(1)) + result7 := compare.Equal([]int{1, 2}, []int{1, 2, 3}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + + // Output: + // true + // true + // true + // true + // false + // false + // false +} +``` + +### EqualValue + +检查两个值是否相等(只检查值)
+ +函数签名: + +```go +func EqualValue(left, right any) bool +``` + +示例: [运行](https://go.dev/play/p/fxnna_LLD9u) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := compare.EqualValue(1, 1) + result2 := compare.EqualValue(int(1), int64(1)) + result3 := compare.EqualValue(1, "1") + result4 := compare.EqualValue(1, "2") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // true + // false +} +``` + +### LessThan + +验证参数`left`的值是否小于参数`right`的值。
+ +函数签名: + +```go +func LessThan(left, right any) bool +``` + +示例: [运行](https://go.dev/play/p/cYh7FQQj0ne) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := compare.LessThan(1, 2) + result2 := compare.LessThan(1.1, 2.2) + result3 := compare.LessThan("a", "b") + + time1 := time.Now() + time2 := time1.Add(time.Second) + result4 := compare.LessThan(time1, time2) + + result5 := compare.LessThan(2, 1) + result6 := compare.LessThan(1, int64(2)) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // true + // true + // true + // true + // false + // false +} +``` + +### GreaterThan + +验证参数`left`的值是否大于参数`right`的值。
+ +函数签名: + +```go +func GreaterThan(left, right any) bool +``` + +示例: [运行](https://go.dev/play/p/9-NYDFZmIMp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := compare.GreaterThan(2, 1) + result2 := compare.GreaterThan(2.2, 1.1) + result3 := compare.GreaterThan("b", "a") + + time1 := time.Now() + time2 := time1.Add(time.Second) + result4 := compare.GreaterThan(time2, time1) + + result5 := compare.GreaterThan(1, 2) + result6 := compare.GreaterThan(int64(2), 1) + result7 := compare.GreaterThan("b", "c") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + + // Output: + // true + // true + // true + // true + // false + // false + // false +} +``` + +### LessOrEqual + +验证参数`left`的值是否小于或等于参数`right`的值。
+ +函数签名: + +```go +func LessOrEqual(left, right any) bool +``` + +示例: [运行](https://go.dev/play/p/e4T_scwoQzp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := compare.LessOrEqual(1, 1) + result2 := compare.LessOrEqual(1.1, 2.2) + result3 := compare.LessOrEqual("a", "b") + + time1 := time.Now() + time2 := time1.Add(time.Second) + result4 := compare.LessOrEqual(time1, time2) + + result5 := compare.LessOrEqual(2, 1) + result6 := compare.LessOrEqual(1, int64(2)) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // true + // true + // true + // true + // false + // false +} +``` + +### GreaterOrEqual + +验证参数`left`的值是否大于或参数`right`的值。
+ +函数签名: + +```go +func GreaterOrEqual(left, right any) bool +``` + +示例: [运行](https://go.dev/play/p/vx8mP0U8DFk) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := compare.GreaterOrEqual(1, 1) + result2 := compare.GreaterOrEqual(2.2, 1.1) + result3 := compare.GreaterOrEqual("b", "b") + + time1 := time.Now() + time2 := time1.Add(time.Second) + result4 := compare.GreaterOrEqual(time2, time1) + + result5 := compare.GreaterOrEqual(1, 2) + result6 := compare.GreaterOrEqual(int64(2), 1) + result7 := compare.GreaterOrEqual("b", "c") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + + // Output: + // true + // true + // true + // true + // false + // false + // false +} +``` + +### InDelta + +检查增量内两个值是否相等。
+ +函数签名: + +```go +func InDelta[T constraints.Integer | constraints.Float](left, right T, delta float64) bool +``` + +示例: [运行](https://go.dev/play/p/TuDdcNtMkjo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := InDelta(1, 1, 0) + result2 := InDelta(1, 2, 0) + + result3 := InDelta(2.0/3.0, 0.66667, 0.001) + result4 := InDelta(2.0/3.0, 0.0, 0.001) + + result5 := InDelta(float64(74.96)-float64(20.48), 54.48, 0) + result6 := InDelta(float64(74.96)-float64(20.48), 54.48, 1e-14) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // true + // false + // true + // false + // false + // true +} +``` diff --git a/docs/api/packages/concurrency.md b/docs/api/packages/concurrency.md new file mode 100644 index 00000000..a6946426 --- /dev/null +++ b/docs/api/packages/concurrency.md @@ -0,0 +1,852 @@ +# Concurrency + +并发包包含一些支持并发编程的功能。例如:goroutine, channel 等。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/concurrency/channel.go](https://github.com/duke-git/lancet/blob/main/concurrency/channel.go) +- [https://github.com/duke-git/lancet/blob/main/concurrency/keyed_locker.go](https://github.com/duke-git/lancet/blob/main/concurrency/keyed_locker.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/concurrency" +) +``` + + + +## 目录 + +### Channel + +- [NewChannel](#NewChannel) +- [Bridge](#Bridge) +- [FanIn](#FanIn) +- [Generate](#Generate) +- [Or](#Or) +- [OrDone](#OrDone) +- [Repeat](#Repeat) +- [RepeatFn](#RepeatFn) +- [Take](#Take) +- [Tee](#Tee) + +### KeyedLocker + +- [NewKeyedLocker](#NewKeyedLocker) +- [KeyedLocker_Do](#Do) +- [NewRWKeyedLocker](#NewRWKeyedLocker) +- [RLock](#RLock) +- [Lock](#Lock) +- [NewTryKeyedLocker](#NewTryKeyedLocker) +- [TryLock](#TryLock) +- [Unlock](#Unlock) + + + +## 文档 + +### Channel + +### NewChannel + +返回一个Channel指针实例
+ +函数签名: + +```go +type Channel[T any] struct +func NewChannel[T any]() *Channel[T] +``` + +示例:[运行](https://go.dev/play/p/7aB4KyMMp9A) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + c := concurrency.NewChannel[int]() +} +``` + +### Bridge + +将多个channel链接到一个channel,直到取消上下文。
+ +函数签名: + +```go +func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-chan T +``` + +示例:[运行](https://go.dev/play/p/qmWSy1NVF-Y) + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c := concurrency.NewChannel[int]() + genVals := func() <-chan <-chan int { + out := make(chan (<-chan int)) + go func() { + defer close(out) + for i := 1; i <= 5; i++ { + stream := make(chan int, 1) + stream <- i + close(stream) + out <- stream + } + }() + return out + } + + for v := range c.Bridge(ctx, genVals()) { + fmt.Println(v) + } + + // Output: + // 1 + // 2 + // 3 + // 4 + // 5 +} +``` + +### FanIn + +将多个channel合并为一个channel,直到取消上下文。
+ +函数签名: + +```go +func (c *Channel[T]) FanIn(ctx context.Context, channels ...<-chan T) <-chan T +``` + +示例:[运行](https://go.dev/play/p/2VYFMexEvTm) + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c := concurrency.NewChannel[int]() + channels := make([]<-chan int, 2) + + for i := 0; i < 2; i++ { + channels[i] = c.Take(ctx, c.Repeat(ctx, i), 2) + } + + chs := c.FanIn(ctx, channels...) + + for v := range chs { + fmt.Println(v) //1 1 0 0 or 0 0 1 1 + } +} +``` + +### Generate + +根据传入的值,生成channel.
+ +函数签名: + +```go +func (c *Channel[T]) Generate(ctx context.Context, values ...T) <-chan T +``` + +示例:[运行](https://go.dev/play/p/7aB4KyMMp9A) + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c := concurrency.NewChannel[int]() + intStream := c.Generate(ctx, 1, 2, 3) + + fmt.Println(<-intStream) + fmt.Println(<-intStream) + fmt.Println(<-intStream) + + // Output: + // 1 + // 2 + // 3 +} +``` + +### Repeat + +返回一个channel,将参数`values`重复放入channel,直到取消上下文。
+ +函数签名: + +```go +func (c *Channel[T]) Repeat(ctx context.Context, values ...T) <-chan T +``` + +示例:[运行](https://go.dev/play/p/k5N_ALVmYjE) + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c := concurrency.NewChannel[int]() + intStream := c.Take(ctx, c.Repeat(ctx, 1, 2), 4) + + for v := range intStream { + fmt.Println(v) + } + + // Output: + // 1 + // 2 + // 1 + // 2 +} +``` + +### RepeatFn + +返回一个channel,重复执行函数fn,并将结果放入返回的channel,直到取消上下文。
+ +函数签名: + +```go +func (c *Channel[T]) RepeatFn(ctx context.Context, fn func() T) <-chan T +``` + +示例:[运行](https://go.dev/play/p/4J1zAWttP85) + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + fn := func() string { + return "hello" + } + + c := concurrency.NewChannel[string]() + intStream := c.Take(ctx, c.RepeatFn(ctx, fn), 3) + + for v := range intStream { + fmt.Println(v) + } + // Output: + // hello + // hello + // hello +} +``` + +### Or + +将一个或多个channel读取到一个channel中,当任何读取channel关闭时将结束读取。
+ +函数签名: + +```go +func (c *Channel[T]) Or(channels ...<-chan T) <-chan T +``` + +示例:[运行](https://go.dev/play/p/Wqz9rwioPww) + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + sig := func(after time.Duration) <-chan any { + c := make(chan any) + go func() { + defer close(c) + time.Sleep(after) + }() + return c + } + + start := time.Now() + + c := concurrency.NewChannel[any]() + <-c.Or( + sig(1*time.Second), + sig(2*time.Second), + sig(3*time.Second), + ) + + fmt.Println("done after %v", time.Since(start)) //1.003s +} +``` + +### OrDone + +将一个channel读入另一个channel,直到取消上下文。
+ +函数签名: + +```go +func (c *Channel[T]) OrDone(ctx context.Context, channel <-chan T) <-chan T +``` + +示例:[运行](https://go.dev/play/p/lm_GoS6aDjo) + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c := concurrency.NewChannel[int]() + intStream := c.Take(ctx, c.Repeat(ctx, 1), 3) + + for v := range c.OrDone(ctx, intStream) { + fmt.Println(v) + } + + // Output: + // 1 + // 1 + // 1 +} +``` + +### Take + +返回一个channel,其值从另一个channel获取,直到取消上下文。
+ +函数签名: + +```go +func (c *Channel[T]) Take(ctx context.Context, valueStream <-chan T, number int) <-chan T +``` + +示例:[运行](https://go.dev/play/p/9Utt-1pDr2J) + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + numbers := make(chan int, 5) + numbers <- 1 + numbers <- 2 + numbers <- 3 + numbers <- 4 + numbers <- 5 + defer close(numbers) + + c := concurrency.NewChannel[int]() + intStream := c.Take(ctx, numbers, 3) + + for v := range intStream { + fmt.Println(v) + } + + // Output: + // 1 + // 2 + // 3 +} +``` + +### Tee + +将一个channel分成两个channel,直到取消上下文。
+ +函数签名: + +```go +func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T) +``` + +示例:[运行](https://go.dev/play/p/3TQPKnCirrP) + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c := concurrency.NewChannel[int]() + intStream := c.Take(ctx, c.Repeat(ctx, 1), 2) + + ch1, ch2 := c.Tee(ctx, intStream) + + for v := range ch1 { + fmt.Println(v) + fmt.Println(<-ch2) + } + // Output: + // 1 + // 1 + // 1 + // 1 +} +``` + +### KeyedLocker + +### NewKeyedLocker + +NewKeyedLocker创建一个新的KeyedLocker,并为锁的过期设置指定的 TTL。KeyedLocker 是一个简单的键值锁实现,允许非阻塞的锁获取。
+ +函数签名: + +```go +func NewKeyedLocker[K comparable](ttl time.Duration) *KeyedLocker[K] +``` + +示例:[运行](https://go.dev/play/p/GzeyC33T5rw) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewKeyedLocker[string](2 * time.Second) + + task := func() { + fmt.Println("Executing task...") + time.Sleep(1 * time.Second) + fmt.Println("Task completed.") + } + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + if err := locker.Do(ctx, "mykey", task); err != nil { + log.Fatalf("Error executing task: %v\n", err) + } else { + fmt.Println("Task successfully executed.") + } + + ctx2, cancel2 := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel2() + + if err := locker.Do(ctx2, "mykey", task); err != nil { + log.Fatalf("Error executing task: %v\n", err) + } else { + fmt.Println("Task successfully executed.") + } + + // Output: + // Executing task... + // Task completed. + // Task successfully executed. + // Executing task... + // Task completed. + // Task successfully executed. +} +``` + +### Do + +为指定的键获取锁并执行提供的函数。
+ +函数签名: + +```go +func (l *KeyedLocker[K]) Do(ctx context.Context, key K, fn func()) error +``` + +示例:[运行](https://go.dev/play/p/GzeyC33T5rw) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewKeyedLocker[string](2 * time.Second) + + task := func() { + fmt.Println("Executing task...") + time.Sleep(1 * time.Second) + fmt.Println("Task completed.") + } + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + if err := locker.Do(ctx, "mykey", task); err != nil { + log.Fatalf("Error executing task: %v\n", err) + } else { + fmt.Println("Task successfully executed.") + } + + ctx2, cancel2 := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel2() + + if err := locker.Do(ctx2, "mykey", task); err != nil { + log.Fatalf("Error executing task: %v\n", err) + } else { + fmt.Println("Task successfully executed.") + } + + // Output: + // Executing task... + // Task completed. + // Task successfully executed. + // Executing task... + // Task completed. + // Task successfully executed. +} +``` + +### NewRWKeyedLocker + +NewRWKeyedLocker创建一个新的RWKeyedLocker,并为锁的过期设置指定的 TTL。RWKeyedLocker 是一个简单的键值读写锁实现,允许非阻塞的锁获取。
+ +函数签名: + +```go +func NewRWKeyedLocker[K comparable](ttl time.Duration) *RWKeyedLocker[K] +``` + +示例:[运行](https://go.dev/play/p/CkaJWWwZm9) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewRWKeyedLocker[string](2 * time.Second) + + // Simulate a key + key := "resource_key" + + fn := func() { + fmt.Println("Starting write operation...") + // Simulate write operation, assuming it takes 2 seconds + time.Sleep(200 * time.Millisecond) + fmt.Println("Write operation completed!") + } + + // Acquire the write lock and execute the operation + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + // Execute the lock operation with a 3-second timeout + err := locker.Lock(ctx, key, fn) + if err != nil { + return + } + + //output: + //Starting write operation... + //Write operation completed! +} +``` + +### RLock + +RLock为指定的键获取读锁并执行提供的函数。
+ +函数签名: + +```go +func (l *RWKeyedLocker[K]) RLock(ctx context.Context, key K, fn func()) error +``` + +示例:[运行](https://go.dev/play/p/ZrCr8sMo77T) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewRWKeyedLocker[string](2 * time.Second) + + // Simulate a key + key := "resource_key" + + fn := func() { + fmt.Println("Starting write operation...") + // Simulate write operation, assuming it takes 2 seconds + time.Sleep(200 * time.Millisecond) + fmt.Println("Write operation completed!") + } + + // Acquire the write lock and execute the operation + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + // Execute the lock operation with a 3-second timeout + err := locker.RLock(ctx, key, fn) + if err != nil { + return + } + + //output: + //Starting write operation... + //Write operation completed! +} +``` + +### Lock + +Lock为指定的键获取锁并执行提供的函数。
+ +函数签名: + +```go +func (l *RWKeyedLocker[K]) Lock(ctx context.Context, key K, fn func()) error +``` + +示例:[运行](https://go.dev/play/p/WgAcXbOPKGk) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := NewRWKeyedLocker[string](2 * time.Second) + + // Simulate a key + key := "resource_key" + + fn := func() { + fmt.Println("Starting write operation...") + // Simulate write operation, assuming it takes 2 seconds + time.Sleep(200 * time.Millisecond) + fmt.Println("Write operation completed!") + } + + // Acquire the write lock and execute the operation + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + // Execute the lock operation with a 3-second timeout + err := locker.Lock(ctx, key, fn) + if err != nil { + return + } + + //output: + //Starting write operation... + //Write operation completed! +} +``` + +### NewTryKeyedLocker + +创建一个TryKeyedLocker实例,TryKeyedLocker是KeyedLocker的非阻塞版本。
+ +函数签名: + +```go +func NewTryKeyedLocker[K comparable]() *TryKeyedLocker[K] +``` + +示例:[运行](https://go.dev/play/p/VG9qLvyetE2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewTryKeyedLocker[string]() + + key := "resource_key" + + if locker.TryLock(key) { + fmt.Println("Lock acquired") + time.Sleep(1 * time.Second) + // Unlock after work is done + locker.Unlock(key) + fmt.Println("Lock released") + } else { + fmt.Println("Lock failed") + } + + //output: + //Lock acquired + //Lock released +} +``` + +### TryLock + +TryLock尝试获取指定键的锁。如果锁成功获取,则返回true,否则返回false。
+ +函数签名: + +```go +func (l *TryKeyedLocker[K]) TryLock(key K) bool +``` + +示例:[运行](https://go.dev/play/p/VG9qLvyetE2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewTryKeyedLocker[string]() + + key := "resource_key" + + if locker.TryLock(key) { + fmt.Println("Lock acquired") + time.Sleep(1 * time.Second) + // Unlock after work is done + locker.Unlock(key) + fmt.Println("Lock released") + } else { + fmt.Println("Lock failed") + } + + //output: + //Lock acquired + //Lock released +} +``` + +### Unlock + +释放指定键的锁。
+ +函数签名: + +```go +func (l *TryKeyedLocker[K]) Unlock(key K) +``` + +示例:[运行](https://go.dev/play/p/VG9qLvyetE2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewTryKeyedLocker[string]() + + key := "resource_key" + + if locker.TryLock(key) { + fmt.Println("Lock acquired") + time.Sleep(1 * time.Second) + // Unlock after work is done + locker.Unlock(key) + fmt.Println("Lock released") + } else { + fmt.Println("Lock failed") + } + + //output: + //Lock acquired + //Lock released +} +``` diff --git a/docs/api/packages/condition.md b/docs/api/packages/condition.md new file mode 100644 index 00000000..9dfe5b6e --- /dev/null +++ b/docs/api/packages/condition.md @@ -0,0 +1,335 @@ +# Condition +condition包含一些用于条件判断的函数。这个包的实现参考了carlmjohnson的truthy包的实现,更多有用的信息可以在[truthy](https://github.com/carlmjohnson/truthy)中找到,感谢carlmjohnson。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/condition/condition.go](https://github.com/duke-git/lancet/blob/main/condition/condition.go) + + + +## 用法: +```go +import ( + "github.com/duke-git/lancet/v2/condition" +) +``` + + + +## 目录 + +- [Bool](#Bool) +- [And](#And) +- [Or](#Or) +- [Xor](#Generate) +- [Nor](#Nor) +- [Xnor](#Xnor) +- [Nand](#Nand) +- [Ternary](#Ternary) +- [TernaryOperatordeprecated](#TernaryOperator) + + + +## 文档 + +### Bool +返回传入参数的bool值.
+如果出入类型参数含有Bool方法, 会调用该方法并返回
+如果传入类型参数有IsZero方法, 返回IsZero方法返回值的取反
+slices和map的length大于0时,返回true,否则返回false
+其他类型会判断是否是零值
逻辑且操作,当切仅当a和b都为true时返回true
+ +函数签名: + +```go +func And[T, U any](a T, b U) bool +``` +示例:[运行](https://go.dev/play/p/W1SSUmt6pvr) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + fmt.Println(condition.And(0, 1)) // false + fmt.Println(condition.And(0, "")) // false + fmt.Println(condition.And(0, "0")) // false + fmt.Println(condition.And(1, "0")) // true +} +``` + +### Or +逻辑或操作,当切仅当a和b都为false时返回false
+ +函数签名: + +```go +func Or[T, U any](a T, b U) bool +``` +示例:[运行](https://go.dev/play/p/UlQTxHaeEkq) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + fmt.Println(condition.Or(0, "")) // false + fmt.Println(condition.Or(0, 1)) // true + fmt.Println(condition.Or(0, "0")) // true + fmt.Println(condition.Or(1, "0")) // true +} +``` + +### Xor +逻辑异或操作,a和b相同返回false,a和b不相同返回true
+ +函数签名: + +```go +func Xor[T, U any](a T, b U) bool +``` +示例:[运行](https://go.dev/play/p/gObZrW7ZbG8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + fmt.Println(condition.Xor(0, 0)) // false + fmt.Println(condition.Xor(0, 1)) // true + fmt.Println(condition.Xor(1, 0)) // true + fmt.Println(condition.Xor(1, 1)) // false +} +``` + +### Nor +异或的取反操作
+ +函数签名: + +```go +func Nor[T, U any](a T, b U) bool +``` +示例:[运行](https://go.dev/play/p/g2j08F_zZky) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + fmt.Println(condition.Nor(0, 0)) // true + fmt.Println(condition.Nor(0, 1)) // false + fmt.Println(condition.Nor(1, 0)) // false + fmt.Println(condition.Nor(1, 1)) // false +} +``` + +### Xnor +如果a和b都是真的或a和b均是假的,则返回true。
+ +函数签名: + +```go +func Xnor[T, U any](a T, b U) bool +``` +示例:[运行](https://go.dev/play/p/OuDB9g51643) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + fmt.Println(condition.Xnor(0, 0)) // true + fmt.Println(condition.Xnor(0, 1)) // false + fmt.Println(condition.Xnor(1, 0)) // false + fmt.Println(condition.Xnor(1, 1)) // true +} +``` + +### Nand +如果a和b都为真,返回false,否则返回true
+ +函数签名: + +```go +func Nand[T, U any](a T, b U) bool +``` +示例:[运行](https://go.dev/play/p/vSRMLxLIbq8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + fmt.Println(condition.Nand(0, 0)) // true + fmt.Println(condition.Nand(0, 1)) // true + fmt.Println(condition.Nand(1, 0)) // true + fmt.Println(condition.Nand(1, 1)) // false +} +``` + +### Ternary +三元运算符。
+ +函数签名: + +```go +func Ternary[T, U any](isTrue T, ifValue U, elseValue U) U +``` +示例:[运行](https://go.dev/play/p/ElllPZY0guT) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + conditionTrue := 2 > 1 + result1 := condition.Ternary(conditionTrue, 0, 1) + + conditionFalse := 2 > 3 + result2 := condition.Ternary(conditionFalse, 0, 1) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // 1 +} +``` + +### TernaryOperator +三元运算符
+ +> ⚠️ 本函数已弃用,使用`Ternary`代替。 + +函数签名: + +```go +func TernaryOperator[T, U any](isTrue T, ifValue U, elseValue U) U +``` +示例:[运行](https://go.dev/play/p/ElllPZY0guT) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + conditionTrue := 2 > 1 + result1 := condition.TernaryOperator(conditionTrue, 0, 1) + + conditionFalse := 2 > 3 + result2 := condition.TernaryOperator(conditionFalse, 0, 1) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // 1 +} +``` + + + + + + diff --git a/docs/api/packages/convertor.md b/docs/api/packages/convertor.md new file mode 100644 index 00000000..c3896941 --- /dev/null +++ b/docs/api/packages/convertor.md @@ -0,0 +1,1182 @@ +# Convertor + +convertor 转换器包支持一些常见的数据类型转换 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/convertor" +) +``` + + + +## 目录 + +- [ColorHexToRGB](#ColorHexToRGB) +- [ColorRGBToHex](#ColorRGBToHex) +- [ToBool](#ToBool) +- [ToBytes](#ToBytes) +- [ToChar](#ToChar) +- [ToChannel](#ToChannel) +- [ToFloat](#ToFloat) +- [ToInt](#ToInt) +- [ToJson](#ToJson) +- [ToMap](#ToMap) +- [ToPointer](#ToPointer) +- [ToString](#ToString) +- [StructToMap](#StructToMap) +- [MapToSlice](#MapToSlice) +- [EncodeByte](#EncodeByte) +- [DecodeByte](#DecodeByte) +- [DeepClone](#DeepClone) +- [CopyProperties](#CopyProperties) +- [ToInterface](#ToInterface) +- [Utf8ToGbk](#Utf8ToGbk) +- [GbkToUtf8](#GbkToUtf8) +- [ToStdBase64](#ToStdBase64) +- [ToUrlBase64](#ToUrlBase64) +- [ToRawStdBase64](#ToRawStdBase64) +- [ToRawUrlBase64](#ToRawUrlBase64) +- [ToBigInt](#ToBigInt) + + + +## 文档 + +### ColorHexToRGB + +颜色值十六进制转rgb。
+ +函数签名: + +```go +func ColorHexToRGB(colorHex string) (red, green, blue int) +``` + +示例:[运行](https://go.dev/play/p/o7_ft-JCJBV) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + colorHex := "#003366" + r, g, b := convertor.ColorHexToRGB(colorHex) + + fmt.Println(r, g, b) + + // Output: + // 0 51 102 +} +``` + +### ColorRGBToHex + +颜色值rgb转十六进制。
+ +函数签名: + +```go +func ColorRGBToHex(red, green, blue int) string +``` + +示例:[运行](https://go.dev/play/p/nzKS2Ro87J1) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + r := 0 + g := 51 + b := 102 + colorHex := ColorRGBToHex(r, g, b) + + fmt.Println(colorHex) + + // Output: + // #003366 +} +``` + +### ToBool + +字符串转布尔类型,使用strconv.ParseBool。
+ +函数签名: + +```go +func ToBool(s string) (bool, error) +``` + +示例:[运行](https://go.dev/play/p/ARht2WnGdIN) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + cases := []string{"1", "true", "True", "false", "False", "0", "123", "0.0", "abc"} + + for i := 0; i < len(cases); i++ { + result, _ := convertor.ToBool(cases[i]) + fmt.Println(result) + } + + // Output: + // true + // true + // true + // false + // false + // false + // false + // false + // false +} +``` + +### ToBytes + +Interface转字节切片。
+ +函数签名: + +```go +func ToBytes(data any) ([]byte, error) +``` + +示例:[运行](https://go.dev/play/p/fAMXYFDvOvr) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + bytesData, err := convertor.ToBytes("abc") + if err != nil { + fmt.Println(err) + } + + fmt.Println(bytesData) + + // Output: + // [97 98 99] +} +``` + +### ToChar + +字符串转字符切片。
+ +函数签名: + +```go +func ToChar(s string) []string +``` + +示例:[运行](https://go.dev/play/p/JJ1SvbFkVdM) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + result1 := convertor.ToChar("") + result2 := convertor.ToChar("abc") + result3 := convertor.ToChar("1 2#3") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // [] + // [a b c] + // [1 2 # 3] +} +``` + +### ToChannel + +将切片转为只读channel。
+ +函数签名: + +```go +func ToChannel[T any](array []T) <-chan T +``` + +示例:[运行](https://go.dev/play/p/hOx_oYZbAnL) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + ch := convertor.ToChannel([]int{1, 2, 3}) + result1 := <-ch + result2 := <-ch + result3 := <-ch + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 1 + // 2 + // 3 +} +``` + +### ToFloat + +将interface转成float64类型,如果参数无法转换,会返回0和error。
+ +函数签名: + +```go +func ToFloat(value any) (float64, error) +``` + +示例:[运行](https://go.dev/play/p/4YTmPCibqHJ) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + result1, _ := convertor.ToFloat("") + result2, err := convertor.ToFloat("abc") + result3, _ := convertor.ToFloat("-1") + result4, _ := convertor.ToFloat("-.11") + result5, _ := convertor.ToFloat("1.23e3") + result6, _ := convertor.ToFloat(true) + + fmt.Println(result1) + fmt.Println(result2, err) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // 0 + // 0 strconv.ParseFloat: parsing "": invalid syntax + // -1 + // -0.11 + // 1230 + // 0 +} +``` + +### ToInt + +将interface转成int64类型,如果参数无法转换,会返回0和error。
+ +函数签名: + +```go +func ToInt(value any) (int64, error) +``` + +示例:[运行](https://go.dev/play/p/9_h9vIt-QZ_b) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + result1, _ := convertor.ToInt("123") + result2, _ := convertor.ToInt("-123") + result3, _ := convertor.ToInt(float64(12.3)) + result4, err := convertor.ToInt("abc") + result5, _ := convertor.ToInt(true) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4, err) + fmt.Println(result5) + + // Output: + // 123 + // -123 + // 12 + // 0 strconv.ParseInt: parsing "": invalid syntax + // 0 +} +``` + +### ToJson + +将interface转成json字符串,如果参数无法转换,会返回""和error。
+ +函数签名: + +```go +func ToJson(value any) (string, error) +``` + +示例:[运行](https://go.dev/play/p/2rLIkMmXWvR) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + aMap := map[string]int{"a": 1, "b": 2, "c": 3} + result, err := convertor.ToJson(aMap) + + if err != nil { + fmt.Printf("%v", err) + } + + fmt.Println(result) + + // Output: + // {"a":1,"b":2,"c":3} +} +``` + +### ToMap + +将切片转为map。
+ +函数签名: + +```go +func ToMap[T any, K comparable, V any](array []T, iteratee func(T) (K, V)) map[K]V +``` + +示例:[运行](https://go.dev/play/p/tVFy7E-t24l) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + type Message struct { + name string + code int + } + messages := []Message{ + {name: "Hello", code: 100}, + {name: "Hi", code: 101}, + } + + result := convertor.ToMap(messages, func(msg Message) (int, string) { + return msg.code, msg.name + }) + + fmt.Println(result) + + // Output: + // map[100:Hello 101:Hi] +} +``` + +### ToPointer + +返回传入值的指针。
+ +函数签名: + +```go +func ToPointer[T any](value T) *T +``` + +示例:[运行](https://go.dev/play/p/ASf_etHNlw1) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + result := convertor.ToPointer(123) + fmt.Println(*result) + + // Output: + // 123 +} +``` + +### ToString + +将值转换为字符串,对于数字、字符串、[]byte,将转换为字符串。 对于其他类型(切片、映射、数组、结构体)将调用 json.Marshal
+ +函数签名: + +```go +func ToString(value any) string +``` + +示例:[运行](https://go.dev/play/p/nF1zOOslpQq) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + result1 := convertor.ToString("") + result2 := convertor.ToString(nil) + result3 := convertor.ToString(0) + result4 := convertor.ToString(1.23) + result5 := convertor.ToString(true) + result6 := convertor.ToString(false) + result7 := convertor.ToString([]int{1, 2, 3}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + + // Output: + // + // + // 0 + // 1.23 + // true + // false + // [1,2,3] +} +``` + +### StructToMap + +将struct转成map,只会转换struct中可导出的字段。struct中导出字段需要设置json tag标记。
+ +函数签名: + +```go +func StructToMap(value any) (map[string]any, error) +``` + +示例:[运行](https://go.dev/play/p/KYGYJqNUBOI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + type People struct { + Name string `json:"name"` + age int + } + p := People{ + "test", + 100, + } + pm, _ := convertor.StructToMap(p) + + fmt.Println(pm) + + // Output: + // map[name:test] +} +``` + +### MapToSlice + +map中key和value执行函数iteratee后,转为切片。
+ +函数签名: + +```go +func MapToSlice[T any, K comparable, V any](aMap map[K]V, iteratee func(K, V) T) []T +``` + +示例:[运行](https://go.dev/play/p/dmX4Ix5V6Wl) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + aMap := map[string]int{"a": 1, "b": 2, "c": 3} + result := MapToSlice(aMap, func(key string, value int) string { + return key + ":" + strconv.Itoa(value) + }) + + fmt.Println(result) //[]string{"a:1", "b:2", "c:3"} +} +``` + +### EncodeByte + +将data编码成字节切片。
+ +函数签名: + +```go +func EncodeByte(data any) ([]byte, error) +``` + +示例:[运行](https://go.dev/play/p/DVmM1G5JfuP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + byteData, _ := convertor.EncodeByte("abc") + fmt.Println(byteData) + + // Output: + // [6 12 0 3 97 98 99] +} +``` + +### DecodeByte + +解码字节切片到目标对象,目标对象需要传入一个指针实例。
+ +函数签名: + +```go +func DecodeByte(data []byte, target any) error +``` + +示例:[运行](https://go.dev/play/p/zI6xsmuQRbn) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + var result string + byteData := []byte{6, 12, 0, 3, 97, 98, 99} + + err := convertor.DecodeByte(byteData, &result) + if err != nil { + return + } + + fmt.Println(result) + + // Output: + // abc +} +``` + +### DeepClone + +创建一个传入值的深拷贝, 无法克隆结构体的非导出字段。
+ +函数签名: + +```go +func DeepClone[T any](src T) T +``` + +示例:[运行](https://go.dev/play/p/j4DP5dquxnk) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + type Struct struct { + Str string + Int int + Float float64 + Bool bool + Nil interface{} + unexported string + } + + cases := []interface{}{ + true, + 1, + 0.1, + map[string]int{ + "a": 1, + "b": 2, + }, + &Struct{ + Str: "test", + Int: 1, + Float: 0.1, + Bool: true, + Nil: nil, + // unexported: "can't be cloned", + }, + } + + for _, item := range cases { + cloned := convertor.DeepClone(item) + + isPointerEqual := &cloned == &item + fmt.Println(cloned, isPointerEqual) + } + + // Output: + // true false + // 1 false + // 0.1 false + // map[a:1 b:2] false + // &{test 1 0.1 true拷贝不同结构体之间的同名字段。使用json.Marshal序列化,需要设置dst和src struct字段的json tag。
+ +函数签名: + +```go +func CopyProperties[T, U any](dst T, src U) (err error) +``` + +示例:[运行](https://go.dev/play/p/oZujoB5Sgg5) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + type Disk struct { + Name string `json:"name"` + Total string `json:"total"` + Used string `json:"used"` + Percent float64 `json:"percent"` + } + + type DiskVO struct { + Name string `json:"name"` + Total string `json:"total"` + Used string `json:"used"` + Percent float64 `json:"percent"` + } + + type Indicator struct { + Id string `json:"id"` + Ip string `json:"ip"` + UpTime string `json:"upTime"` + LoadAvg string `json:"loadAvg"` + Cpu int `json:"cpu"` + Disk []Disk `json:"disk"` + Stop chan bool `json:"-"` + } + + type IndicatorVO struct { + Id string `json:"id"` + Ip string `json:"ip"` + UpTime string `json:"upTime"` + LoadAvg string `json:"loadAvg"` + Cpu int64 `json:"cpu"` + Disk []DiskVO `json:"disk"` + } + + indicator := &Indicator{Id: "001", Ip: "127.0.0.1", Cpu: 1, Disk: []Disk{ + {Name: "disk-001", Total: "100", Used: "1", Percent: 10}, + {Name: "disk-002", Total: "200", Used: "1", Percent: 20}, + {Name: "disk-003", Total: "300", Used: "1", Percent: 30}, + }} + + indicatorVO := IndicatorVO{} + + err := convertor.CopyProperties(&indicatorVO, indicator) + + if err != nil { + return + } + + fmt.Println(indicatorVO.Id) + fmt.Println(indicatorVO.Ip) + fmt.Println(len(indicatorVO.Disk)) + + // Output: + // 001 + // 127.0.0.1 + // 3 +} +``` + +### ToInterface + +将反射值转换成对应的interface类型。
+ +函数签名: + +```go +func ToInterface(v reflect.Value) (value interface{}, ok bool) +``` + +示例:[运行](https://go.dev/play/p/syqw0-WG7Xd) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + val := reflect.ValueOf("abc") + iVal, ok := convertor.ToInterface(val) + + fmt.Printf("%T\n", iVal) + fmt.Printf("%v\n", iVal) + fmt.Println(ok) + + // Output: + // string + // abc + // true +} +``` + +### Utf8ToGbk + +utf8编码转GBK编码。
+ +函数签名: + +```go +func Utf8ToGbk(bs []byte) ([]byte, error) +``` + +示例:[运行](https://go.dev/play/p/9FlIaFLArIL) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + utf8Data := []byte("hello") + gbkData, _ := convertor.Utf8ToGbk(utf8Data) + + fmt.Println(utf8.Valid(utf8Data)) + fmt.Println(validator.IsGBK(gbkData)) + + // Output: + // true + // true +} +``` + +### GbkToUtf8 + +GBK编码转utf8编码。
+ +函数签名: + +```go +func GbkToUtf8(bs []byte) ([]byte, error) +``` + +示例:[运行](https://go.dev/play/p/OphmHCN_9u8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + gbkData, _ := convertor.Utf8ToGbk([]byte("hello")) + utf8Data, _ := convertor.GbkToUtf8(gbkData) + + fmt.Println(utf8.Valid(utf8Data)) + fmt.Println(string(utf8Data)) + + // Output: + // true + // hello +} +``` + +### ToStdBase64 + +将值转换为StdBase64编码的字符串。error类型的数据也会把error的原因进行编码,复杂的结构会转为JSON格式的字符串
+ +函数签名: + +```go +func ToStdBase64(value any) string +``` + +示例:[运行](https://go.dev/play/p/_fLJqJD3NMo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + afterEncode := convertor.ToStdBase64(nil) + fmt.Println(afterEncode) + + afterEncode = convertor.ToStdBase64("") + fmt.Println(afterEncode) + + stringVal := "hello" + afterEncode = convertor.ToStdBase64(stringVal) + fmt.Println(afterEncode) + + byteSliceVal := []byte("hello") + afterEncode = convertor.ToStdBase64(byteSliceVal) + fmt.Println(afterEncode) + + intVal := 123 + afterEncode = convertor.ToStdBase64(intVal) + fmt.Println(afterEncode) + + mapVal := map[string]any{"a": "hi", "b": 2, "c": struct { + A string + B int + }{"hello", 3}} + afterEncode = convertor.ToStdBase64(mapVal) + fmt.Println(afterEncode) + + floatVal := 123.456 + afterEncode = convertor.ToStdBase64(floatVal) + fmt.Println(afterEncode) + + boolVal := true + afterEncode = convertor.ToStdBase64(boolVal) + fmt.Println(afterEncode) + + errVal := errors.New("err") + afterEncode = convertor.ToStdBase64(errVal) + fmt.Println(afterEncode) + + // Output: + // + // + // aGVsbG8= + // aGVsbG8= + // MTIz + // eyJhIjoiaGkiLCJiIjoyLCJjIjp7IkEiOiJoZWxsbyIsIkIiOjN9fQ== + // MTIzLjQ1Ng== + // dHJ1ZQ== + // ZXJy +} + +``` + +### ToUrlBase64 + +值转换为 ToUrlBase64 编码的字符串。error 类型的数据也会把 error 的原因进行编码,复杂的结构会转为 JSON 格式的字符串
+ +函数签名: + +```go +func ToUrlBase64(value any) string +``` + +示例:[运行](https://go.dev/play/p/C_d0GlvEeUR) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + afterEncode := convertor.ToUrlBase64(nil) + fmt.Println(afterEncode) + + + stringVal := "hello" + afterEncode = convertor.ToUrlBase64(stringVal) + fmt.Println(afterEncode) + + byteSliceVal := []byte("hello") + afterEncode = convertor.ToUrlBase64(byteSliceVal) + fmt.Println(afterEncode) + + intVal := 123 + afterEncode = convertor.ToUrlBase64(intVal) + fmt.Println(afterEncode) + + mapVal := map[string]any{"a": "hi", "b": 2, "c": struct { + A string + B int + }{"hello", 3}} + afterEncode = convertor.ToUrlBase64(mapVal) + fmt.Println(afterEncode) + + floatVal := 123.456 + afterEncode = convertor.ToUrlBase64(floatVal) + fmt.Println(afterEncode) + + boolVal := true + afterEncode = convertor.ToUrlBase64(boolVal) + fmt.Println(afterEncode) + + errVal := errors.New("err") + afterEncode = convertor.ToUrlBase64(errVal) + fmt.Println(afterEncode) + + // Output: + // + // aGVsbG8= + // aGVsbG8= + // MTIz + // eyJhIjoiaGkiLCJiIjoyLCJjIjp7IkEiOiJoZWxsbyIsIkIiOjN9fQ== + // MTIzLjQ1Ng== + // dHJ1ZQ== + // ZXJy +} + +``` + +### ToRawStdBase64 + +值转换为 ToRawStdBase64 编码的字符串。error 类型的数据也会把 error 的原因进行编码,复杂的结构会转为 JSON 格式的字符串
+ +函数签名: + +```go +func ToRawStdBase64(value any) string +``` + +示例:[运行](https://go.dev/play/p/wSAr3sfkDcv) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + + stringVal := "hello" + afterEncode = convertor.ToRawStdBase64(stringVal) + fmt.Println(afterEncode) + + byteSliceVal := []byte("hello") + afterEncode = convertor.ToRawStdBase64(byteSliceVal) + fmt.Println(afterEncode) + + intVal := 123 + afterEncode = convertor.ToRawStdBase64(intVal) + fmt.Println(afterEncode) + + mapVal := map[string]any{"a": "hi", "b": 2, "c": struct { + A string + B int + }{"hello", 3}} + afterEncode = convertor.ToRawStdBase64(mapVal) + fmt.Println(afterEncode) + + floatVal := 123.456 + afterEncode := convertor.ToRawStdBase64(floatVal) + fmt.Println(afterEncode) + + boolVal := true + afterEncode = convertor.ToRawStdBase64(boolVal) + fmt.Println(afterEncode) + + errVal := errors.New("err") + afterEncode = convertor.ToRawStdBase64(errVal) + fmt.Println(afterEncode) + + // Output: + // aGVsbG8 + // aGVsbG8 + // MTIz + // eyJhIjoiaGkiLCJiIjoyLCJjIjp7IkEiOiJoZWxsbyIsIkIiOjN9fQ + // MTIzLjQ1Ng + // dHJ1ZQ + // ZXJy +} +``` + +### ToRawUrlBase64 + +值转换为 ToRawUrlBase64 编码的字符串。error 类型的数据也会把 error 的原因进行编码,复杂的结构会转为 JSON 格式的字符串
+ +函数签名:[运行](https://go.dev/play/p/HwdDPFcza1O) + +```go +func ToRawUrlBase64(value any) string +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + + stringVal := "hello" + afterEncode := convertor.ToRawUrlBase64(stringVal) + fmt.Println(afterEncode) + + byteSliceVal := []byte("hello") + afterEncode = convertor.ToRawUrlBase64(byteSliceVal) + fmt.Println(afterEncode) + + intVal := 123 + afterEncode = convertor.ToRawUrlBase64(intVal) + fmt.Println(afterEncode) + + mapVal := map[string]any{"a": "hi", "b": 2, "c": struct { + A string + B int + }{"hello", 3}} + afterEncode = convertor.ToRawUrlBase64(mapVal) + fmt.Println(afterEncode) + + floatVal := 123.456 + afterEncode = convertor.ToRawUrlBase64(floatVal) + fmt.Println(afterEncode) + + boolVal := true + afterEncode = convertor.ToRawUrlBase64(boolVal) + fmt.Println(afterEncode) + + errVal := errors.New("err") + afterEncode = convertor.ToRawUrlBase64(errVal) + fmt.Println(afterEncode) + + // Output: + // aGVsbG8 + // aGVsbG8 + // MTIz + // eyJhIjoiaGkiLCJiIjoyLCJjIjp7IkEiOiJoZWxsbyIsIkIiOjN9fQ + // MTIzLjQ1Ng + // dHJ1ZQ + // ZXJy +} +``` + +### ToBigInt + +将整数值转换为bigInt。
+ +函数签名:[运行](https://go.dev/play/p/X3itkCxwB_x) + +```go +func ToBigInt[T any](v T) (*big.Int, error) +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + n := 9876543210 + bigInt, _ := convertor.ToBigInt(n) + + fmt.Println(bigInt) + // Output: + // 9876543210 +} +``` \ No newline at end of file diff --git a/docs/api/packages/cryptor.md b/docs/api/packages/cryptor.md new file mode 100644 index 00000000..2264c2ca --- /dev/null +++ b/docs/api/packages/cryptor.md @@ -0,0 +1,1831 @@ +# Cryptor + +cryptor 包包含数据加密和解密功能。支持 base64, md5, hmac, hash, aes, des, rsa。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/cryptor/basic.go](https://github.com/duke-git/lancet/blob/main/cryptor/basic.go) +- [https://github.com/duke-git/lancet/blob/main/cryptor/crypto.go](https://github.com/duke-git/lancet/blob/main/cryptor/crypto.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/cryptor" +) +``` + + + +## 目录 + +- [AesEcbEncrypt](#AesEcbEncrypt) +- [AesEcbDecrypt](#AesEcbDecrypt) +- [AesCbcEncrypt](#AesCbcEncrypt) +- [AesCbcDecrypt](#AesCbcDecrypt) +- [AesCtrCryptdeprecated](#AesCtrCrypt) +- [AesCtrEncrypt](#AesCtrEncrypt) +- [AesCtrDecrypt](#AesCtrDecrypt) +- [AesCfbEncrypt](#AesCfbEncrypt) +- [AesCfbDecrypt](#AesCfbDecrypt) +- [AesOfbEncrypt](#AesOfbEncrypt) +- [AesOfbDecrypt](#AesOfbDecrypt) +- [AesGcmEncrypt](#AesGcmEncrypt) +- [AesGcmDecrypt](#AesGcmDecrypt) +- [Base64StdEncode](#Base64StdEncode) +- [Base64StdDecode](#Base64StdDecode) +- [DesEcbEncrypt](#DesEcbEncrypt) +- [DesEcbDecrypt](#DesEcbDecrypt) +- [DesCbcEncrypt](#DesCbcEncrypt) +- [DesCbcDecrypt](#DesCbcDecrypt) +- [DesCtrCryptdeprecated](#DesCtrCrypt) +- [DesCfbEncrypt](#DesCfbEncrypt) +- [DesCfbDecrypt](#DesCfbDecrypt) +- [DesOfbEncrypt](#DesOfbEncrypt) +- [DesOfbDecrypt](#DesOfbDecrypt) +- [HmacMd5](#HmacMd5) +- [HmacMd5WithBase64](#HmacMd5WithBase64) +- [HmacSha1](#HmacSha1) +- [HmacSha1WithBase64](#HmacSha1WithBase64) +- [HmacSha256](#HmacSha256) +- [HmacSha256WithBase64](#HmacSha256WithBase64) +- [HmacSha512](#HmacSha512) +- [HmacSha512WithBase64](#HmacSha512WithBase64) +- [Md5String](#Md5String) +- [Md5StringWithBase64](#Md5StringWithBase64) +- [Md5Byte](#Md5Byte) +- [Md5ByteWithBase64](#Md5ByteWithBase64) +- [Md5File](#Md5File) +- [Sha1](#Sha1) +- [Sha1WithBase64](#Sha1WithBase64) +- [Sha256](#Sha256) +- [Sha256WithBase64](#Sha256WithBase64) +- [Sha512](#Sha512) +- [Sha512WithBase64](#Sha512WithBase64) +- [GenerateRsaKey](#GenerateRsaKey) +- [RsaEncrypt](#RsaEncrypt) +- [RsaDecrypt](#RsaDecrypt) +- [GenerateRsaKeyPair](#GenerateRsaKeyPair) +- [RsaEncryptOAEP](#RsaEncryptOAEP) +- [RsaDecryptOAEP](#RsaDecryptOAEP) +- [RsaSign](#RsaSign) +- [RsaVerifySign](#RsaVerifySign) + + + +## 文档 + +### AesEcbEncrypt + +使用AES ECB算法模式加密数据. 参数`key`的长度是16, 24 or 32。
+ +函数签名: + +```go +func AesEcbEncrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/zI6xsmuQRbn) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesEcbDecrypt + +使用AES ECB算法模式解密数据,参数`key`的长度是16, 24 or 32。
+ +函数签名: + +```go +func AesEcbDecrypt(encrypted, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/zI6xsmuQRbn) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCbcEncrypt + +使用AES CBC算法模式加密数据,参数`key`的长度是16, 24 or 32。
+ +函数签名: + +```go +func AesCbcEncrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/IOq_g8_lKZD) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCbcDecrypt + +使用AES CBC算法模式解密数据,参数`key`的长度是16, 24 or 32。
+ +函数签名: + +```go +func AesCbcDecrypt(encrypted, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/IOq_g8_lKZD) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCtrCrypt + +使用AES CTR算法模式加密/解密数据,参数`key`的长度是16, 24 or 32。
+ +> ⚠️ 本函数已弃用,使用`AesCtrEncrypt`和`AesCtrDecrypt`代替。 + +函数签名: + +```go +func AesCtrCrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/SpaZO0-5Nsp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCtrEncrypt + +使用AES CTR算法模式加密数据,参数`key`的长度是16, 24 or 32。
+ +函数签名: + +```go +func AesCtrEncrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/x6pjPAvThRz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCtrEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCtrDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCtrDecrypt + +使用AES CTR算法模式解密数据,参数`key`的长度是16, 24 or 32。
+ +函数签名: + +```go +func AesCtrDecrypt(encrypted, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/x6pjPAvThRz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCtrEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCtrDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCfbEncrypt + +使用AES CFB算法模式加密数据,参数`key`的长度是16, 24 or 32。
+ +函数签名: + +```go +func AesCfbEncrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/tfkF10B13kH) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCfbDecrypt + +使用AES CFB算法模式解密数据,参数`key`的长度是16, 24 or 32。
+ +函数签名: + +```go +func AesCfbDecrypt(encrypted, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/tfkF10B13kH) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesOfbEncrypt + +使用AES OFB算法模式加密数据,参数`key`的长度是16, 24 or 32。
+ +函数签名: + +```go +func AesOfbEncrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/VtHxtkUj-3F) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesOfbDecrypt + +使用AES OFB算法模式解密数据,参数`key`的长度是16, 24 or 32。
+ +函数签名: + +```go +func AesOfbDecrypt(encrypted, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/VtHxtkUj-3F) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesGcmEncrypt + +使用AES GCM算法模式加密数据。
+ +函数签名: + +```go +func AesGcmEncrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/rUt0-DmsPCs) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesGcmEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesGcmDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesGcmDecrypt + +使用AES GCM算法解密数据。
+ +函数签名: + +```go +func AesGcmDecrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/rUt0-DmsPCs) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesGcmEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesGcmDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### Base64StdEncode + +将字符串base64编码。
+ +函数签名: + +```go +func Base64StdEncode(s string) string +``` + +示例:[运行](https://go.dev/play/p/VOaUyQUreoK) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + base64Str := cryptor.Base64StdEncode("hello") + fmt.Println(base64Str) + + // Output: + // aGVsbG8= +} +``` + +### Base64StdDecode + +解码base64字符串。
+ +函数签名: + +```go +func Base64StdDecode(s string) string +``` + +示例:[运行](https://go.dev/play/p/RWQylnJVgIe) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := cryptor.Base64StdDecode("aGVsbG8=") + fmt.Println(str) + + // Output: + // hello +} +``` + +### DesEcbEncrypt + +使用DES ECB算法模式加密数据,参数`key`的长度是8。
+ +函数签名: + +```go +func DesEcbEncrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/8qivmPeZy4P) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key)) + + decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesEcbDecrypt + +使用DES ECB算法模式解决密数据,参数`key`的长度是8。
+ +函数签名: + +```go +func DesEcbDecrypt(encrypted, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/8qivmPeZy4P) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key)) + + decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCbcEncrypt + +使用DES CBC算法模式加密数据,参数`key`的长度是8。
+ +函数签名: + +```go +func DesCbcEncrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/4cC4QvWfe3_1) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCbcDecrypt + +使用DES CBC算法模式解密数据,参数`key`的长度是8。
+ +函数签名: + +```go +func DesCbcDecrypt(encrypted, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/4cC4QvWfe3_1) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCtrEncrypt + +使用DES CTR算法模式加密数据,参数`key`的长度是8
+ +函数签名: + +```go +func DesCtrEncrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/S6p_WHCgH1d) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCtrEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCtrDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCtrDecrypt + +使用DES CTR算法模式加密数据,参数`key`的长度是8
+ +函数签名: + +```go +func DesCtrDecrypt(encrypted, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/S6p_WHCgH1d) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCtrEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCtrDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCtrCrypt + +使用DES CTR算法模式加密/解密数据,参数`key`的长度是8
+ +> ⚠️ 本函数已弃用,使用`DesCtrEncrypt`和`DesCtrDecrypt`代替。 + +函数签名: + +```go +func DesCtrCrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/9-T6OjKpcdw) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCfbEncrypt + +使用DES CFB算法模式加密数据,参数`key`的长度是8。
+ +函数签名: + +```go +func DesCfbEncrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/y-eNxcFBlxL) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCfbDecrypt + +使用DES CFB算法模式解决密数据,参数`key`的长度是8。
+ +函数签名: + +```go +func DesCfbDecrypt(encrypted, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/y-eNxcFBlxL) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesOfbEncrypt + +使用DES OFB算法模式加密数据,参数`key`的长度是8。
+ +函数签名: + +```go +func DesOfbEncrypt(data, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/74KmNadjN1J) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesOfbDecrypt + +使用DES OFB算法模式解密数据,参数`key`的长度是8。
+ +函数签名: + +```go +func DesOfbDecrypt(encrypted, key []byte) []byte +``` + +示例:[运行](https://go.dev/play/p/74KmNadjN1J) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### HmacMd5 + +获取字符串md5 hmac值。
+ +函数签名: + +```go +func HmacMd5(str, key string) string +``` + +示例:[运行](https://go.dev/play/p/uef0q1fz53I) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacMd5(str, key) + fmt.Println(hms) + + // Output: + // e834306eab892d872525d4918a7a639a +} +``` + +### HmacMd5WithBase64 + +获取字符串md5 hmac base64字符串值。
+ +函数签名: + +```go +func HmacMd5WithBase64(str, key string) string +``` + +示例:[运行](https://go.dev/play/p/UY0ng2AefFC) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacMd5WithBase64(str, key) + fmt.Println(hms) + + // Output: + // 6DQwbquJLYclJdSRinpjmg== +} +``` + +### HmacSha1 + +获取字符串的sha1 hmac值。
+ +函数签名: + +```go +func HmacSha1(str, key string) string +``` + +示例:[运行](https://go.dev/play/p/1UI4oQ4WXKM) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacSha1(str, key) + fmt.Println(hms) + + // Output: + // 5c6a9db0cccb92e36ed0323fd09b7f936de9ace0 +} +``` + +### HmacSha1WithBase64 + +获取字符串的sha1 base64值。
+ +函数签名: + +```go +func HmacSha1WithBase64(str, key string) string +``` + +示例:[运行](https://go.dev/play/p/47JmmGrnF7B) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacSha1WithBase64(str, key) + fmt.Println(hms) + + // Output: + // XGqdsMzLkuNu0DI/0Jt/k23prOA= +} +``` + +### HmacSha256 + +获取字符串sha256 hmac值。
+ +函数签名: + +```go +func HmacSha256(str, key string) string +``` + +示例:[运行](https://go.dev/play/p/HhpwXxFhhC0) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacSha256(str, key) + fmt.Println(hms) + + // Output: + // 315bb93c4e989862ba09cb62e05d73a5f376cb36f0d786edab0c320d059fde75 +} +``` + +### HmacSha256WithBase64 + +获取字符串sha256 hmac base64值。
+ +函数签名: + +```go +func HmacSha256WithBase64(str, key string) string +``` + +示例:[运行](https://go.dev/play/p/EKbkUvPTLwO) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacSha256WithBase64(str, key) + fmt.Println(hms) + + // Output: + // MVu5PE6YmGK6Ccti4F1zpfN2yzbw14btqwwyDQWf3nU= +} +``` + +### HmacSha512 + +获取字符串sha512 hmac值。
+ +函数签名: + +```go +func HmacSha512(str, key string) string +``` + +示例:[运行](https://go.dev/play/p/59Od6m4A0Ud) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacSha512(str, key) + fmt.Println(hms) + + // Output: + // dd8f1290a9dd23d354e2526d9a2e9ce8cffffdd37cb320800d1c6c13d2efc363288376a196c5458daf53f8e1aa6b45a6d856303d5c0a2064bff9785861d48cfc +} +``` + +### HmacSha512WithBase64 + +获取字符串sha512 hmac base64值。
+ +函数签名: + +```go +func HmacSha512WithBase64(str, key string) string +``` + +示例:[运行](https://go.dev/play/p/c6dSe3E2ydU) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacSha512WithBase64(str, key) + fmt.Println(hms) + + // Output: + // 3Y8SkKndI9NU4lJtmi6c6M///dN8syCADRxsE9Lvw2Mog3ahlsVFja9T+OGqa0Wm2FYwPVwKIGS/+XhYYdSM/A== +} +``` + +### Md5String + +获取字符串md5值。
+ +函数签名: + +```go +func Md5String(str string) string +``` + +示例:[运行](https://go.dev/play/p/1bLcVetbTOI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + + md5Str := cryptor.Md5String(str) + fmt.Println(md5Str) + + // Output: + // 5d41402abc4b2a76b9719d911017c592 +} +``` + +### Md5StringWithBase64 + +获取字符串md5 base64值。
+ +函数签名: + +```go +func Md5StringWithBase64(s string) string +``` + +示例:[运行](https://go.dev/play/p/Tcb-Z7LN2ax) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + md5Str := cryptor.Md5StringWithBase64("hello") + fmt.Println(md5Str) + + // Output: + // XUFAKrxLKna5cZ2REBfFkg== +} +``` + +### Md5Byte + +获取byte slice的md5值。
+ +函数签名: + +```go +func Md5Byte(data []byte) string +``` + +示例:[运行](https://go.dev/play/p/suraalH8lyC) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + md5Str := cryptor.Md5Byte([]byte{'a'}) + fmt.Println(md5Str) + + // Output: + // 0cc175b9c0f1b6a831c399e269772661 +} +``` + +### Md5ByteWithBase64 + +获取byte slice的md5 base64值。
+ +函数签名: + +```go +func Md5ByteWithBase64(data []byte) string +``` + +示例:[运行](https://go.dev/play/p/Lx4gH7Vdr5_y) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + md5Str := cryptor.Md5ByteWithBase64([]byte("hello")) + fmt.Println(md5Str) + + // Output: + // XUFAKrxLKna5cZ2REBfFkg== +} +``` + +### Md5File + +获取文件md5值。
+ +函数签名: + +```go +func Md5File(filepath string) (string, error) +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + s := cryptor.Md5File("./main.go")) + fmt.Println(s) +} +``` + +### Sha1 + +获取字符串sha1值。
+ +函数签名: + +```go +func Sha1(str string) string +``` + +示例:[运行](https://go.dev/play/p/_m_uoD1deMT) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + + result := cryptor.Sha1(str) + fmt.Println(result) + + // Output: + // aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d +} +``` + +### Sha1WithBase64 + +获取字符串sha1 base64值。
+ +函数签名: + +```go +func Sha1WithBase64(str string) string +``` + +示例:[运行](https://go.dev/play/p/fSyx-Gl2l2-) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + result := cryptor.Sha1WithBase64("hello") + fmt.Println(result) + + // Output: + // qvTGHdzF6KLavt4PO0gs2a6pQ00= +} +``` + +### Sha256 + +获取字符串sha256值。
+ +函数签名: + +```go +func Sha256(str string) string +``` + +示例:[运行](https://go.dev/play/p/tU9tfBMIAr1) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + + result := cryptor.Sha256(str) + fmt.Println(result) + + // Output: + // 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 +} +``` + +### Sha256WithBase64 + +获取字符串sha256 base64值。
+ +函数签名: + +```go +func Sha256WithBase64(str string) string +``` + +示例:[运行](https://go.dev/play/p/85IXJHIal1k) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + result := cryptor.Sha256WithBase64("hello") + fmt.Println(result) + + // Output: + // LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ= +} +``` + +### Sha512 + +获取字符串sha512值。
+ +函数签名: + +```go +func Sha512(str string) string +``` + +示例:[运行](https://go.dev/play/p/3WsvLYZxsHa) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + + result := cryptor.Sha512(str) + fmt.Println(result) + + // Output: + // 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043 +} +``` + +### Sha512WithBase64 + +获取字符串sha512 base64值。
+ +函数签名: + +```go +func Sha512WithBase64(str string) string +``` + +示例:[运行](https://go.dev/play/p/q_fY2rA-k5I) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + result := cryptor.Sha512WithBase64("hello") + fmt.Println(result) + + // Output: + // m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw== +} +``` + +### GenerateRsaKey + +在当前目录下创建rsa私钥文件和公钥文件。
+ +函数签名: + +```go +func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error +``` + +示例:[运行](https://go.dev/play/p/zutRHrDqs0X) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") + if err != nil { + fmt.Println(err) + } +} +``` + +### RsaEncrypt + +用公钥文件ras加密数据。
+ +函数签名: + +```go +func RsaEncrypt(data []byte, pubKeyFileName string) []byte +``` + +示例:[运行](https://go.dev/play/p/7_zo6mrx-eX) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") + if err != nil { + return + } + + data := []byte("hello") + encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem") + decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem") + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### RsaDecrypt + +用私钥文件rsa解密数据。
+ +函数签名: + +```go +func RsaDecrypt(data []byte, privateKeyFileName string) []byte +``` + +示例:[运行](https://go.dev/play/p/7_zo6mrx-eX) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") + if err != nil { + return + } + + data := []byte("hello") + encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem") + decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem") + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### GenerateRsaKeyPair + +创建rsa公钥私钥和key。
+ +函数签名: + +```go +func GenerateRsaKeyPair(keySize int) (*rsa.PrivateKey, *rsa.PublicKey) +``` + +示例:[运行](https://go.dev/play/p/sSVmkfENKMz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + pri, pub := cryptor.GenerateRsaKeyPair(1024) +} +``` + +### RsaEncryptOAEP + +rsa OAEP加密。
+ +函数签名: + +```go +func RsaEncryptOAEP(data []byte, label []byte, key rsa.PublicKey) ([]byte, error) +``` + +示例:[运行](https://go.dev/play/p/sSVmkfENKMz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + pri, pub := cryptor.GenerateRsaKeyPair(1024) + + data := []byte("hello world") + label := []byte("123456") + + encrypted, err := cryptor.RsaEncryptOAEP(data, label, *pub) + if err != nil { + return + } + + decrypted, err := cryptor.RsaDecryptOAEP([]byte(encrypted), label, *pri) + if err != nil { + return + } + + fmt.Println(string(decrypted)) + + // Output: + // hello world +} +``` + +### RsaDecryptOAEP + +rsa OAEP解密。
+ +函数签名: + +```go +func RsaDecryptOAEP(ciphertext []byte, label []byte, key rsa.PrivateKey) ([]byte, error) +``` + +示例:[运行](https://go.dev/play/p/sSVmkfENKMz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + pri, pub := cryptor.GenerateRsaKeyPair(1024) + + data := []byte("hello world") + label := []byte("123456") + + encrypted, err := cryptor.RsaEncryptOAEP(data, label, *pub) + if err != nil { + return + } + + decrypted, err := cryptor.RsaDecryptOAEP([]byte(encrypted), label, *pri) + if err != nil { + return + } + + fmt.Println(string(decrypted)) + + // Output: + // hello world +} +``` + +### RsaSign + +应用RSA算法签名数据。
+ +函数签名: + +```go +func RsaSign(hash crypto.Hash, data []byte, privateKeyFileName string) ([]byte, error) +``` + +示例:[运行](https://go.dev/play/p/qhsbf8BJ6Mf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := []byte("This is a test data for RSA signing") + hash := crypto.SHA256 + + privateKey := "./rsa_private.pem" + publicKey := "./rsa_public.pem" + + signature, err := cryptor.RsaSign(hash, data, privateKey) + if err != nil { + return + } + + err = cryptor.RsaVerifySign(hash, data, signature, publicKey) + if err != nil { + return + } +} +``` + +### RsaVerifySign + +验证数据的签名是否符合RSA算法。
+ +函数签名: + +```go +func RsaVerifySign(hash crypto.Hash, data, signature []byte, pubKeyFileName string) error +``` + +示例:[运行](https://go.dev/play/p/qhsbf8BJ6Mf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := []byte("This is a test data for RSA signing") + hash := crypto.SHA256 + + privateKey := "./rsa_private.pem" + publicKey := "./rsa_public.pem" + + signature, err := cryptor.RsaSign(hash, data, privateKey) + if err != nil { + return + } + + err = cryptor.RsaVerifySign(hash, data, signature, publicKey) + if err != nil { + return + } +} +``` diff --git a/docs/api/packages/datastructure/copyonwritelist.md b/docs/api/packages/datastructure/copyonwritelist.md new file mode 100644 index 00000000..db054a4b --- /dev/null +++ b/docs/api/packages/datastructure/copyonwritelist.md @@ -0,0 +1,525 @@ +# CopyOnWriteList + +CopyOnWriteList 是一个线程安全的 List 实现,底层使用 go 切片。写入时,会复制一份新的切片,写入完成后,再将新的切片赋值给原来的切片。读取时,直接读取原来的切片。 + +## 源码 + +- [https://github.com/duke-git/lancet/blob/main/datastructure/list/copyonwritelist.go](https://github.com/duke-git/lancet/blob/main/datastructure/list/copyonwritelist.go) + +## 用法 + +```go +import ( + "github.com/duke-git/lancet/datastructure/list" +) + +``` + + + +## 目录 + +- [NewCopyOnWriteList](#NewCopyOnWriteList) +- [Size](#Size) +- [Get](#Get) +- [Set](#Set) +- [Remove](#Remove) +- [IndexOf](#IndexOf) +- [LastIndexOf](#LastIndexOf) +- [IndexOfFunc](#IndexOfFunc) +- [LastIndexOfFunc](#LastIndexOfFunc) +- [IsEmpty](#IsEmpty) +- [Contain](#Contain) +- [ValueOf](#ValueOf) +- [Add](#Add) +- [AddAll](#AddAll) +- [AddByIndex](#AddByIndex) +- [DeleteAt](#DeleteAt) +- [DeleteIf](#DeleteIf) +- [DeleteBy](#DeleteBy) +- [DeleteRange](#DeleteRange) +- [Equal](#Equal) + +## 文档 + +### NewCopyOnWriteList + +返回一个具有空切片的 CopyOnWriteList。 + +```go +type CopyOnWriteList[T any] struct { + data []T + lock sync.Locker +} + +func NewCopyOnWriteList() *CopyOnWriteList + +``` + +#### 示例 + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l) +} + +``` + +### Size + +返回 CopyOnWriteList 的长度。 + +```go +func (l *CopyOnWriteList[T]) Size() int +``` + +#### 示例 + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.Size()) +} + +``` + +### Get + +返回列表中指定位置的元素 + +```go +func (c *CopyOnWriteList[T]) Get(index int) *T +``` + +#### 示例 + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.Get(2)) +} + +``` + +### Set + +将此列表中指定位置的元素替换为指定元素。 + +```go +func (c *CopyOnWriteList[T]) Set(index int, e T) (oldValue *T, ok bool) +``` + +#### 示例 + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.Set(2, 4)) +} + +``` + +### Remove + +### IndexOf + +返回列表中值的索引,如果没有找到返回-1。 + +```go +func (c *CopyOnWriteList[T]) IndexOf(e T) int +``` + +#### 示例 + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.IndexOf(1)) +} + +``` + +### LastIndexOf + +返回指定元素在此列表中最后出现的索引,如果此列表不包含该元素,则返回-1。 + +```go +func (c *CopyOnWriteList[T]) LastIndexOf(e T) int +``` + +#### 示例 + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3,1}) + fmt.Println(l.LastIndexOf(1)) +} + +``` + +### IndexOfFunc +返回第一个满足判断函数f(v)的元素的索引,如果找不到则返回-1。
+ +函数签名: + +```go +func (l *CopyOnWriteList[T]) IndexOfFunc(f func(T) bool) int +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1, 2, 3}) + + fmt.Println(l.IndexOfFunc(func(a int) bool { return a == 1 })) //0 + fmt.Println(l.IndexOfFunc(func(a int) bool { return a == 0 })) //-1 +} +``` + +### LastIndexOfFunc +返回最后一个满足判断函数f(v)的元素的索引,如果找不到则返回-1。
+ +函数签名: + +```go +func (l *CopyOnWriteList[T]) LastIndexOfFunc(f func(T) bool) int +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1, 2, 3, 1}) + + fmt.Println(l.LastIndexOfFunc(func(a int) bool { return a == 1 })) // 3 + fmt.Println(l.LastIndexOfFunc(func(a int) bool { return a == 0 })) //-1 +} +``` + +### IsEmpty + +如果此列表不包含任何元素,则返回 true。 + +```go +func (c *CopyOnWriteList[T]) IsEmpty() bool +``` + +#### 示例 + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{}) + fmt.Println(l.IsEmpty()) +} +``` + +### Contain + +判断 CopyOnWriteList 是否包含某个元素 + +```go +func (c *CopyOnWriteList[T]) Contain(e T) bool +``` + +#### 示例 + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.Contain(1)) +} +``` + +### ValueOf + +返回列表中索引处的值指针 + +```go +func (c *CopyOnWriteList[T]) ValueOf(index int) []T +``` + +#### 示例 + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.ValueOf(2)) +} + +``` + +### Add + +将指定的元素追加到此列表的末尾。 + +```go +func (c *CopyOnWriteList[T]) Add(e T) bool +``` + +#### 示例 + +```go + +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + l.Add(4) + fmt.Println(l.getList()) +} + +``` + +### AddAll + +将指定集合中的所有元素追加到此列表的末尾 + +```go +func (c *CopyOnWriteList[T]) AddAll(e []T) bool +``` + +#### 示例 + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + l.AddAll([]int{4,5,6}) + fmt.Println(l.getList()) +} + +``` + +### AddByIndex + +将指定元素插入此列表中的指定位置。 + +```go +func (c *CopyOnWriteList[T]) AddByIndex(index int, e T) bool +``` + +#### 示例 + +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.AddByIndex(2, 6) + fmt.Println(l.getList()) +} + +``` + +### DeleteAt + +移除此列表中指定位置的元素。 + +```go +func (c *CopyOnWriteList[T]) DeleteAt(index int) (oldValue *T, ok bool) +``` + +#### 示例 + +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.DeleteAt(2) + fmt.Println(l.getList()) +} +``` + +### DeleteIf + +从此列表中删除第一个出现的指定元素(如果该元素存在)。 + +```go +func (c *CopyOnWriteList[T]) DeleteIf(f func(T) bool) (oldValue *T, ok bool) +``` + +#### 示例 + +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.DeleteIf(func(i int) bool { + return i == 2 + }) + fmt.Println(l.getList()) +} +``` + +### DeleteBy + +从此列表中删除第一个出现的指定元素(如果该元素存在)。 + +```go +func (c *CopyOnWriteList[T]) DeleteBy(e T) (*T bool) +``` + +#### 示例 + +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.DeleteBy(2) + fmt.Println(l.getList()) +} +``` + +### DeleteRange + +从该列表中删除索引介于 fromIndex(包含)和 toIndex(不包含)之间的所有元素。 +(左闭右开)。 + +```go +func (c *CopyOnWriteList[T]) DeleteRange(start int, end int) +``` + +#### 示例 + +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3,4,5,6,7,8,9}) + list.DeleteRange(2, 5) + fmt.Println(l.getList()) +} +``` + +### Equal + +如果指定的对象等于此列表,则返回 true。 + +```go +func (c *CopyOnWriteList[T]) Equal(e []T) bool +``` + +#### 示例 + +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3,4,5,6,7,8,9}) + fmt.Println(l.Equal([]int{1,2,3,4,5,6,7,8,9})) +} +``` diff --git a/docs/api/packages/datastructure/hashmap.md b/docs/api/packages/datastructure/hashmap.md new file mode 100644 index 00000000..3369852f --- /dev/null +++ b/docs/api/packages/datastructure/hashmap.md @@ -0,0 +1,346 @@ +# HashMap + +HashMap 数据结构实现 + + + +## 源码 + +- [https://github.com/duke-git/lancet/blob/main/datastructure/hashmap/hashmap.go](https://github.com/duke-git/lancet/blob/main/datastructure/hashmap/hashmap.go) + + + +## 用法 + +```go +import ( + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) +``` + + + +## 目录 + +- [NewHashMap](#NewHashMap) +- [NewHashMapWithCapacity](#NewHashMapWithCapacity) +- [Get](#Get) +- [Put](#Put) +- [Delete](#Delete) +- [Contains](#Contains) +- [Iterate](#Iterate) +- [Keys](#Keys) +- [Values](#Values) +- [FilterByValue](#FilterByValue) + + + +## API 文档 + +### NewHashMap + +新建默认容量(1 << 10)的HashMap指针实例
+ +函数签名: + +```go +func NewHashMap() *HashMap +``` + +示例: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + fmt.Println(hm) +} +``` + +### NewHashMapWithCapacity + +新建指定容量和长度的HashMap指针实例.
+ +函数签名: + +```go +func NewHashMapWithCapacity(size, capacity uint64) *HashMap +``` + +示例: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMapWithCapacity(uint64(100), uint64(1000)) + fmt.Println(hm) +} +``` + +### Get + +在hashmap中根据key获取值
+ +函数签名: + +```go +func (hm *HashMap) Get(key any) any +``` + +示例: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + val := hm.Get("a") + + fmt.Println(val) //nil +} +``` + +### Put + +将key-value放入hashmap中
+ +函数签名: + +```go +func (hm *HashMap) Put(key any, value any) any +``` + +示例: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + hm.Put("a", 1) + + val := hm.Get("a") + fmt.Println(val) //1 +} +``` + +### Delete + +将指定的key从hashmap中删除
+ +函数签名: + +```go +func (hm *HashMap) Delete(key any) +``` + +示例: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + hm.Put("a", 1) + val := hm.Get("a") + fmt.Println(val) //1 + + hm.Delete("a") + val = hm.Get("a") + fmt.Println(val) //nil +} +``` + +### Contains + +判断hashmap中是否包含指定的key
+ +函数签名: + +```go +func (hm *HashMap) Contains(key any) bool +``` + +示例: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + hm.Put("a", 1) + + fmt.Println(hm.Contains("a")) //true + fmt.Println(hm.Contains("b")) //false +} +``` + + +### Iterate + +迭代hashmap,对每个key和value执行iteratee函数
+ +函数签名: + +```go +func (hm *HashMap) Iterate(iteratee func(key, value any)) +``` + +示例: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + hm.Put("a", 1) + hm.Put("b", 2) + hm.Put("c", 3) + + hm.Iterate(func(key, value any) { + fmt.Println(key) + fmt.Println(value) + }) +} +``` + + + +### Keys + +返回hashmap所有key的切片 (随机顺序)
+ +函数签名: + +```go +func (hm *HashMap) Keys() []any +``` + +示例: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + hm.Put("a", 1) + hm.Put("b", 2) + hm.Put("c", 3) + + keys := hm.Keys() + fmt.Println(keys) //[]interface{"a", "b", "c"} +} +``` + + +### Values + +返回hashmap所有值的切片 (随机顺序)。
+ +函数签名: + +```go +func (hm *HashMap) Values() []any +``` + +示例: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + hm.Put("a", 1) + hm.Put("b", 2) + hm.Put("c", 3) + + values := hm.Values() + fmt.Println(values) //[]interface{2, 1, 3} +} +``` + + +### FilterByValue + +返回一个过滤后的HashMap。 如果任何值与 perdicate 函数不匹配,则返回 nil,否则返回包含选定值的 HashMap。
+ +函数签名: + +```go +func (hm *HashMap) FilterByValue(perdicate func(value any) bool) *HashMap +``` + +示例: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := hashmap.NewHashMap() + + hm.Put("a", 1) + hm.Put("b", 2) + hm.Put("c", 3) + hm.Put("d", 4) + hm.Put("e", 5) + hm.Put("f", 6) + + filteredHM := hm.FilterByValue(func(value any) bool { + return value.(int) == 1 || value.(int) == 3 + }) + + fmt.Println(filteredHM.Size()) //2 +} +``` diff --git a/docs/api/packages/datastructure/heap.md b/docs/api/packages/datastructure/heap.md new file mode 100644 index 00000000..e4c59613 --- /dev/null +++ b/docs/api/packages/datastructure/heap.md @@ -0,0 +1,364 @@ +# Heap +堆,切片实现的二叉堆数据结构。 + + + +## 源码 + +- [https://github.com/duke-git/lancet/blob/main/datastructure/heap/maxheap.go](https://github.com/duke-git/lancet/blob/main/datastructure/heap/maxheap.go) + + + + +## 用法 +```go +import ( + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) +``` + + + +## 目录 + +- [MaxHeap](#MaxHeap) +- [Push](#Push) +- [Pop](#Pop) +- [Peek](#Peek) +- [Data](#Data) +- [Size](#Size) + + + + +## API文档 + +### 1. MaxHeap +MaxHeap是通过slice实现的二叉堆树,根节点的key既大于等于左子树的key值且大于等于右子树的key值。 + +### NewMaxHeap +返回NewMaxHeap指针实例
+ +函数签名: + +```go +type MaxHeap[T any] struct { + data []T + comparator constraints.Comparator +} +func NewMaxHeap[T any](comparator constraints.Comparator) *MaxHeap[T] +``` +示例: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + fmt.Println(maxHeap) +} +``` + + + + +### Push +向堆中插入数据
+ +函数签名: + +```go +func (h *MaxHeap[T]) Push(value T) +``` +示例: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + values := []int{6, 5, 2, 4, 7, 10, 12, 1, 3, 8, 9, 11} + + for _, v := range values { + maxHeap.Push(v) + } + + fmt.Println(maxHeap.Data()) //[]int{12, 9, 11, 4, 8, 10, 7, 1, 3, 5, 6, 2} +} +``` + + + + +### Pop +返回堆中最大值并将其从堆中删除,如果堆为空,返回零值并返回false
+ +函数签名: + +```go +func (h *MaxHeap[T]) Pop() (T, bool) +``` +示例: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + values := []int{6, 5, 2, 4, 7, 10, 12, 1, 3, 8, 9, 11} + + for _, v := range values { + maxHeap.Push(v) + } + val, ok := maxHeap.Pop() + + fmt.Println(val) //12 + fmt.Println(ok) //true +} +``` + + + +### Peek +返回堆中最大值,如果堆为空,返回零值并返回false
+ +函数签名: + +```go +func (h *MaxHeap[T]) Peek() (T, bool) +``` +示例: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + values := []int{6, 5, 2, 4, 7, 10, 12, 1, 3, 8, 9, 11} + + for _, v := range values { + maxHeap.Push(v) + } + val, ok := maxHeap.Peek() + + fmt.Println(val) //12 + fmt.Println(maxHeap.Size()) //12 +} +``` + + + +### Data +返回堆中全部元素的切片
+ +函数签名: + +```go +func (h *MaxHeap[T]) Data() []T +``` +示例: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + values := []int{6, 5, 2, 4, 7, 10, 12, 1, 3, 8, 9, 11} + + for _, v := range values { + maxHeap.Push(v) + } + + fmt.Println(maxHeap.Data()) //[]int{12, 9, 11, 4, 8, 10, 7, 1, 3, 5, 6, 2} +} +``` + + +### Size +返回堆中元素的数量
+ +函数签名: + +```go +func (h *MaxHeap[T]) Size() int +``` +示例: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + values := []int{6, 5, 2} + + for _, v := range values { + maxHeap.Push(v) + } + + fmt.Println(maxHeap.Size()) //3 +} +``` + + + +### PrintStructure +打印堆的树形结构
+ +函数签名: + +```go +func (h *MaxHeap[T]) PrintStructure() +``` +示例: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + values := []int{6, 5, 2, 4, 7, 10, 12, 1, 3, 8, 9, 11} + + for _, v := range values { + maxHeap.Push(v) + } + + fmt.Println(maxHeap.PrintStructure()) +// 12 +// 9 11 +// 4 8 10 7 +// 1 3 5 6 2 +} +``` \ No newline at end of file diff --git a/docs/api/packages/datastructure/link.md b/docs/api/packages/datastructure/link.md new file mode 100644 index 00000000..76b5e8d6 --- /dev/null +++ b/docs/api/packages/datastructure/link.md @@ -0,0 +1,1017 @@ +# Linklist +Linklist是链表数据结构,它的节点有一个值和一个指向下一个节点的指针。 + + + +## 源码 + +- [https://github.com/duke-git/lancet/blob/main/datastructure/link/singlylink.go](https://github.com/duke-git/lancet/blob/main/datastructure/link/singlylink.go) +- [https://github.com/duke-git/lancet/blob/main/datastructure/link/doublylink.go](https://github.com/duke-git/lancet/blob/main/datastructure/link/doublylink.go) + + + + +## 用法 +```go +import ( + link "github.com/duke-git/lancet/v2/datastructure/link" +) +``` + + + +## 目录 + +### 1. SinglyLink单链表 + +- [NewSinglyLink](#NewSinglyLink) +- [Values](#SinglyLink_Values) +- [InsertAt](#SinglyLink_InsertAt) +- [InsertAtHead](#SinglyLink_InsertAtHead) +- [InsertAtTail](#SinglyLink_InsertAtTail) +- [DeleteAt](#SinglyLink_DeleteAt) +- [DeleteAtHead](#SinglyLink_DeleteAtHead) +- [DeleteAtTail](#SinglyLink_DeleteAtTail) +- [DeleteValue](#SinglyLink_DeleteValue) +- [Reverse](#SinglyLink_Reverse) +- [GetMiddleNode](#SinglyLink_GetMiddleNode) +- [Size](#SinglyLink_Size) +- [IsEmpty](#SinglyLink_IsEmpty) +- [Clear](#SinglyLink_Clear) +- [Print](#SinglyLink_Print) + +### 2. DoublyLink双向链表 + +- [NewDoublyLink](#NewDoublyLink) +- [Values](#DoublyLink_Values) +- [InsertAt](#DoublyLink_InsertAt) +- [InsertAtHead](#DoublyLink_InsertAtHead) +- [InsertAtTail](#DoublyLink_InsertAtTail) +- [DeleteAt](#DoublyLink_DeleteAt) +- [DeleteAtHead](#DoublyLink_DeleteAtHead) +- [DeleteAtTail](#DoublyLink_DeleteAtTail) +- [Reverse](#DoublyLink_Reverse) +- [GetMiddleNode](#DoublyLink_GetMiddleNode) +- [Size](#DoublyLink_Size) +- [IsEmpty](#DoublyLink_IsEmpty) +- [Clear](#DoublyLink_Clear) +- [Print](#DoublyLink_Print) + + + + +## 文档 + +### 1. SinglyLink +SingleLink是单向链表,它的节点有一个值和一个指向链表的下一个节点的指针。 + +### NewSinglyLink +创建SinglyLink指针实例
+ +函数签名: + +```go +type LinkNode[T any] struct { + Value T + Next *LinkNode[T] +} +type SinglyLink[T any] struct { + Head *datastructure.LinkNode[T] + length int +} +func NewSinglyLink[T any]() *SinglyLink[T] +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + fmt.Println(lk) +} +``` + + + +### Values +返回链表中所有节点值的切片
+ +函数签名: + +```go +func (link *SinglyLink[T]) Values() []T +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.Values()) //[]int{1, 2, 3} +} +``` + + + + +### InsertAt +将值插入到索引处的链表中,索引应大于或等于0且小于或等于链表节点数
+ +函数签名: + +```go +func (link *SinglyLink[T]) InsertAt(index int, value T) +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAt(1, 1) //do nothing + + lk.InsertAt(0, 1) + lk.InsertAt(1, 2) + lk.InsertAt(2, 3) + lk.InsertAt(2, 4) + + fmt.Println(lk.Values()) //[]int{1, 2, 4, 3} +} +``` + + + + +### InsertAtHead +将值插入到链表表头
+ +函数签名: + +```go +func (link *SinglyLink[T]) InsertAtHead(value T) +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtHead(1) + lk.InsertAtHead(2) + lk.InsertAtHead(3) + + fmt.Println(lk.Values()) //[]int{3, 2, 1} +} +``` + + + + +### InsertAtTail +将值插入到链表末尾
+ +函数签名: + +```go +func (link *SinglyLink[T]) InsertAtTail(value T) +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.Values()) //[]int{1, 2, 3} +} +``` + + + +### DeleteAt +删除特定索引处的值,索引应大于或等于0且小于或等于链接节点数-1
+ +函数签名: + +```go +func (link *SinglyLink[T]) DeleteAt(index int) +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + lk.InsertAtTail(4) + + lk.DeleteAt(3) + + fmt.Println(lk.Values()) //[]int{1, 2, 3} +} +``` + + + +### DeleteAtHead +删除链表头节点
+ +函数签名: + +```go +func (link *SinglyLink[T]) DeleteAtHead() +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + lk.InsertAtTail(4) + + lk.DeleteAtHead() + + fmt.Println(lk.Values()) //[]int{2, 3, 4} +} +``` + + + + +### DeleteAtTail +删除链表末尾节点
+ +函数签名: + +```go +func (link *SinglyLink[T]) DeleteAtTail() +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.DeleteAtTail() + + fmt.Println(lk.Values()) //[]int{1, 2} +} +``` + + + +### DeleteValue +删除链表中指定的value值
+ +函数签名: + +```go +func (link *SinglyLink[T]) DeleteValue(value T) +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.DeleteValue(2) + fmt.Println(lk.Values()) //[]int{1, 3} +} +``` + + + + +### Reverse +反转链表所有节点顺序
+ +函数签名: + +```go +func (link *SinglyLink[T]) Reverse() +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.Reverse() + fmt.Println(lk.Values()) //[]int{3, 2, 1} +} +``` + + + +### GetMiddleNode +获取链表中部节点
+ +函数签名: + +```go +func (link *SinglyLink[T]) GetMiddleNode() *datastructure.LinkNode[T] +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + midNode := lk.GetMiddleNode() + fmt.Println(midNode.Value) //2 +} +``` + + + +### Size +获取链表节点数量
+ +函数签名: + +```go +func (link *SinglyLink[T]) Size() int +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.Size()) //3 +} +``` + + + +### IsEmpty +判断链表是否为空
+ +函数签名: + +```go +func (link *SinglyLink[T]) IsEmpty() bool +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + fmt.Println(lk.IsEmpty()) //true + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.IsEmpty()) //false +} +``` + + + +### Clear +清空链表所有节点
+ +函数签名: + +```go +func (link *SinglyLink[T]) Clear() +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.Clear() + + fmt.Println(lk.Values()) // +} +``` + + + +### Print +打印链表结构
+ +函数签名: + +```go +func (link *SinglyLink[T]) Clear() +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.Print() //[ &{Value:1 Pre:创建NewDoublyLink指针实例
+ +函数签名: + +```go +type LinkNode[T any] struct { + Value T + Pre *LinkNode[T] + Next *LinkNode[T] +} +type DoublyLink[T any] struct { + Head *datastructure.LinkNode[T] + length int +} +func NewDoublyLink[T any]() *DoublyLink[T] +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + fmt.Println(lk) +} +``` + + + +### Values +返回链表中所有节点值的切片
+ +函数签名: + +```go +func (link *DoublyLink[T]) Values() []T +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.Values()) //[]int{1, 2, 3} +} +``` + + + + +### InsertAt +将值插入到索引处的链表中,索引应大于或等于0且小于或等于链表节点数
+ +函数签名: + +```go +func (link *DoublyLink[T]) InsertAt(index int, value T) +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAt(1, 1) //do nothing + + lk.InsertAt(0, 1) + lk.InsertAt(1, 2) + lk.InsertAt(2, 3) + lk.InsertAt(2, 4) + + fmt.Println(lk.Values()) //[]int{1, 2, 4, 3} +} +``` + + + + +### InsertAtHead +将值插入到链表表头
+ +函数签名: + +```go +func (link *DoublyLink[T]) InsertAtHead(value T) +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtHead(1) + lk.InsertAtHead(2) + lk.InsertAtHead(3) + + fmt.Println(lk.Values()) //[]int{3, 2, 1} +} +``` + + + + +### InsertAtTail +将值插入到链表末尾
+ +函数签名: + +```go +func (link *DoublyLink[T]) InsertAtTail(value T) +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.Values()) //[]int{1, 2, 3} +} +``` + + + +### DeleteAt +删除特定索引处的值,索引应大于或等于0且小于或等于链接节点数-1
+ +函数签名: + +```go +func (link *DoublyLink[T]) DeleteAt(index int) +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + lk.InsertAtTail(4) + + lk.DeleteAt(3) + + fmt.Println(lk.Values()) //[]int{1, 2, 3} +} +``` + + + +### DeleteAtHead +删除链表头节点
+ +函数签名: + +```go +func (link *DoublyLink[T]) DeleteAtHead() +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + lk.InsertAtTail(4) + + lk.DeleteAtHead() + + fmt.Println(lk.Values()) //[]int{2, 3, 4} +} +``` + + + + +### DeleteAtTail +删除链表末尾节点
+ +函数签名: + +```go +func (link *DoublyLink[T]) DeleteAtTail() +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.DeleteAtTail() + + fmt.Println(lk.Values()) //[]int{1, 2} +} +``` + + + + +### Reverse +反转链表所有节点顺序
+ +函数签名: + +```go +func (link *DoublyLink[T]) Reverse() +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.Reverse() + fmt.Println(lk.Values()) //[]int{3, 2, 1} +} +``` + + + +### GetMiddleNode +获取链表中部节点
+ +函数签名: + +```go +func (link *DoublyLink[T]) GetMiddleNode() *datastructure.LinkNode[T] +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + midNode := lk.GetMiddleNode() + fmt.Println(midNode.Value) //2 +} +``` + + + +### Size +获取链表节点数量
+ +函数签名: + +```go +func (link *DoublyLink[T]) Size() int +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.Size()) //3 +} +``` + + + +### IsEmpty +判断链表是否为空
+ +函数签名: + +```go +func (link *DoublyLink[T]) IsEmpty() bool +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + fmt.Println(lk.IsEmpty()) //true + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.IsEmpty()) //false +} +``` + + + +### Clear +清空链表所有节点
+ +函数签名: + +```go +func (link *DoublyLink[T]) Clear() +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.Clear() + + fmt.Println(lk.Values()) // +} +``` + + + +### Print +打印链表结构
+ +函数签名: + +```go +func (link *DoublyLink[T]) Clear() +``` +示例: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.Print() // +} +``` \ No newline at end of file diff --git a/docs/api/packages/datastructure/list.md b/docs/api/packages/datastructure/list.md new file mode 100644 index 00000000..5051efca --- /dev/null +++ b/docs/api/packages/datastructure/list.md @@ -0,0 +1,1116 @@ +# List +List是线性表数据结构, 用go切片实现。 + + + +## 源码 + +- [https://github.com/duke-git/lancet/blob/main/datastructure/list/list.go](https://github.com/duke-git/lancet/blob/main/datastructure/list/list.go) + + + + +## 用法 +```go +import ( + "github.com/duke-git/lancet/v2/datastructure" +) +``` + + + +## 目录 + +- [NewList](#NewList) +- [Contain](#Contain) +- [Data](#Data) +- [ValueOf](#ValueOf) +- [IndexOf](#IndexOf) +- [LastIndexOf](#LastIndexOf) +- [IndexOfFunc](#IndexOfFunc) +- [LastIndexOfFunc](#LastIndexOfFunc) +- [Push](#Push) +- [PopFirst](#PopFirst) +- [PopLast](#PopLast) +- [DeleteAt](#DeleteAt) +- [InsertAt](#InsertAt) +- [UpdateAt](#UpdateAt) +- [Equal](#Equal) +- [IsEmpty](#IsEmpty) +- [Clear](#Clear) +- [Clone](#Clone) +- [Merge](#Merge) +- [Size](#Size) +- [Cap](#Cap) +- [Swap](#Swap) +- [Reverse](#Reverse) +- [Unique](#Unique) +- [Union](#Union) +- [Intersection](#Intersection) +- [Difference](#Difference) +- [SymmetricDifference](#SymmetricDifference) +- [RetainAll](#RetainAll) +- [DeleteAll](#DeleteAll) +- [ForEach](#ForEach) +- [Iterator](#Iterator) +- [ListToMap](#ListToMap) +- [SubList](#SubList) +- [DeleteIf](#DeleteIf) + + + +## 文档 + +### NewList +返回List指针实例
+ +函数签名: + +```go +type List[T any] struct { + data []T +} +func NewList[T any](data []T) *List[T] +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + fmt.Println(li) +} +``` + + + +### Contain +判断列表中是否包含特定值
+ +函数签名: + +```go +func (l *List[T]) Contain(value T) bool +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + + fmt.Println(li.Contain(1)) //true + fmt.Println(li.Contain(0)) //false +} +``` + + + + +### Data +返回List中所有数据(切片)
+ +函数签名: + +```go +func (l *List[T]) Data() []T +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + data := li.Data() + + fmt.Println(data) //[]int{1, 2, 3} +} +``` + + + + +### ValueOf +返回列表中索引处的值指针
+ +函数签名: + +```go +func (l *List[T]) ValueOf(index int) (*T, bool) +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + v, ok := li.ValueOf(0) + + fmt.Println(*v) //1 + fmt.Println(ok) //true +} +``` + + + + +### IndexOf +返回列表中值的索引,如果没有找到返回-1
+ +函数签名: + +```go +func (l *List[T]) IndexOf(value T) int +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + + fmt.Println(li.IndexOf(1)) //0 + fmt.Println(li.IndexOf(0)) //-1 +} +``` + + +### LastIndexOf +返回列表中最后一次出现的值的索引。如果未找到,则返回-1
+ +函数签名: + +```go +func (l *List[T]) LastIndexOf(value T) int +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3, 1}) + + fmt.Println(li.LastIndexOf(1)) // 3 + fmt.Println(li.LastIndexOf(0)) //-1 +} +``` + +### IndexOfFunc +返回第一个符合函数条件的元素的索引。如果未找到,则返回-1
+ +函数签名: + +```go +func (l *List[T]) IndexOfFunc(f func(T) bool) int +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + + fmt.Println(li.IndexOfFunc(func(a int) bool { return a == 1 })) //0 + fmt.Println(li.IndexOfFunc(func(a int) bool { return a == 0 })) //-1 +} +``` + +### LastIndexOfFunc +返回最后一个符合函数条件的元素的索引。如果未找到,则返回-1
+ +函数签名: + +```go +func (l *List[T]) LastIndexOfFunc(f func(T) bool) int +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3, 1}) + + fmt.Println(li.LastIndexOfFunc(func(a int) bool { return a == 1 })) // 3 + fmt.Println(li.LastIndexOfFunc(func(a int) bool { return a == 0 })) //-1 +} +``` + + + +### Push +将值附加到列表末尾
+ +函数签名: + +```go +func (l *List[T]) Push(value T) +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + li.Push(4) + + fmt.Println(li.Data()) //[]int{1, 2, 3, 4} +} +``` + + + + +### PopFirst +删除列表的第一个值并返回该值
+ +函数签名: + +```go +func (l *List[T]) PopFirst() (*T, bool) +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + v, ok := li.PopFirst() + + fmt.Println(*v) //1 + fmt.Println(ok) //true + fmt.Println(li.Data()) //2, 3 +} +``` + + + + + +### PopFirst +删除列表的最后一个值并返回该值
+ +函数签名: + +```go +func (l *List[T]) PopLast() (*T, bool) +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + v, ok := li.PopLast() + + fmt.Println(*v) //3 + fmt.Println(ok) //true + fmt.Println(li.Data()) //1, 2 +} +``` + + + + +### DeleteAt +删除索引处列表的值,如果索引不在0和列表数据长度之间,则不执行任何操作
+ +函数签名: + +```go +func (l *List[T]) DeleteAt(index int) +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3, 4}) + + li.DeleteAt(-1) + fmt.Println(li.Data()) //1,2,3,4 + + li.DeleteAt(4) + fmt.Println(li.Data()) //1,2,3,4 + + li.DeleteAt(0) + fmt.Println(li.Data()) //2,3,4 + + li.DeleteAt(2) + fmt.Println(li.Data()) //2,3 +} +``` + + + + +### InsertAt +在索引处插入值到列表中,如果索引不在 0 和列表数据长度之间,则不执行任何操作
+ +函数签名: + +```go +func (l *List[T]) InsertAt(index int, value T) +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + + li.InsertAt(-1, 0) + fmt.Println(li.Data()) //1,2,3 + + li.InsertAt(4, 0) + fmt.Println(li.Data()) //1,2,3 + + li.InsertAt(3, 4) + fmt.Println(li.Data()) //1,2,3,4 + + // li.InsertAt(2, 4) + // fmt.Println(li.Data()) //1,2,4,3 +} +``` + + + +### UpdateAt +更新索引处列表的值,索引应该在0和列表数据长度-1之间
+ +函数签名: + +```go +func (l *List[T]) UpdateAt(index int, value T) +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + + li.UpdateAt(-1, 0) + fmt.Println(li.Data()) //1,2,3 + + li.UpdateAt(2, 4) + fmt.Println(li.Data()) //1,2,4 + + li.UpdateAt(3, 5) + fmt.Println(li.Data()) //1,2,4 +} +``` + + +### Equal +比较一个列表和另一个列表,在每个元素上使用 reflect.DeepEqual
+ +函数签名: + +```go +func (l *List[T]) Equal(other *List[T]) bool +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li1 := list.NewList([]int{1, 2, 3, 4}) + li2 := list.NewList([]int{1, 2, 3, 4}) + li3 := list.NewList([]int{1, 2, 3}) + + fmt.Println(li1.Equal(li2)) //true + fmt.Println(li1.Equal(li3)) //false +} +``` + + + +### IsEmpty +判断列表是否为空
+ +函数签名: + +```go +func (l *List[T]) IsEmpty() bool +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li1 := list.NewList([]int{1, 2, 3}) + li2 := list.NewList([]int{}) + + fmt.Println(li1.IsEmpty()) //false + fmt.Println(li2.IsEmpty()) //true +} +``` + + + + +### Clear +清空列表数据
+ +函数签名: + +```go +func (l *List[T]) Clear() +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + li.Clear() + + fmt.Println(li.Data()) // empty +} +``` + + + +### Clone +返回列表的一个拷贝
+ +函数签名: + +```go +func (l *List[T]) Clone() *List[T] +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + cloneList := li.Clone() + + fmt.Println(cloneList.Data()) // 1,2,3 +} +``` + + + + +### Merge +合并两个列表,返回新的列表
+ +函数签名: + +```go +func (l *List[T]) Merge(other *List[T]) *List[T] +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li1 := list.NewList([]int{1, 2, 3, 4}) + li2 := list.NewList([]int{4, 5, 6}) + li3 := li1.Merge(li2) + + fmt.Println(li3.Data()) //1, 2, 3, 4, 4, 5, 6 +} +``` + + + +### Size +返回列表数据项的数量
+ +函数签名: + +```go +func (l *List[T]) Size() int +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3, 4}) + + fmt.Println(li.Size()) //4 +} +``` + + + +### Cap +返回列表数据容量
+ +函数签名: + +```go +func (l *List[T]) Cap() int +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + data := make([]int, 0, 100) + + li := list.NewList(data) + + fmt.Println(li.Cap()) // 100 +} +``` + + + +### Swap +交换列表中两个索引位置的值
+ +函数签名: + +```go +func (l *List[T]) Swap(i, j int) +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3, 4}) + li.Swap(0, 3) + + fmt.Println(li.Data()) //4, 2, 3, 1 +} +``` + + + + +### Reverse +反转列表的数据项顺序
+ +函数签名: + +```go +func (l *List[T]) Reverse() +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3, 4}) + li.Reverse() + + fmt.Println(li.Data()) //4, 3, 2, 1 +} +``` + + + + +### Unique +列表去除重复数据项
+ +函数签名: + +```go +func (l *List[T]) Unique() +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 2, 3, 4}) + li.Unique() + + fmt.Println(li.Data()) //1,2,3,4 +} +``` + + + + +### Union +两个列表取并集,去除重复数据项
+ +函数签名: + +```go +func (l *List[T]) Union(other *List[T]) *List[T] +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li1 := list.NewList([]int{1, 2, 3, 4}) + li2 := list.NewList([]int{4, 5, 6}) + li3 := li1.Union(li2) + + fmt.Println(li3.Data()) //1,2,3,4,5,6 +} +``` + + + + +### Intersection +两个列表取交集
+ +函数签名: + +```go +func (l *List[T]) Intersection(other *List[T]) *List[T] +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li1 := list.NewList([]int{1, 2, 3, 4}) + li2 := list.NewList([]int{4, 5, 6}) + li3 := li1.Intersection(li2) + + fmt.Println(li3.Data()) //4 +} +``` + + +### Difference +差集运算。
+ +函数签名: + +```go +func (l *List[T]) Difference(other *List[T]) *List[T] +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list1 := NewList([]int{1, 2, 3}) + list2 := NewList([]int{1, 2, 4}) + + list3 := list1.Intersection(list2) + + fmt.Println(list3.Data()) //3 +} +``` + + +### SymmetricDifference +对称差集运算。
+ +函数签名: + +```go +func (l *List[T]) SymmetricDifference(other *List[T]) *List[T] +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list1 := NewList([]int{1, 2, 3}) + list2 := NewList([]int{1, 2, 4}) + + list3 := list1.Intersection(list2) + + fmt.Println(list3.Data()) //3, 4 +} +``` + + +### RetainAll +仅保留列表中包含在给定列表中的元素。
+ +函数签名: + +```go +func (l *List[T]) RetainAll(list *List[T]) bool +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list := NewList([]int{1, 2, 3, 4}) + list1 := NewList([]int{1, 2, 3, 4}) + list2 := NewList([]int{1, 2, 3, 4}) + + retain := NewList([]int{1, 2}) + retain1 := NewList([]int{2, 3}) + retain2 := NewList([]int{1, 2, 5}) + + list.RetainAll(retain) + list1.RetainAll(retain1) + list2.RetainAll(retain2) + + fmt.Println(list.Data()) //1, 2 + fmt.Println(list1.Data()) //2, 3 + fmt.Println(list2.Data()) //1, 2 +} +``` + + +### DeleteAll +从列表中删除给定列表中包含的所有元素。
+ +函数签名: + +```go +func (l *List[T]) DeleteAll(list *List[T]) bool +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list := NewList([]int{1, 2, 3, 4}) + list1 := NewList([]int{1, 2, 3, 4}) + list2 := NewList([]int{1, 2, 3, 4}) + + del := NewList([]int{1}) + del1 := NewList([]int{2, 3}) + del2 := NewList([]int{1, 2, 5}) + + list.DeleteAll(del) + list1.DeleteAll(del1) + list2.DeleteAll(del2) + + fmt.Println(list.Data()) //2,3,4 + fmt.Println(list1.Data()) //1,4 + fmt.Println(list2.Data()) //3,4 +} +``` + + +### ForEach +对列表的每个元素执行给定的操作。
+ +函数签名: + +```go +func (l *List[T]) ForEach(consumer func(T)) +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list := NewList([]int{1, 2, 3, 4}) + + result := make([]int, 0) + list.ForEach(func(i int) { + result = append(result, i) + }) + + fmt.Println(result.Data()) //1,2,3,4 +} +``` + + +### Iterator +按顺序返回列表中元素的迭代器。
+ +函数签名: + +```go +func (l *List[T]) Iterator() iterator.Iterator[T] +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list := NewList([]int{1, 2, 3, 4}) + + iterator := list.Iterator() + + result := make([]int, 0) + for iterator.HasNext() { + item, _ := iterator.Next() + result = append(result, item) + } + + fmt.Println(result.Data()) //1,2,3,4 +} +``` + + +### ListToMap +基于iteratee函数将列表转换为映射map。
+ +函数签名: + +```go +func ListToMap[T any, K comparable, V any](list *List[T], iteratee func(T) (K, V)) map[K]V +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list := NewList([]int{1, 2, 3, 4}) + + result := ListToMap(list, func(n int) (int, bool) { + return n, n > 1 + }) + + fmt.Println(result) //map[int]bool{1: false, 2: true, 3: true, 4: true} +} +``` + + +### SubList +返回指定的fromIndex(包含)和toIndex(不包含)之间的原始列表的子列表。
+ +函数签名: + +```go +func (l *List[T]) SubList(fromIndex, toIndex int) *List[T] +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + l := list.NewList([]int{1, 2, 3, 4, 5, 6}) + + fmt.Println(l.SubList(2, 5)) // []int{3, 4, 5} +} +``` + + + + +### DeleteIf +删除列表中所有符合函数(调用函数返回true)的元素,返回删除元素的数量
+ +函数签名: + +```go +func (l *List[T]) DeleteIf(f func(T) bool) int +``` +示例: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1}) + + fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12 + fmt.Println(l.Data()) // []int{2, 3, 4} +} +``` \ No newline at end of file diff --git a/docs/api/packages/datastructure/optional.md b/docs/api/packages/datastructure/optional.md new file mode 100644 index 00000000..4d9365ab --- /dev/null +++ b/docs/api/packages/datastructure/optional.md @@ -0,0 +1,412 @@ +# Optional +Optional类型代表一个可选的值,它要么包含一个实际值,要么为空。 + + + +## 源码 + +- [https://github.com/duke-git/lancet/blob/main/datastructure/optional/optional.go](https://github.com/duke-git/lancet/blob/main/datastructure/optional/optional.go) + + + + +## 用法 +```go +import ( + "github.com/duke-git/lancet/v2/datastructure/optional" +) +``` + + + +## 目录 + +- [Of](#Of) +- [FromNillable](#FromNillable) +- [Default](#Default) +- [IsNotNil](#IsNotNil) +- [IsNil](#IsNil) +- [IsNotNil](#IsNotNil) +- [IfNotNilOrElse](#IfNotNilOrElse) +- [Umwarp](#Umwarp) +- [OrElse](#OrElse) +- [OrElseGet](#OrElseGet) +- [OrElseTrigger](#OrElseTrigger) + + + + +## 文档 + +### Of +返回一个包含非空值的Optional。
+ +函数签名: + +```go +func Of[T any](value T) Optional[T] +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + value := 42 + opt := optional.Of(value) + + fmt.Println(opt.Get()) + + // Output: + // 42 +} +``` + +### FromNillable +返回一个包含给定值的Optional,该值可能为空 (nil)。
+ +函数签名: + +```go +func FromNillable[T any](value *T) Optional[T] +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + var value *int = nil + opt := optional.FromNillable(value) + + fmt.Println(opt.IsNotNil()) + + value = new(int) + *value = 42 + opt = optional.FromNillable(value) + + fmt.Println(opt.IsNotNil()) + + + // Output: + // false + // true +} +``` + + +### Default +返回一个空Optional实例。
+ +函数签名: + +```go +func Default[T any]() Optional[T] +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + optDefault := optional.Default[int]() + fmt.Println(optDefault.IsNil()) + + // Output: + // true +} +``` + + +### IsNil +验证Optional是否为空。
+ +函数签名: + +```go +func (o Optional[T]) IsNil() bool +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + optDefault := optional.Default[int]() + fmt.Println(optDefault.IsNil()) + + // Output: + // true +} +``` + +### IsNotNil +检查当前Optional内是否存在值。
+ +函数签名: + +```go +func (o Optional[T]) IsNotNil() bool +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + var value *int = nil + opt := optional.FromNillable(value) + + fmt.Println(opt.IsNotNil()) + + value = new(int) + *value = 42 + opt = optional.FromNillable(value) + + fmt.Println(opt.IsNotNil()) + + + // Output: + // false + // true +} +``` + +### IfNotNil +如果值存在,则使用action方法执行给定的操作。
+ +函数签名: + +```go +func (o Optional[T]) IfNotNil(action func(value T)) +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + called := false + action := func(value int) { called = true } + + optDefault := optional.Default[int]() + optDefault.IfNotNil(action) + + fmt.Println(called) + + called = false // Reset for next test + optWithValue := optional.Of(42) + optWithValue.IfNotNil(action) + + fmt.Println(optWithValue.IsNotNil()) + + // Output: + // false + // true +} +``` + + +### IfNotNilOrElse +根据是否存在值执行相应的操作:有值则执行指定操作,没有值则执行默认操作。
+ +函数签名: + +```go +func (o Optional[T]) IfNotNilOrElse(action func(value T), fallbackAction func()) +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + calledWithValue := false + valueAction := func(value int) { calledWithValue = true } + emptyAction := func() { t.Errorf("Empty action should not be called when value is present") } + + optWithValue := optional.Of(42) + optWithValue.IfNotNilOrElse(valueAction, emptyAction) + + fmt.Println(calledWithValue) + + calledWithEmpty := false + valueAction = func(value int) { t.Errorf("Value action should not be called when value is not present") } + emptyAction = func() { calledWithEmpty = true } + + optDefault := optional.Default[int]() + optDefault.IfNotNilOrElse(valueAction, emptyAction) + + fmt.Println(calledWithEmpty) + + // Output: + // true + // true +} +``` + +### Unwrap +如果存在,返回该值,否则引发panic。
+ +函数签名: + +```go +func (o Optional[T]) Unwrap() T +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + value := 42 + opt := optional.Of(value) + + fmt.Println(opt.Unwrap()) + + // Output: + // 42 +} +``` + + +### OrElse +检查Optional值是否存在,如果存在,则直接返回该值。如果不存在,返回参数other值。
+ +函数签名: + +```go +func (o Optional[T]) OrElse(other T) T +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + optDefault := optional.Empty[int]() + val := optDefault.OrElse(100) + fmt.Println(val) + + optWithValue := optional.Of(42) + val = optWithValue.OrElse(100) + fmt.Println(val) + + // Output: + // 100 + // 42 +} +``` + + +### OrElseGet +检查Optional值是否存在,如果存在,则直接返回该值。如果不存在,则调用一个提供的函数 (supplier),并返回该函数的执行结果。
+ +函数签名: + +```go +func (o Optional[T]) OrElseGet(action func() T) T +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + optDefault := optional.Default[int]() + action := func() int { return 100 } + + val := optDefault.OrElseGet(action) + fmt.Println(val) + + // Output: + // 100 +} +``` + +### OrElseTrigger +检查Optional值是否存在,如果存在,则直接返回该值,否则返回错误。
+ +函数签名: + +```go + OrElseTrigger(errorHandler func() error) (T, error) +``` +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + optDefault := optional.Default[int]() + _, err := optDefault.OrElseTrigger(func() error { return errors.New("no value") }) + + fmt.Println(err.Error()) + + optWithValue := optional.Of(42) + val, err := optWithValue.OrElseTrigger(func() error { return errors.New("no value") }) + + fmt.Println(val) + fmt.Println(err) + + // Output: + // no value + // 42 + // nil +} +``` \ No newline at end of file diff --git a/docs/api/packages/datastructure/queue.md b/docs/api/packages/datastructure/queue.md new file mode 100644 index 00000000..fddc43e3 --- /dev/null +++ b/docs/api/packages/datastructure/queue.md @@ -0,0 +1,1387 @@ +# Queue +队列数据结构,包括ArrayQueue, LinkedQueue, CircularQueue, and PriorityQueue。 + + + +## 源码 + +- [https://github.com/duke-git/lancet/blob/main/datastructure/queue/arrayqueue.go](https://github.com/duke-git/lancet/blob/main/datastructure/queue/arrayqueue.go) +- [https://github.com/duke-git/lancet/blob/main/datastructure/queue/linkedqueue.go](https://github.com/duke-git/lancet/blob/main/datastructure/queue/linkedqueue.go) +- [https://github.com/duke-git/lancet/blob/main/datastructure/queue/circularqueue.go](https://github.com/duke-git/lancet/blob/main/datastructure/queue/circularqueue.go) +- [https://github.com/duke-git/lancet/blob/main/datastructure/queue/priorityqueue.go](https://github.com/duke-git/lancet/blob/main/datastructure/queue/priorityqueue.go) + + + +## 用法 +```go +import ( + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) +``` + + + +## 目录 + +### 1. ArrayQueue +- [NewArrayQueue](#NewArrayQueue) +- [Data](#ArrayQueue_Data) +- [Enqueue](#ArrayQueue_Enqueue) +- [Dequeue](#ArrayQueue_Dequeue) +- [Front](#ArrayQueue_Front) +- [Back](#ArrayQueue_Back) +- [Size](#ArrayQueue_Size) +- [IsEmpty](#ArrayQueue_IsEmpty) +- [IsFull](#ArrayQueue_IsFull) +- [Clear](#ArrayQueue_Clear) +- [Contain](#ArrayQueue_Contain) + + + +### 2. LinkedQueue +- [NewLinkedQueue](#NewLinkedQueue) +- [Data](#LinkedQueue_Data) +- [Enqueue](#LinkedQueue_Enqueue) +- [Dequeue](#LinkedQueue_Dequeue) +- [Front](#LinkedQueue_Front) +- [Back](#LinkedQueue_Back) +- [Size](#LinkedQueue_Size) +- [IsEmpty](#LinkedQueue_IsEmpty) +- [Clear](#LinkedQueue_Clear) +- [Contain](#LinkedQueue_Contain) + + +### 3. CircularQueue +- [NewCircularQueue](#NewCircularQueue) +- [Data](#CircularQueue_Data) +- [Enqueue](#CircularQueue_Enqueue) +- [Dequeue](#CircularQueue_Dequeue) +- [Front](#CircularQueue_Front) +- [Back](#CircularQueue_Back) +- [Size](#CircularQueue_Size) +- [IsEmpty](#CircularQueue_IsEmpty) +- [IsFull](#CircularQueue_IsFull) +- [Clear](#CircularQueue_Clear) +- [Contain](#CircularQueue_Contain) + + + +### 4. PriorityQueue +- [NewPriorityQueue](#NewPriorityQueue) +- [Data](#PriorityQueue_Data) +- [Enqueue](#PriorityQueue_Enqueue) +- [Dequeue](#PriorityQueue_Dequeue) +- [IsEmpty](#PriorityQueue_IsEmpty) +- [IsFull](#PriorityQueue_IsFull) +- [Size](#PriorityQueue_Size) + + + + +## 文档 + +### 1. ArrayQueue +切片实现普通队列数据结构 + +### NewArrayQueue +返回具有特定容量的ArrayQueue指针
+ +函数签名: + +```go +func NewArrayQueue[T any](capacity int) *ArrayQueue[T] + +type ArrayQueue[T any] struct { + items []T + head int + tail int + capacity int + size int +} +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + fmt.Println(q.Data()) // [] +} +``` + + + +### Data +获取队列所有元素的切片
+ +函数签名: + +```go +func (q *ArrayQueue[T]) Data() []T +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + fmt.Println(q.Data()) // [] +} +``` + + + + +### Enqueue +元素入队列
+ +函数签名: + +```go +func (q *ArrayQueue[T]) Enqueue(item T) bool +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + + +### Dequeue +移除队列的头元素并返回
+ +函数签名: + +```go +func (q *ArrayQueue[T]) Dequeue() (T, bool) +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Dequeue()) // 1 + fmt.Println(q.Data()) // 2,3 +} +``` + + + + +### Front +获取对列头部元素
+ +函数签名: + +```go +func (q *ArrayQueue[T]) Front() T +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Front()) // 1 + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + + +### Back +获取对列尾部元素
+ +函数签名: + +```go +func (q *ArrayQueue[T]) Back() T +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Back()) // 3 + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + +### Size +获取队列元素的数量
+ +函数签名: + +```go +func (q *ArrayQueue[T]) Size() int +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Size()) // 3 +} +``` + + + +### IsEmpty +判断对了是否为空
+ +函数签名: + +```go +func (q *ArrayQueue[T]) IsEmpty() bool +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + fmt.Println(q.IsEmpty()) // true + + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.IsEmpty()) // false +} +``` + + + + +### IsFull +判断对了是否为满
+ +函数签名: + +```go +func (q *ArrayQueue[T]) IsFull() bool +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](3) + fmt.Println(q.IsFull()) // false + + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.IsFull()) // true +} +``` + + + +### Clear +清空队列元素
+ +函数签名: + +```go +func (q *ArrayQueue[T]) Clear() +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + q.Clear() + + fmt.Println(q.IsEmpty()) // true +} +``` + + + +### Contain +判断队列是否包含某个值
+ +函数签名: + +```go +func (q *ArrayQueue[T]) Contain(value T) bool +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Contain(1)) // true + fmt.Println(q.Contain(4)) // false +} +``` + + + +### 2. LinkedQueue +链表实现普通队列数据结构 + +### NewLinkedQueue +返回LinkedQueue指针
+ +函数签名: + +```go +func NewLinkedQueue[T any]() *LinkedQueue[T] + +type LinkedQueue[T any] struct { + head *datastructure.QueueNode[T] + tail *datastructure.QueueNode[T] + length int +} +type QueueNode[T any] struct { + Value T + Next *QueueNode[T] +} +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int]() + fmt.Println(q.Data()) // [] +} +``` + + + +### Data +获取队列所有元素的切片
+ +函数签名: + +```go +func (q *LinkedQueue[T]) Data() []T +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int]() + fmt.Println(q.Data()) // [] +} +``` + + + + +### Enqueue +元素入队列
+ +函数签名: + +```go +func (q *LinkedQueue[T]) Enqueue(value T) +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + + +### Dequeue +移除队列的头元素并返回
+ +函数签名: + +```go +func (q *LinkedQueue[T]) Dequeue() (T, error) +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Dequeue()) // 1 + fmt.Println(q.Data()) // 2,3 +} +``` + + + + +### Front +获取对列头部元素
+ +函数签名: + +```go +func (q *LinkedQueue[T]) Front() (*T, error) +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Front()) // 1 + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + + +### Back +获取对列尾部元素
+ +函数签名: + +```go +func (q *LinkedQueue[T]) Back() (*T, error) +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Back()) // 3 + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + +### Size +获取队列元素的数量
+ +函数签名: + +```go +func (q *LinkedQueue[T]) Size() int +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Size()) // 3 +} +``` + + + +### IsEmpty +判断对了是否为空
+ +函数签名: + +```go +func (q *LinkedQueue[T]) IsEmpty() bool +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + fmt.Println(q.IsEmpty()) // true + + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.IsEmpty()) // false +} +``` + + + + +### Clear +清空队列元素
+ +函数签名: + +```go +func (q *LinkedQueue[T]) Clear() +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + q.Clear() + + fmt.Println(q.IsEmpty()) // true +} +``` + + + +### Contain +判断队列是否包含某个值
+ +函数签名: + +```go +func (q *LinkedQueue[T]) Contain(value T) bool +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Contain(1)) // true + fmt.Println(q.Contain(4)) // false +} +``` + + + + +### 3. CircularQueue +切片实现的循环队列. + +### NewCircularQueue +返回具有特定容量的CircularQueue指针
+ +函数签名: + +```go +func NewCircularQueue[T any](capacity int) *CircularQueue[T] + +type CircularQueue[T any] struct { + data []T + front int + rear int + capacity int +} +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + fmt.Println(q.Data()) // [] +} +``` + + + +### Data +获取队列所有元素的切片
+ +函数签名: + +```go +func (q *CircularQueue[T]) Data() []T +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + fmt.Println(q.Data()) // [] +} +``` + + + + +### Enqueue +元素入队列
+ +函数签名: + +```go +func (q *CircularQueue[T]) Enqueue(value T) error +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + + +### Dequeue +移除队列的头元素并返回
+ +函数签名: + +```go +func (q *CircularQueue[T]) Dequeue() (*T, bool) +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + val := q.Dequeue() + fmt.Println(*val) // 1 + fmt.Println(q.Data()) // 2,3 +} +``` + + + + +### Front +获取对列头部元素
+ +函数签名: + +```go +func (q *CircularQueue[T]) Front() T +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Front()) // 1 + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + + +### Back +获取对列尾部元素
+ +函数签名: + +```go +func (q *CircularQueue[T]) Back() T +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Back()) // 3 + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + +### Size +获取队列元素的数量
+ +函数签名: + +```go +func (q *CircularQueue[T]) Size() int +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Size()) // 3 +} +``` + + + +### IsEmpty +判断对了是否为空
+ +函数签名: + +```go +func (q *CircularQueue[T]) IsEmpty() bool +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + fmt.Println(q.IsEmpty()) // true + + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.IsEmpty()) // false +} +``` + + + + +### IsFull +判断对了是否为满
+ +函数签名: + +```go +func (q *CircularQueue[T]) IsFull() bool +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](3) + fmt.Println(q.IsFull()) // false + + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.IsFull()) // true +} +``` + + + +### Clear +清空队列元素
+ +函数签名: + +```go +func (q *CircularQueue[T]) Clear() +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + q.Clear() + + fmt.Println(q.IsEmpty()) // true +} +``` + + + +### Contain +判断队列是否包含某个值
+ +函数签名: + +```go +func (q *CircularQueue[T]) Contain(value T) bool +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Contain(1)) // true + fmt.Println(q.Contain(4)) // false +} +``` + + +### 4. PriorityQueue +切片实现的优先级队列。 + +### NewPriorityQueue +返回一个具有特定容量的PriorityQueue指针,参数 `comarator` 用于比较队列中T类型的值。
+ +函数签名: + +```go +func NewPriorityQueue[T any](capacity int, comparator constraints.Comparator) *PriorityQueue[T] + +type PriorityQueue[T any] struct { + items []T + size int + comparator constraints.Comparator +} +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewPriorityQueue[int](3) + fmt.Println(q.Data()) // [] +} +``` + + + +### Data +获取队列所有元素的切片
+ +函数签名: + +```go +func (q *PriorityQueue[T]) Data() []T +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewPriorityQueue[int](3) + fmt.Println(q.Data()) // [] +} +``` + + + + +### Enqueue +元素入队列
+ +函数签名: + +```go +func (q *PriorityQueue[T]) Enqueue(item T) bool +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + comparator := &intComparator{} + q := queue.NewPriorityQueue[int](10, comparator) + for i := 1; i < 11; i++ { + q.Enqueue(i) + } + + fmt.Println(q.Data()) // 10, 9, 6, 7, 8, 2, 5, 1, 4, 3 +} +``` + + + + +### Dequeue +移除队列的头元素并返回
+ +函数签名: + +```go +func (q *PriorityQueue[T]) Dequeue() (T, bool) +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + comparator := &intComparator{} + q := queue.NewPriorityQueue[int](10, comparator) + for i := 1; i < 11; i++ { + q.Enqueue(i) + } + val, ok := pq.Dequeue() + fmt.Println(val) // 10 + fmt.Println(q.Data()) // 9, 8, 6, 7, 3, 2, 5, 1, 4 +} +``` + + + +### IsEmpty +判断对了是否为空
+ +函数签名: + +```go +func (q *PriorityQueue[T]) IsEmpty() bool +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + comparator := &intComparator{} + q := queue.NewPriorityQueue[int](10, comparator) + fmt.Println(q.IsEmpty()) // true + + for i := 1; i < 11; i++ { + q.Enqueue(i) + } + fmt.Println(q.IsEmpty()) // false +} +``` + + + + +### IsFull +判断对了是否为满
+ +函数签名: + +```go +func (q *PriorityQueue[T]) IsFull() bool +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + comparator := &intComparator{} + q := queue.NewPriorityQueue[int](10, comparator) + fmt.Println(q.IsFull()) // false + + for i := 1; i < 11; i++ { + q.Enqueue(i) + } + fmt.Println(q.IsFull()) // true +} +``` + + + + +### Size +获取队列元素的数量
+ +函数签名: + +```go +func (q *PriorityQueue[T]) Size() int +``` +示例: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + comparator := &intComparator{} + q := queue.NewPriorityQueue[int](10, comparator) + fmt.Println(q.IsFull()) // false + + for i := 1; i < 5; i++ { + q.Enqueue(i) + } + fmt.Println(q.Size()) // 4 +} +``` + + diff --git a/docs/api/packages/datastructure/set.md b/docs/api/packages/datastructure/set.md new file mode 100644 index 00000000..93dcbf50 --- /dev/null +++ b/docs/api/packages/datastructure/set.md @@ -0,0 +1,709 @@ +# Set + +集合数据结构,类似列表。Set中元素不重复。 + + + +## 源码 + +- [https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go](https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go) + + + +## 用法 + +```go +import ( + set "github.com/duke-git/lancet/v2/datastructure/set" +) +``` + + + +## 目录 + +- [New](#New) +- [FromSlice](#FromSlice) +- [Valuesdeprecated](#Values) +- [Add](#Add) +- [AddIfNotExist](#AddIfNotExist) +- [AddIfNotExistBy](#AddIfNotExistBy) +- [Delete](#Delete) +- [Contain](#Contain) +- [ContainAll](#ContainAll) +- [Clone](#Clone) +- [Size](#Size) +- [Equal](#Equal) +- [Iterate](#Iterate) +- [IsEmpty](#IsEmpty) +- [Union](#Union) +- [Intersection](#Intersection) +- [SymmetricDifference](#SymmetricDifference) +- [Minus](#Minus) +- [Pop](#Pop) +- [ToSlice](#ToSlice) +- [ToSortedSlice](#ToSortedSlice) + + + +## 文档 + +### New + +返回Set结构体对象
+ +函数签名: + +```go +type Set[T comparable] map[T]struct{} +func New[T comparable](items ...T) Set[T] +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int](1,2,2,3) + fmt.Println(st.Values()) //1,2,3 +} +``` + +### FromSlice + +基于切片创建集合
+ +函数签名: + +```go +func FromSlice[T comparable](items []T) Set[T] +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.FromSlice([]int{1, 2, 2, 3}) + fmt.Println(st.Values()) //1,2,3 +} +``` + +### Values + +获取集合中所有元素的切片。
+ +> ⚠️ 本函数已弃用,使用`ToSlice`代替。 + +函数签名: + +```go +func (s Set[T]) Values() []T +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int](1,2,2,3) + fmt.Println(st.Values()) //1,2,3 +} +``` + +### Add + +向集合中添加元素
+ +函数签名: + +```go +func (s Set[T]) Add(items ...T) +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int]() + st.Add(1, 2, 3) + + fmt.Println(st.Values()) //1,2,3 +} +``` + +### AddIfNotExist + +如果集合中不存在元素,则添加该元素返回true, 如果集合中存在元素, 不做任何操作,返回false
+ +函数签名: + +```go +func (s Set[T]) AddIfNotExist(item T) bool +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int]() + st.Add(1, 2, 3) + + r1 := st.AddIfNotExist(1) + r2 := st.AddIfNotExist(4) + + fmt.Println(r1) // false + fmt.Println(r2) // true + fmt.Println(st.Values()) // 1,2,3,4 +} +``` + +### AddIfNotExistBy + +根据checker函数判断元素是否在集合中,如果集合中不存在元素且checker返回true,则添加该元素返回true, 否则不做任何操作,返回false
+ +函数签名: + +```go +func (s Set[T]) AddIfNotExistBy(item T, checker func(element T) bool) bool +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int]() + st.Add(1, 2) + + ok := st.AddIfNotExistBy(3, func(val int) bool { + return val%2 != 0 + }) + fmt.Println(ok) // true + + + notOk := st.AddIfNotExistBy(4, func(val int) bool { + return val%2 != 0 + }) + fmt.Println(notOk) // false + + fmt.Println(st.Values()) // 1, 2, 3 +} +``` + +### Delete + +删除集合中元素
+ +函数签名: + +```go +func (s Set[T]) Delete(items ...T) +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int]() + st.Add(1, 2, 3) + + set.Delete(3) + fmt.Println(st.Values()) //1,2 +} +``` + +### Contain + +判断集合是否包含某个值
+ +函数签名: + +```go +func (s Set[T]) Contain(item T) bool +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int]() + st.Add(1, 2, 3) + + fmt.Println(st.Contain(1)) //true + fmt.Println(st.Contain(4)) //false +} +``` + +### ContainAll + +判断集合是否包含另一个集合
+ +函数签名: + +```go +func (s Set[T]) ContainAll(other Set[T]) bool +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New(1, 2) + set3 := set.New(1, 2, 3, 4) + + fmt.Println(set1.ContainAll(set2)) //true + fmt.Println(set1.ContainAll(set3)) //false +} +``` + +### Size + +获取集合中元素的个数
+ +函数签名: + +```go +func (s Set[T]) Size() int +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + + fmt.Println(set1.Size()) //3 +} +``` + +### Clone + +克隆一个集合
+ +函数签名: + +```go +func (s Set[T]) Clone() Set[T] +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set1.Clone() + + fmt.Println(set1.Size() == set2.Size()) //true + fmt.Println(set1.ContainAll(set2)) //true +} +``` + +### Equal + +比较两个集合是否相等,包含相同元素为相等
+ +函数签名: + +```go +func (s Set[T]) Equal(other Set[T]) bool +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New(1, 2, 3) + set3 := set.New(1, 2, 3, 4) + + fmt.Println(set1.Equal(set2)) //true + fmt.Println(set1.Equal(set3)) //false +} +``` + +### Iterate + +迭代结合,在每个元素上调用函数
+ +函数签名: + +```go +func (s Set[T]) Iterate(fn func(item T)) +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + arr := []int{} + set.Iterate(func(item int) { + arr = append(arr, item) + }) + + fmt.Println(arr) //1,2,3 +} +``` + +### EachWithBreak + +遍历集合的元素并为每个元素调用iteratee函数,当iteratee函数返回false时,终止遍历。
+ +函数签名: + +```go +func (s Set[T]) EachWithBreak(iteratee func(item T) bool) +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + s := set.New(1, 2, 3, 4, 5) + + var sum int + + s.EachWithBreak(func(n int) bool { + if n > 3 { + return false + } + sum += n + return true + }) + + fmt.Println(sum) //6 +} +``` + +### IsEmpty + +判断集合是否为空
+ +函数签名: + +```go +func (s Set[T]) IsEmpty() bool +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New() + + fmt.Println(set1.IsEmpty()) //false + fmt.Println(set2.IsEmpty()) //true +} +``` + +### Union + +求两个集合的并集
+ +函数签名: + +```go +func (s Set[T]) Union(other Set[T]) Set[T] +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New(2, 3, 4, 5) + set3 := set1.Union(set2) + + fmt.Println(set3.Values()) //1,2,3,4,5 +} +``` + +### Intersection + +求两个集合的交集
+ +函数签名: + +```go +func (s Set[T]) Intersection(other Set[T]) Set[T] +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New(2, 3, 4, 5) + set3 := set1.Intersection(set2) + + fmt.Println(set3.Values()) //2,3 +} +``` + +### SymmetricDifference + +返回一个集合,其中元素在第一个集合或第二个集合中,且不同时存在于两个集合中
+ +函数签名: + +```go +func (s Set[T]) SymmetricDifference(other Set[T]) Set[T] +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New(2, 3, 4, 5) + set3 := set1.SymmetricDifference(set2) + + fmt.Println(set3.Values()) //1,4,5 +} +``` + +### Minus + +创建一个集合,其元素在原始集中但不在比较集中
+ +函数签名: + +```go +func (s Set[T]) Minus(comparedSet Set[T]) Set[T] +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New(2, 3, 4, 5) + set3 := set.New(2, 3) + + res1 := set1.Minus(set2) + fmt.Println(res1.Values()) //1 + + res2 := set2.Minus(set3) + fmt.Println(res2.Values()) //4,5 +} +``` + +### Pop + +删除并返回集合中的顶部元素
+ +函数签名: + +```go +func (s Set[T]) Pop() (v T, ok bool) +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + s := set.New[int]() + s.Add(1) + s.Add(2) + s.Add(3) + + val, ok = s.Pop() + + fmt.Println(val) // 3 + fmt.Println(ok) // true +} +``` + +### ToSlice + +以切片的形式返回集合中所有的元素(无序)
+ +函数签名: + +```go +func (s Set[T]) ToSlice() (v T, ok bool) +``` + +示例: + +```go +func main() { + s := set.New(1, 2, 3, 4, 5) + + val := s.ToSlice() + fmt.Println(val) // [2 3 4 5 1] +} +``` + +### ToSortedSlice + +以切片的形式返回集合中所有的元素(按给定的规则排序)
+ +函数签名: + +```go +func (s Set[T]) ToSortedSlice() (v T, ok bool) +``` + +示例: + +```go +func main() { + s1 := set.New(1, 2, 3, 4, 5) + type Person struct { + Name string + Age int + } + s2 := FromSlice([]Person{{"Tom", 20}, {"Jerry", 18}, {"Spike", 25}}) + + res1 := s1.ToSortedSlice(func(v1, v2 int) bool { + return v1 < v2 + }) + + res2 := s2.ToSortedSlice(func(v1, v2 Person) bool { + return v1.Age < v2.Age + }) + + fmt.Println(res1) // [1 2 3 4 5] + fmt.Println(res2) // [{Jerry 18} {Tom 20} {Spike 25}] +} +``` diff --git a/docs/api/packages/datastructure/stack.md b/docs/api/packages/datastructure/stack.md new file mode 100644 index 00000000..3f044e4d --- /dev/null +++ b/docs/api/packages/datastructure/stack.md @@ -0,0 +1,611 @@ +# Stack +栈数据结构,包括ArrayStack(数组栈)和LinkedStack(链表栈)。 + + + +## 源码 + +- [https://github.com/duke-git/lancet/blob/main/datastructure/stack/arraystack.go](https://github.com/duke-git/lancet/blob/main/datastructure/stack/arraystack.go) +- [https://github.com/duke-git/lancet/blob/main/datastructure/stack/linkedstack.go](https://github.com/duke-git/lancet/blob/main/datastructure/stack/linkedstack.go) + + + + +## 用法 +```go +import ( + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) +``` + + + +## 目录 + +### 1. ArrayStack(数组栈) + +- [NewArrayStack](#NewArrayStack) +- [Push](#ArrayStack_Push) +- [Pop](#ArrayStack_Pop) +- [Peak](#ArrayStack_Peak) +- [Data](#ArrayStack_Data) +- [Size](#ArrayStack_Size) +- [IsEmpty](#ArrayStack_IsEmpty) +- [Clear](#ArrayStack_Clear) + +### 2. LinkedStack(链表栈) + +- [NewLinkedStack](#NewLinkedStack) +- [Push](#LinkedStack_Push) +- [Pop](#LinkedStack_Pop) +- [Peak](#LinkedStack_Peak) +- [Data](#LinkedStack_Data) +- [Size](#LinkedStack_Size) +- [IsEmpty](#LinkedStack_IsEmpty) +- [Clear](#LinkedStack_Clear) +- [Print](#LinkedStack_Print) + + + +## 文档 + +### 1. ArrayStack +用切片实现栈结构 + +### NewArrayStack +返回ArrayStack指针实例
+ +函数签名: + +```go +type ArrayStack[T any] struct { + data []T + length int +} +func NewArrayStack[T any]() *ArrayStack[T] +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + fmt.Println(sk) +} +``` + + + + +### Push +将元素加入数组栈
+ +函数签名: + +```go +func (s *ArrayStack[T]) Push(value T) +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.Data()) //[]int{3, 2, 1} +} +``` + + + + +### Pop +删除栈顶元素并返回该元素指针
+ +函数签名: + +```go +func (s *ArrayStack[T]) Pop() (*T, error) +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + val, err := sk.Pop() + fmt.Println(err) //nil + fmt.Println(*val) //3 + + fmt.Println(sk.Data()) //[]int{2, 1} +} +``` + + + + +### Peak +返回栈顶元素指针
+ +函数签名: + +```go +func (s *ArrayStack[T]) Peak() (*T, error) +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + val, err := sk.Peak() + fmt.Println(err) //nil + fmt.Println(*val) //3 + + fmt.Println(sk.Data()) //[]int{3, 2, 1} +} +``` + + + + +### Data +返回栈中所有元素组成的切片
+ +函数签名: + +```go +func (s *ArrayStack[T]) Data() []T +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.Data()) //[]int{3, 2, 1} +} +``` + + + + +### Size +返回栈中元素的数量
+ +函数签名: + +```go +func (s *ArrayStack[T]) Size() int +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.Size()) //3 +} +``` + + + + +### IsEmpty +判断栈是否为空
+ +函数签名: + +```go +func (s *ArrayStack[T]) IsEmpty() bool +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + fmt.Println(sk.IsEmpty()) //true + + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.IsEmpty()) //false +} +``` + + + + +### Clear +清空栈元素,使栈为空
+ +函数签名: + +```go +func (s *ArrayStack[T]) Clear() +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + + sk.Push(1) + sk.Push(2) + sk.Push(3) + + sk.Clear() + + fmt.Println(sk.Data()) //[]int{} +} +``` + + + +### 2. LinkedStack +链表实现的栈结构。 + +### NewLinkedStack +返回LinkedStack指针实例
+ +函数签名: + +```go +type StackNode[T any] struct { + Value T + Next *StackNode[T] +} +type LinkedStack[T any] struct { + top *datastructure.StackNode[T] + length int +} +func NewLinkedStack[T any]() *LinkedStack[T] +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + fmt.Println(sk) +} +``` + + + + +### Push +将元素加入链表栈
+ +函数签名: + +```go +func (s *LinkedStack[T]) Push(value T) +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.Data()) //[]int{3, 2, 1} +} +``` + + + + +### Pop +删除栈顶元素并返回该元素指针
+ +函数签名: + +```go +func (s *LinkedStack[T]) Pop() (*T, error) +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + val, err := sk.Pop() + fmt.Println(err) //nil + fmt.Println(*val) //3 + + fmt.Println(sk.Data()) //[]int{2, 1} +} +``` + + + + +### Peak +返回栈顶元素指针
+ +函数签名: + +```go +func (s *LinkedStack[T]) Peak() (*T, error) +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + val, err := sk.Peak() + fmt.Println(err) //nil + fmt.Println(*val) //3 + + fmt.Println(sk.Data()) //[]int{3, 2, 1} +} +``` + + + + +### Data +返回栈中所有元素组成的切片
+ +函数签名: + +```go +func (s *LinkedStack[T]) Data() []T +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.Data()) //[]int{3, 2, 1} +} +``` + + + + +### Size +返回栈中元素的数量
+ +函数签名: + +```go +func (s *LinkedStack[T]) Size() int +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.Size()) //3 +} +``` + + + + +### IsEmpty +判断栈是否为空
+ +函数签名: + +```go +func (s *LinkedStack[T]) IsEmpty() bool +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + fmt.Println(sk.IsEmpty()) //true + + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.IsEmpty()) //false +} +``` + + + + +### Clear +清空栈元素,使栈为空
+ +函数签名: + +```go +func (s *LinkedStack[T]) Clear() +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + + sk.Push(1) + sk.Push(2) + sk.Push(3) + + sk.Clear() + + fmt.Println(sk.Data()) //[]int{} +} +``` + + + + +### Print +打印链表栈结构
+ +函数签名: + +```go +func (s *LinkedStack[T]) Print() +``` +示例: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + + sk.Push(1) + sk.Push(2) + sk.Push(3) + + + sk.Print() //[ &{Value:3 Next:0xc000010260}, &{Value:2 Next:0xc000010250}, &{Value:1 Next:返回BSTree指针实例
+ +函数签名: + +```go +func NewBSTree[T any](rootData T, comparator constraints.Comparator) *BSTree[T] + +type BSTree[T any] struct { + root *datastructure.TreeNode[T] + comparator constraints.Comparator +} + +type TreeNode[T any] struct { + Value T + Left *TreeNode[T] + Right *TreeNode[T] +} +``` +示例: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + fmt.Println(bstree) // +} +``` + + + + +### Insert +将值插入二叉搜索树
+ +函数签名: + +```go +func (t *BSTree[T]) Insert(data T) +``` +示例: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.PreOrderTraverse()) //6, 5, 2, 4, 7 +} +``` + + + + +### Delete +删除插入二叉搜索树中指定的值
+ +函数签名: + +```go +func (t *BSTree[T]) Delete(data T) +``` +示例: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + bstree.Delete(4) + + fmt.Println(bstree.PreOrderTraverse()) //2, 5, 6, 7 +} +``` + + + + +### PreOrderTraverse +按前序遍历树节点
+ +函数签名: + +```go +func (t *BSTree[T]) PreOrderTraverse() []T +``` +示例: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.PreOrderTraverse()) //6, 5, 2, 4, 7 +} +``` + + + + +### InOrderTraverse +按中序遍历树节点
+ +函数签名: + +```go +func (t *BSTree[T]) InOrderTraverse() []T +``` +示例: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.InOrderTraverse()) //2, 4, 5, 6, 7 +} +``` + + + + +### PostOrderTraverse +按后序遍历树节点
+ +函数签名: + +```go +func (t *BSTree[T]) PostOrderTraverse() []T +``` +示例: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.PostOrderTraverse()) //5, 2, 4, 7, 6 +} +``` + + + + +### LevelOrderTraverse +按节点层次遍历树节点
+ +函数签名: + +```go +func (t *BSTree[T]) LevelOrderTraverse() []T +``` +示例: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.LevelOrderTraverse()) //6, 5, 7, 2, 4 +} +``` + + + + +### Depth +获取树的深度
+ +函数签名: + +```go +func (t *BSTree[T]) Depth() int +``` +示例: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.Depth()) //4 +} +``` + + + + +### HasSubTree +判断给定树是否是子树
+ +函数签名: + +```go +func (t *BSTree[T]) HasSubTree(subTree *BSTree[T]) bool +``` +示例: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + superTree := tree.NewBSTree(8, &intComparator{}) + superTree.Insert(4) + superTree.Insert(5) + superTree.Insert(6) + superTree.Insert(9) + superTree.Insert(4) + + subTree := tree.NewBSTree(5, &intComparator{}) + subTree.Insert(4) + subTree.Insert(6) + + fmt.Println(superTree.HasSubTree(subTree)) //true + fmt.Println(subTree.HasSubTree(superTree)) //false +} +``` + + + + +### Print +打印树结构
+ +函数签名: + +```go +func (t *BSTree[T]) Print() +``` +示例: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.Print()) +// 6 +// / \ +// / \ +// / \ +// / \ +// 5 7 +// / +// / +// 2 +// \ +// 4 +} +``` \ No newline at end of file diff --git a/docs/api/packages/datetime.md b/docs/api/packages/datetime.md new file mode 100644 index 00000000..28c984d4 --- /dev/null +++ b/docs/api/packages/datetime.md @@ -0,0 +1,1853 @@ +# Datetime + +datetime 日期时间处理包,格式化日期,比较日期。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/datetime" +) +``` + + + +## 目录 + +- [AddDay](#AddDay) +- [AddWeek](#AddWeek) +- [AddMonth](#AddMonth) +- [AddHour](#AddHour) +- [AddMinute](#AddMinute) +- [AddYear](#AddYear) +- [AddDaySafe](#AddDaySafe) +- [AddMonthSafe](#AddMonthSafe) +- [AddYearSafe](#AddYearSafe) +- [BeginOfMinute](#BeginOfMinute) +- [BeginOfHour](#BeginOfHour) +- [BeginOfDay](#BeginOfDay) +- [BeginOfWeek](#BeginOfWeek) +- [BeginOfMonth](#BeginOfMonth) +- [BeginOfYear](#BeginOfYear) +- [EndOfMinute](#EndOfMinute) +- [EndOfHour](#EndOfHour) +- [EndOfDay](#EndOfDay) +- [EndOfWeek](#EndOfWeek) +- [EndOfMonth](#EndOfMonth) +- [EndOfYear](#EndOfYear) +- [GetNowDate](#GetNowDate) +- [GetNowTime](#GetNowTime) +- [GetNowDateTime](#GetNowDateTime) +- [GetTodayStartTime](#GetTodayStartTime) +- [GetTodayEndTime](#GetTodayEndTime) +- [GetZeroHourTimestamp](#GetZeroHourTimestamp) +- [GetNightTimestamp](#GetNightTimestamp) +- [FormatTimeToStr](#FormatTimeToStr) +- [FormatStrToTime](#FormatStrToTime) +- [NewUnixNow](#NewUnixNow) +- [NewUnix](#NewUnix) +- [NewFormat](#NewFormat) +- [NewISO8601](#NewISO8601) +- [ToUnix](#ToUnix) +- [ToFormat](#ToFormat) +- [ToFormatForTpl](#ToFormatForTpl) +- [ToIso8601](#ToIso8601) +- [IsLeapYear](#IsLeapYear) +- [BetweenSeconds](#BetweenSeconds) +- [DayOfYear](#DayOfYear) +- [IsWeekenddeprecated](#IsWeekend) +- [NowDateOrTime](#NowDateOrTime) +- [Timestamp](#Timestamp) +- [TimestampMilli](#TimestampMilli) +- [TimestampMicro](#TimestampMicro) +- [TimestampNano](#TimestampNano) +- [TrackFuncTime](#TrackFuncTime) +- [DaysBetween](#DaysBetween) +- [GenerateDatetimesBetween](#GenerateDatetimesBetween) +- [Min](#Min) +- [Max](#Max) +- [MaxMin](#MaxMin) + + + +## 文档 + +## 注: + +1. 函数中`format`参数值需要传以下值之一 (忽略大小写): + +- yyyy-mm-dd hh:mm:ss +- yyyy-mm-dd hh:mm +- yyyy-mm-dd hh +- yyyy-mm-dd +- yyyy-mm +- mm-dd +- dd-mm-yy hh:mm:ss +- yyyy/mm/dd hh:mm:ss +- yyyy/mm/dd hh:mm +- yyyy/mm/dd hh +- yyyy/mm/dd +- yyyy/mm +- mm/dd +- dd/mm/yy hh:mm:ss +- yyyymmdd +- mmddyy +- yyyy +- yy +- mm +- hh:mm:ss +- hh:mm +- mm:ss + +### AddDay + +将日期加/减天数。
+ +函数签名: + +```go +func AddDay(t time.Time, days int64) time.Time +``` + +示例:[运行](https://go.dev/play/p/dIGbs_uTdFa) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00") + + after1Day := datetime.AddDay(date, 1) + before1Day := datetime.AddDay(date, -1) + + fmt.Println(after1Day.Format("2006-01-02 15:04:05")) + fmt.Println(before1Day.Format("2006-01-02 15:04:05")) + + // Output: + // 2021-01-02 00:00:00 + // 2020-12-31 00:00:00 +} +``` + +### AddWeek + +将日期加/减星期数。
+ +函数签名: + +```go +func AddWeek(t time.Time, weeks int64) time.Time +``` + +示例:[运行](https://go.dev/play/p/M9TqdMiaA2p) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02", "2021-01-01") + + after2Weeks := datetime.AddWeek(date, 2) + before2Weeks := datetime.AddWeek(date, -2) + + fmt.Println(after2Weeks.Format("2006-01-02")) + fmt.Println(before2Weeks.Format("2006-01-02")) + + // Output: + // 2021-01-15 + // 2020-12-18 +} +``` + +### AddMonth + +将日期加/减月数。
+ +函数签名: + +```go +func AddMonth(t time.Time, months int64) time.Time +``` + +示例:[运行](https://go.dev/play/p/DLoiOnpLvsN) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02", "2021-01-01") + + after2Months := datetime.AddMonth(date, 2) + before2Months := datetime.AddMonth(date, -2) + + fmt.Println(after2Months.Format("2006-01-02")) + fmt.Println(before2Months.Format("2006-01-02")) + + // Output: + // 2021-03-01 + // 2020-11-01 +} +``` + +### AddHour + +将日期加/减小时数。
+ +函数签名: + +```go +func AddHour(t time.Time, hours int64) time.Time +``` + +示例:[运行](https://go.dev/play/p/rcMjd7OCsi5) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00") + + after2Hours := datetime.AddHour(date, 2) + before2Hours := datetime.AddHour(date, -2) + + fmt.Println(after2Hours.Format("2006-01-02 15:04:05")) + fmt.Println(before2Hours.Format("2006-01-02 15:04:05")) + + // Output: + // 2021-01-01 02:00:00 + // 2020-12-31 22:00:00 +} +``` + +### AddMinute + +将日期加/减分钟数。
+ +函数签名: + +```go +func AddMinute(t time.Time, minutes int64) time.Time +``` + +示例:[运行](https://go.dev/play/p/nT1heB1KUUK) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00") + + after2Minutes := datetime.AddMinute(date, 2) + before2Minutes := datetime.AddMinute(date, -2) + + fmt.Println(after2Minutes.Format("2006-01-02 15:04:05")) + fmt.Println(before2Minutes.Format("2006-01-02 15:04:05")) + + // Output: + // 2021-01-01 00:02:00 + // 2020-12-31 23:58:00 +} +``` + +### AddYear + +将日期加/减年数。
+ +函数签名: + +```go +func AddYear(t time.Time, years int64) time.Time +``` + +示例:[运行](https://go.dev/play/p/MqW2ujnBx10) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02", "2021-01-01") + + after2Years := AddYear(date, 2) + before2Years := AddYear(date, -2) + + fmt.Println(after2Years.Format("2006-01-02")) + fmt.Println(before2Years.Format("2006-01-02")) + + // Output: + // 2023-01-01 + // 2019-01-01 +} +``` + +### AddDaySafe + +增加/减少指定的天数,并确保日期是有效日期。
+ +函数签名: + +```go +func AddDaySafe(t time.Time, days int) time.Time +``` + +示例:[运行](https://go.dev/play/p/JTohZFpoDJ3) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + leapYearDate1, _ := time.Parse("2006-01-02", "2024-02-29") + result1 := datetime.AddDaySafe(leapYearDate1, 1) + + leapYearDate2, _ := time.Parse("2006-01-02", "2024-03-01") + result2 := datetime.AddDaySafe(leapYearDate2, -1) + + nonLeapYearDate1, _ := time.Parse("2006-01-02", "2025-02-28") + result3 := datetime.AddDaySafe(nonLeapYearDate1, 1) + + nonLeaYearDate2, _ := time.Parse("2006-01-02", "2025-03-01") + result4 := datetime.AddDaySafe(nonLeaYearDate2, -1) + + fmt.Println(result1.Format("2006-01-02")) + fmt.Println(result2.Format("2006-01-02")) + fmt.Println(result3.Format("2006-01-02")) + fmt.Println(result4.Format("2006-01-02")) + + // Output: + // 2024-03-01 + // 2024-02-29 + // 2025-03-01 + // 2025-02-28 +} +``` + +### AddMonthSafe + +增加/减少指定的月份,并确保日期是有效日期。
+ +函数签名: + +```go +func AddMonthSafe(t time.Time, months int) time.Time +``` + +示例:[运行](https://go.dev/play/p/KLw0lo6mbVW) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date1, _ := time.Parse("2006-01-02", "2025-01-31") + result1 := datetime.AddMonthSafe(date1, 1) + + date2, _ := time.Parse("2006-01-02", "2024-02-29") + result2 := datetime.AddMonthSafe(date2, -1) + + fmt.Println(result1.Format("2006-01-02")) + fmt.Println(result2.Format("2006-01-02")) + + // Output: + // 2025-02-28 + // 2024-01-29 +} +``` + +### AddYearSafe + +增加/减少指定的年份,并确保日期是有效日期。
+ +函数签名: + +```go +func AddYearSafe(t time.Time, years int) time.Time +``` + +示例:[运行](https://go.dev/play/p/KVGXWZZ54ZH) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02", "2020-02-29") + + result1 := datetime.AddYearSafe(date, 1) + result2 := datetime.AddYearSafe(date, -1) + + fmt.Println(result1.Format("2006-01-02")) + fmt.Println(result2.Format("2006-01-02")) + + // Output: + // 2021-02-28 + // 2019-02-28 +} +``` + +### BeginOfMinute + +返回指定时间的分钟开始时间。
+ +函数签名: + +```go +func BeginOfMinute(t time.Time) time.Time +``` + +示例:[运行](https://go.dev/play/p/ieOLVJ9CiFT) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.BeginOfMinute(input) + + fmt.Println(result) + + // Output: + // 2023-01-08 18:50:00 +0000 UTC +} +``` + +### BeginOfHour + +返回指定时间的小时开始时间。
+ +函数签名: + +```go +func BeginOfHour(t time.Time) time.Time +``` + +示例:[运行](https://go.dev/play/p/GhdGFnDWpYs) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.BeginOfHour(input) + + fmt.Println(result) + + // Output: + // 2023-01-08 18:00:00 +0000 UTC +} +``` + +### BeginOfDay + +返回指定时间的当天开始时间。
+ +函数签名: + +```go +func BeginOfDay(t time.Time) time.Time +``` + +示例:[运行](https://go.dev/play/p/94m_UT6cWs9) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.BeginOfDay(input) + + fmt.Println(result) + + // Output: + // 2023-01-08 00:00:00 +0000 UTC +} +``` + +### BeginOfWeek + +返回指定时间的每周开始时间,默认开始时间星期日。
+ +函数签名: + +```go +func BeginOfWeek(t time.Time, beginFrom time.Weekday) time.Time +``` + +示例:[运行](https://go.dev/play/p/ynjoJPz7VNV) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.BeginOfWeek(input, time.Monday) + + fmt.Println(result) + + // Output: + // 2023-01-09 00:00:00 +0000 UTC +} +``` + +### BeginOfMonth + +返回指定时间的当月开始时间。
+ +函数签名: + +```go +func BeginOfMonth(t time.Time) time.Time +``` + +示例:[运行](https://go.dev/play/p/bWXVFsmmzwL) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.BeginOfMonth(input) + + fmt.Println(result) + + // Output: + // 2023-01-01 00:00:00 +0000 UTC +} +``` + +### BeginOfYear + +返回指定时间的当年开始时间
+ +函数签名: + +```go +func BeginOfYear(t time.Time) time.Time +``` + +示例:[运行](https://go.dev/play/p/i326DSwLnV8) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.BeginOfYear(input) + + fmt.Println(result) + + // Output: + // 2023-01-01 00:00:00 +0000 UTC +} +``` + +### EndOfMinute + +返回指定时间的分钟结束时间。
+ +函数签名: + +```go +func EndOfMinute(t time.Time) time.Time +``` + +示例:[运行](https://go.dev/play/p/yrL5wGzPj4z) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.EndOfMinute(input) + + fmt.Println(result) + + // Output: + // 2023-01-08 18:50:59.999999999 +0000 UTC +} +``` + +### EndOfHour + +返回指定时间的小时结束时间。
+ +函数签名: + +```go +func EndOfHour(t time.Time) time.Time +``` + +示例:[运行](https://go.dev/play/p/6ce3j_6cVqN) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.EndOfHour(input) + + fmt.Println(result) + + // Output: + // 2023-01-08 18:59:59.999999999 +0000 UTC +} +``` + +### EndOfDay + +返回指定时间的当天结束时间。
+ +函数签名: + +```go +func EndOfDay(t time.Time) time.Time +``` + +示例:[运行](https://go.dev/play/p/eMBOvmq5Ih1) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.EndOfDay(input) + + fmt.Println(result) + + // Output: + // 2023-01-02 00:00:00 +0000 UTC +} +``` + +### EndOfWeek + +返回指定时间的星期结束时间,默认结束时间星期六。
+ +函数签名: + +```go +func EndOfWeek(t time.Time, endWith time.Weekday) time.Time +``` + +示例:[运行](https://go.dev/play/p/mGSA162YgX9) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.EndOfWeek(input, time.Sunday) + + fmt.Println(result) + + // Output: + // 2023-01-08 23:59:59.999999999 +0000 UTC +} +``` + +### EndOfMonth + +返回指定时间的当月结束时间。
+ +函数签名: + +```go +func EndOfMonth(t time.Time) time.Time +``` + +示例:[运行](https://go.dev/play/p/_GWh10B3Nqi) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.EndOfMonth(input) + + fmt.Println(result) + + // Output: + // 2023-01-31 23:59:59.999999999 +0000 UTC +} +``` + +### EndOfYear + +返回指定时间的当年结束时间。
+ +函数签名: + +```go +func EndOfYear(t time.Time) time.Time +``` + +示例:[运行](https://go.dev/play/p/G01cKlMCvNm) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.EndOfYear(input) + + fmt.Println(result) + + // Output: + // 2023-12-31 23:59:59.999999999 +0000 UTC +} +``` + +### GetNowDate + +获取当天日期,返回格式:yyyy-mm-dd。
+ +函数签名: + +```go +func GetNowDate() string +``` + +示例:[运行](https://go.dev/play/p/PvfkPpcpBBf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + currentDate := datetime.GetNowDate() + fmt.Println(currentDate) + + // Output: + // 2022-01-28 +} +``` + +### GetNowTime + +获取当时时间,返回格式:hh:mm:ss
+ +函数签名: + +```go +func GetNowTime() string +``` + +示例:[运行](https://go.dev/play/p/l7BNxCkTmJS) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + currentTime := datetime.GetNowTime() + fmt.Println(currentTime) + + // Output: + // 15:57:33 +} +``` + +### GetNowDateTime + +获取当时日期和时间,返回格式:yyyy-mm-dd hh:mm:ss。
+ +函数签名: + +```go +func GetNowDateTime() string +``` + +示例:[运行](https://go.dev/play/p/pI4AqngD0al) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + current := datetime.GetNowDateTime() + fmt.Println(current) + + // Output: + // 2022-01-28 15:59:33 +} +``` + +### GetTodayStartTime + +返回当天开始时间, 格式: yyyy-mm-dd 00:00:00。
+ +函数签名: + +```go +func GetTodayStartTime() string +``` + +示例:[运行](https://go.dev/play/p/84siyYF7t99) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + startTime := datetime.GetTodayStartTime() + fmt.Println(startTime) + + // Output: + // 2023-06-29 00:00:00 +} +``` + +### GetTodayEndTime + +返回当天结束时间,格式: yyyy-mm-dd 23:59:59。
+ +函数签名: + +```go +func GetTodayEndTime() string +``` + +示例:[运行](https://go.dev/play/p/jjrLnfoqgn3) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + endTime := datetime.GetTodayEndTime() + fmt.Println(endTime) + + // Output: + // 2023-06-29 23:59:59 +} +``` + +### GetZeroHourTimestamp + +获取零点时间戳(timestamp of 00:00)
+ +函数签名: + +```go +func GetZeroHourTimestamp() int64 +``` + +示例:[运行](https://go.dev/play/p/QmL2oIaGE3q) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + zeroTime := datetime.GetZeroHourTimestamp() + fmt.Println(zeroTime) + + // Output: + // 1643299200 +} +``` + +### GetNightTimestamp + +获取午夜时间戳(timestamp of 23:59)。
+ +函数签名: + +```go +func GetNightTimestamp() int64 +``` + +示例:[运行](https://go.dev/play/p/UolysR3MYP1) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + nightTime := datetime.GetNightTimestamp() + fmt.Println(nightTime) + + // Output: + // 1643385599 +} +``` + +### FormatTimeToStr + +将日期格式化成字符串,`format` 参数格式参考注1。
+ +函数签名: + +```go +func FormatTimeToStr(t time.Time, format string, timezone ...string) string +``` + +示例:[运行](https://go.dev/play/p/_Ia7M8H_OvE) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + t, _ := time.Parse("2006-01-02 15:04:05", "2021-01-02 16:04:08") + + result1 := datetime.FormatTimeToStr(t, "yyyy-mm-dd hh:mm:ss") + result2 := datetime.FormatTimeToStr(t, "yyyy-mm-dd") + result3 := datetime.FormatTimeToStr(t, "dd-mm-yy hh:mm:ss") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 2021-01-02 16:04:08 + // 2021-01-02 + // 02-01-21 16:04:08 +} +``` + +### FormatStrToTime + +将字符串格式化成时间,`format` 参数格式参考注1。
+ +函数签名: + +```go +func FormatStrToTime(str, format string, timezone ...string) (time.Time, error) +``` + +示例:[运行](https://go.dev/play/p/1h9FwdU8ql4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + result1, _ := datetime.FormatStrToTime("2021-01-02 16:04:08", "yyyy-mm-dd hh:mm:ss") + result2, _ := datetime.FormatStrToTime("2021-01-02", "yyyy-mm-dd") + result3, _ := datetime.FormatStrToTime("02-01-21 16:04:08", "dd-mm-yy hh:mm:ss") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 2021-01-02 16:04:08 +0000 UTC + // 2021-01-02 00:00:00 +0000 UTC + // 2021-01-02 16:04:08 +0000 UTC +} +``` + +### NewUnixNow + +创建一个当前时间的unix时间戳。
+ +函数签名: + +```go +type theTime struct { + unix int64 +} +func NewUnixNow() *theTime +``` + +示例:[运行](https://go.dev/play/p/U4PPx-9D0oz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm := datetime.NewUnixNow() + fmt.Println(tm) + + // Output: + // &{1647597438} +} +``` + +### NewUnix + +创建一个unix时间戳。
+ +函数签名: + +```go +type theTime struct { + unix int64 +} +func NewUnix(unix int64) *theTime +``` + +示例:[运行](https://go.dev/play/p/psoSuh_kLRt) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm := datetime.NewUnix(1647597438) + fmt.Println(tm) + + // Output: + // &{1647597438} +} +``` + +### NewFormat + +创建一个yyyy-mm-dd hh:mm:ss格式时间字符串的unix时间戳。
+ +函数签名: + +```go +type theTime struct { + unix int64 +} +func NewFormat(t string) (*theTime, error) +``` + +示例:[运行](https://go.dev/play/p/VkW08ZOaXPZ) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm, err := datetime.NewFormat("2022-03-18 17:04:05") + fmt.Println(tm) + + // Output: + // &{1647594245} +} +``` + +### NewISO8601 + +创建一个iso8601格式时间字符串的unix时间戳。
+ +函数签名: + +```go +type theTime struct { + unix int64 +} +func NewISO8601(iso8601 string) (*theTime, error) +``` + +示例:[运行](https://go.dev/play/p/mkhOHQkdeA2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm, err := datetime.NewISO8601("2006-01-02T15:04:05.999Z") + fmt.Println(tm) + + // Output: + // &{1136214245} +} +``` + +### ToUnix + +返回unix时间戳。
+ +函数签名: + +```go +func (t *theTime) ToUnix() int64 +``` + +示例:[运行](https://go.dev/play/p/_LUiwAdocjy) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm := datetime.NewUnixNow() + fmt.Println(tm.ToUnix()) + + // Output: + // 1647597438 +} +``` + +### ToFormat + +返回格式'yyyy-mm-dd hh:mm:ss'的日期字符串。
+ +函数签名: + +```go +func (t *theTime) ToFormat() string +``` + +示例:[运行](https://go.dev/play/p/VkW08ZOaXPZ) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm, _ := datetime.NewFormat("2022-03-18 17:04:05") + fmt.Println(tm.ToFormat()) + + // Output: + // 2022-03-18 17:04:05 +} +``` + +### ToFormatForTpl + +返回tpl格式指定的日期字符串。
+ +函数签名: + +```go +func (t *theTime) ToFormatForTpl(tpl string) string +``` + +示例:[运行](https://go.dev/play/p/nyXxXcQJ8L5) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm, _ := datetime.NewFormat("2022-03-18 17:04:05") + ts := tm.ToFormatForTpl("2006/01/02 15:04:05") + fmt.Println(ts) + + // Output: + // 2022/03/18 17:04:05 +} +``` + +### ToIso8601 + +返回iso8601日期字符串。
+ +函数签名: + +```go +func (t *theTime) ToIso8601() string +``` + +示例:[运行](https://go.dev/play/p/mkhOHQkdeA2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm, _ := datetime.NewISO8601("2006-01-02T15:04:05.999Z") + ts := tm.ToIso8601() + fmt.Println(ts) + + // Output: + // 2006-01-02T23:04:05+08:00 +} +``` + +### IsLeapYear + +验证是否是闰年。
+ +函数签名: + +```go +func IsLeapYear(year int) bool +``` + +示例:[运行](https://go.dev/play/p/xS1eS2ejGew) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + result1 := datetime.IsLeapYear(2000) + result2 := datetime.IsLeapYear(2001) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### BetweenSeconds + +返回两个时间的间隔秒数。
+ +函数签名: + +```go +func BetweenSeconds(t1 time.Time, t2 time.Time) int64 +``` + +示例:[运行](https://go.dev/play/p/n3YDRyfyXJu) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + today := time.Now() + tomorrow := datetime.AddDay(today, 1) + yesterday := datetime.AddDay(today, -1) + + result1 := datetime.BetweenSeconds(today, tomorrow) + result2 := datetime.BetweenSeconds(today, yesterday) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 86400 + // -86400 +} +``` + +### DayOfYear + +返回参数日期是一年中的第几天。
+ +函数签名: + +```go +func DayOfYear(t time.Time) int +``` + +示例:[运行](https://go.dev/play/p/0hjqhTwFNlH) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date1 := time.Date(2023, 02, 01, 1, 1, 1, 0, time.Local) + result1 := datetime.DayOfYear(date1) + + date2 := time.Date(2023, 01, 02, 1, 1, 1, 0, time.Local) + result2 := datetime.DayOfYear(date2) + + date3 := time.Date(2023, 01, 01, 1, 1, 1, 0, time.Local) + result3 := datetime.DayOfYear(date3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 31 + // 1 + // 0 +} +``` + +### IsWeekend(已废弃, 使用 '== Weekday') + +判断日期是否是周末。
+ +函数签名: + +```go +func IsWeekend(t time.Time) bool +``` + +示例:[运行](https://go.dev/play/p/cupRM5aZOIY) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date1 := time.Date(2023, 06, 03, 0, 0, 0, 0, time.Local) + date2 := time.Date(2023, 06, 04, 0, 0, 0, 0, time.Local) + date3 := time.Date(2023, 06, 02, 0, 0, 0, 0, time.Local) + + result1 := datetime.IsWeekend(date1) + result2 := datetime.IsWeekend(date2) + result3 := datetime.IsWeekend(date3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### NowDateOrTime + +根据指定的格式和时区返回当前时间字符串。
+ +函数签名: + +```go +func NowDateOrTime(format string, timezone ...string) string +``` + +示例:[运行](https://go.dev/play/p/EZ-begEjtT0) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + result1 := datetime.NowDateOrTime("yyyy-mm-dd hh:mm:ss") + + result2 := datetime.NowDateOrTime("yyyy-mm-dd hh:mm:ss", "EST") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 2023-07-26 15:01:30 + // 2023-07-26 02:01:30 +} +``` + +### Timestamp + +返回当前秒级时间戳。
+ +函数签名: + +```go +func Timestamp(timezone ...string) int64 +``` + +示例:[运行](https://go.dev/play/p/iU5b7Vvjx6x) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + ts := datetime.Timestamp() + + fmt.Println(ts) + + // Output: + // 1690363051 +} +``` + + +### TimestampMilli + +返回当前毫秒级时间戳。
+ +函数签名: + +```go +func TimestampMilli(timezone ...string) int64 +``` + +示例:[运行](https://go.dev/play/p/4gvEusOTu1T) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + ts := datetime.TimestampMilli() + + fmt.Println(ts) + + // Output: + // 1690363051331 +} +``` + +### TimestampMicro + +返回当前微秒级时间戳。
+ +函数签名: + +```go +func TimestampMicro(timezone ...string) int64 +``` + +示例:[运行](https://go.dev/play/p/2maANglKHQE) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + ts := datetime.TimestampMicro() + + fmt.Println(ts) + + // Output: + // 1690363051331784 +} +``` + +### TimestampNano + +返回当前纳秒级时间戳。
+ +函数签名: + +```go +func TimestampNano(timezone ...string) int64 +``` + +示例:[运行](https://go.dev/play/p/A9Oq_COrcCF) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + ts := datetime.TimestampNano() + + fmt.Println(ts) + + // Output: + // 1690363051331788000 +} +``` + +### TrackFuncTime + +测试函数执行时间。
+ +函数签名: + +```go +func TrackFuncTime(pre time.Time) func() +``` + +示例:[运行](https://go.dev/play/p/QBSEdfXHPTp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + defer datetime.TrackFuncTime(time.Now())() + + var n int + for i := 0; i < 5000000; i++ { + n++ + } + + fmt.Println(1) // Function main execution time: 1.460287ms +} +``` + +### DaysBetween + +返回两个日期之间的天数差。
+ +函数签名: + +```go +func DaysBetween(start, end time.Time) int +``` + +示例:[运行](https://go.dev/play/p/qD6qGb3TbOy) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + start := time.Date(2024, time.September, 1, 0, 0, 0, 0, time.UTC) + end := time.Date(2024, time.September, 10, 0, 0, 0, 0, time.UTC) + + result := datetime.DaysBetween(start, end) + + fmt.Println(result) + + // Output: + // 9 +} +``` + +### GenerateDatetimesBetween + +生成从start到end的所有日期时间的字符串列表。layout参数表示时间格式,例如"2006-01-02 15:04:05",interval参数表示时间间隔,例如"1h"表示1小时,"30m"表示30分钟。
+ +函数签名: + +```go +func GenerateDatetimesBetween(start, end time.Time, layout string, interval string) ([]string, error) +``` + +示例:[运行](https://go.dev/play/p/6kHBpAxD9ZC) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + start := time.Date(2024, time.September, 1, 0, 0, 0, 0, time.UTC) + end := time.Date(2024, time.September, 1, 2, 0, 0, 0, time.UTC) + + layout := "2006-01-02 15:04:05" + interval := "1h" + + result, err := datetime.GenerateDatetimesBetween(start, end, layout, interval) + + fmt.Println(result) + fmt.Println(err) + + // Output: + // [2024-09-01 00:00:00 2024-09-01 01:00:00 2024-09-01 02:00:00] + //返回最早时间。
+ +函数签名: + +```go +func Min(t1 time.Time, times ...time.Time) time.Time +``` + +示例:[运行](https://go.dev/play/p/MCIDvHNOGGb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + minTime := datetime.Min(time.Date(2024, time.September, 1, 0, 0, 0, 0, time.UTC), time.Date(2024, time.September, 2, 0, 0, 0, 0, time.UTC)) + + fmt.Println(minTime) + + // Output: + // 2024-09-01 00:00:00 +0000 UTC +} +``` + +### Max + +返回最晚时间。
+ +函数签名: + +```go +func Max(t1 time.Time, times ...time.Time) time.Time +``` + +示例:[运行](https://go.dev/play/p/9m6JMk1LB7-) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + maxTime := datetime.Min(time.Date(2024, time.September, 1, 0, 0, 0, 0, time.UTC), time.Date(2024, time.September, 2, 0, 0, 0, 0, time.UTC)) + + fmt.Println(maxTime) + + // Output: + // 2024-09-02 00:00:00 +0000 UTC +} +``` + +### MaxMin + +返回最早和最晚时间。
+ +函数签名: + +```go +func MaxMin(t1 time.Time, times ...time.Time) (maxTime time.Time, minTime time.Time) +``` + +示例:[运行](https://go.dev/play/p/rbW51cDtM_2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + max, min := datetime.MaxMin(time.Date(2024, time.September, 1, 0, 0, 0, 0, time.UTC), time.Date(2024, time.September, 2, 0, 0, 0, 0, time.UTC), time.Date(2024, time.September, 3, 0, 0, 0, 0, time.UTC)) + + fmt.Println(max) + fmt.Println(min) + + // Output: + // 2024-09-03 00:00:00 +0000 UTC + // 2024-09-01 00:00:00 +0000 UTC +} +``` \ No newline at end of file diff --git a/docs/api/packages/eventbus.md b/docs/api/packages/eventbus.md new file mode 100644 index 00000000..9d26304f --- /dev/null +++ b/docs/api/packages/eventbus.md @@ -0,0 +1,407 @@ +# EventBus + +EventbBus是一个事件总线,用于在应用程序中处理事件。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/eventbus/eventbus.go](https://github.com/duke-git/lancet/blob/main/eventbus/eventbus.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/eventbus" +) +``` + + + +## 目录 + +- [NewEventBus](#NewEventBus) +- [Subscribe](#Subscribe) +- [Unsubscribe](#Unsubscribe) +- [Publish](#Publish) +- [ClearListeners](#ClearListeners) +- [ClearListenersByTopic](#ClearListenersByTopic) +- [GetListenersCount](#GetListenersCount) +- [GetAllListenersCount](#GetAllListenersCount) +- [GetEvents](#GetEvents) +- [SetErrorHandler](#SetErrorHandler) + + + + +## 文档 + +### NewEventBus + +创建EventBus实例。
+ +函数签名: + +```go +func NewEventBus[T any]() *EventBus[T] +``` + +示例:[运行](https://go.dev/play/p/gHbOPV_NUOJ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 1 +} +``` + +### Subscribe + +订阅具有特定事件主题和监听函数的事件。支持异步,事件优先级,事件过滤器。
+ +函数签名: + +```go +func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async bool, priority int, filter func(eventData T) bool) +``` + +示例:[运行](https://go.dev/play/p/EYGf_8cHei-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + filter := func(eventData int) bool { + return eventData == 1 + } + + eb.Subscribe("event1", listener, false, 0, filter) + + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 2}) + + fmt.Println(receivedData) + + // Output: + // 1 +} +``` + +### Unsubscribe + +取消订阅具有特定事件主题的事件。
+ +函数签名: + +```go +func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T)) +``` + +示例:[运行](https://go.dev/play/p/Tmh7Ttfvprf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Unsubscribe("event1", listener) + + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 0 +} +``` + +### Publish + +发布一个带有特定事件主题和数据负载的事件。
+ +函数签名: + +```go +func (eb *EventBus[T]) Publish(event eventbus.Event[T]) +``` + +示例:[运行](https://go.dev/play/p/gHTtVexFSH9) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) { + fmt.Println(eventData) + }, false, 0, nil) + + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // 1 +} +``` + +### ClearListeners + +清空所有事件监听器。
+ +函数签名: + +```go +func (eb *EventBus[T]) ClearListeners() +``` + +示例:[运行](https://go.dev/play/p/KBfBYlKPgqD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Subscribe("event2", listener, false, 0, nil) + + eb.ClearListeners() + + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(eventbus.Event[int]{Topic: "event2", Payload: 2}) + + fmt.Println(receivedData) + + // Output: + // 0 +} +``` + +### ClearListenersByTopic + +清空特定事件监听器。
+ +函数签名: + +```go +func (eb *EventBus[T]) ClearListenersByTopic(topic string) +``` + +示例:[运行](https://go.dev/play/p/gvMljmJOZmU) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Subscribe("event2", listener, false, 0, nil) + + eb.ClearListenersByTopic("event1") + + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(eventbus.Event[int]{Topic: "event2", Payload: 2}) + + fmt.Println(receivedData) + + // Output: + // 2 +} +``` + +### GetListenersCount + +获取特定事件的监听器数量。
+ +函数签名: + +```go +func (eb *EventBus[T]) GetListenersCount(topic string) int +``` + +示例:[运行](https://go.dev/play/p/j6yaJ2xAmFz) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + count := eb.GetListenersCount("event1") + + fmt.Println(count) + + // Output: + // 1 +} +``` + +### GetAllListenersCount + +获取所有事件的监听器数量。
+ +函数签名: + +```go +func (eb *EventBus[T]) GetAllListenersCount() int +``` + +示例:[运行](https://go.dev/play/p/PUlr0xcpEOz) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + count := eb.GetAllListenersCount() + + fmt.Println(count) + + // Output: + // 2 +} +``` + +### GetEvents + +获取所有事件的topic。
+ +函数签名: + +```go +func (eb *EventBus[T]) GetEvents() []string +``` + +示例:[运行](https://go.dev/play/p/etgjjcOtAjX) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + events := eb.GetEvents() + + for _, event := range events { + fmt.Println(event) + } + + // Output: + // event2 + // event1 +} +``` + +### SetErrorHandler + +设置事件的错误处理函数。
+ +函数签名: + +```go +func (eb *EventBus[T]) SetErrorHandler(handler func(err error)) +``` + +示例:[运行](https://go.dev/play/p/gmB0gnFe5mc) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.SetErrorHandler(func(err error) { + fmt.Println(err) + }) + + eb.Subscribe("event1", func(eventData int) { + panic("error") + }, false, 0, nil) + + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // error +} +``` \ No newline at end of file diff --git a/docs/api/packages/fileutil.md b/docs/api/packages/fileutil.md new file mode 100644 index 00000000..8cee0bec --- /dev/null +++ b/docs/api/packages/fileutil.md @@ -0,0 +1,1147 @@ +# Fileutil + +fileutil 包支持文件基本操作。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/fileutil" +) +``` + + + +## 目录 + +- [ClearFile](#ClearFile) +- [CreateFile](#CreateFile) +- [CreateDir](#CreateDir) +- [CopyFile](#CopyFile) +- [CopyDir](#CopyDir) +- [CurrentPath](#CurrentPath) +- [FileMode](#FileMode) +- [MiMeType](#MiMeType) +- [IsExist](#IsExist) +- [IsLink](#IsLink) +- [IsDir](#IsDir) +- [ListFileNames](#ListFileNames) +- [RemoveFile](#RemoveFile) +- [RemoveDir](#RemoveDir) +- [ReadFileToString](#ReadFileToString) +- [ReadFileByLine](#ReadFileByLine) +- [Zip](#Zip) +- [ZipAppendEntry](#ZipAppendEntry) +- [UnZip](#UnZip) +- [IsZipFile](#IsZipFile) +- [FileSize](#FileSize) +- [MTime](#MTime) +- [Sha](#Sha) +- [ReadCsvFile](#ReadCsvFile) +- [WriteCsvFile](#WriteCsvFile) +- [WriteMapsToCsv](#WriteMapsToCsv) +- [WriteStringToFile](#WriteStringToFile) +- [WriteBytesToFile](#WriteBytesToFile) +- [ReadFile](#ReadFile) +- [ChunkRead](#ChunkRead) +- [ParallelChunkRead](#ParallelChunkRead) +- [GetExeOrDllVersion](#GetExeOrDllVersion) + + + +## 文档 + +### ClearFile + +清空文件内容
+ +函数签名: + +```go +func ClearFile(path string) error +``` + +示例:[运行](https://go.dev/play/p/NRZ0ZT-G94H) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.ClearFile("./test.txt") + if err != nil { + fmt.Println(err) + } +} +``` + +### CreateFile + +创建文件,创建成功返回true, 否则返回false
+ +函数签名: + +```go +func CreateFile(path string) bool +``` + +示例:[运行](https://go.dev/play/p/lDt8PEsTNKI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + isCreatedSucceed := fileutil.CreateFile("./test.txt") + fmt.Println(isCreatedSucceed) +} +``` + +### CreateDir + +使用绝对路径创建嵌套目录,例如/a/, /a/b
+ +函数签名: + +```go +func CreateDir(absPath string) error +``` + +示例:[运行](https://go.dev/play/p/qUuCe1OGQnM) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.CreateDir("/a/b") // will create folder /a/b + fmt.Println(err) +} +``` + +### CopyFile + +拷贝文件,会覆盖原有的文件
+ +函数签名: + +```go +func CopyFile(srcPath string, dstPath string) error +``` + +示例:[运行](https://go.dev/play/p/Jg9AMJMLrJi) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.CopyFile("./test.txt", "./test_copy.txt") + if err != nil { + fmt.Println(err) + } +} +``` + +### CopyDir + +拷贝文件夹到目标路径,会递归复制文件夹下所有的文件及文件夹,并且访问权限也与源文件夹保持一致。当dstPath存在时会返回error
+ +函数签名: + +```go +func CopyDir(srcPath string, dstPath string) error +``` + +示例:[运行](https://go.dev/play/p/YAyFTA_UuPb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.CopyFile("./test_src", "./test_dest") + if err != nil { + fmt.Println(err) + } +} +``` + +### CurrentPath + +返回当前位置的绝对路径。
+ +函数签名: + +```go +func CurrentPath() string +``` + +示例:[运行](https://go.dev/play/p/s74a9iBGcSw) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + absPath := CurrentPath() + fmt.Println(absPath) +} +``` + +### FileMode + +获取文件mode信息
+ +函数签名: + +```go +func FileMode(path string) (fs.FileMode, error) +``` + +示例:[运行](https://go.dev/play/p/2l2hI42fA3p) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + mode, err := fileutil.FileMode("./test.txt") + if err != nil { + fmt.Println(err) + } + fmt.Println(mode) +} +``` + +### MiMeType + +获取文件mime类型, 'file'参数的类型必须是string或者*os.File
+ +函数签名: + +```go +func MiMeType(file any) string +``` + +示例:[运行](https://go.dev/play/p/bd5sevSUZNu) + +```go +package main + +import ( + "fmt" + "os" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + type1 := fileutil.MiMeType("./test.txt") + fmt.Println(type1) //text/plain; charset=utf-8 + + f, _ := os.Open("./file.go") + type2 := fileutil.MiMeType(f) + fmt.Println(type2) //text/plain; charset=utf-8 +} +``` + +### IsExist + +判断文件或目录是否存在
+ +函数签名: + +```go +func IsExist(path string) bool +``` + +示例:[运行](https://go.dev/play/p/nKKXt8ZQbmh) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + fileutil.CreateFile("./test.txt") + isFileExist := fileutil.IsExist("./test.txt") + fmt.Println(isFileExist) //true +} +``` + +### IsLink + +判断文件是否是符号链接
+ +函数签名: + +```go +func IsLink(path string) bool +``` + +示例:[运行](https://go.dev/play/p/TL-b-Kzvf44) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + isLinkFile := fileutil.IsLink("./test.txt") + fmt.Println(isLinkFile) //false +} +``` + +### IsDir + +判断参数是否是目录
+ +函数签名: + +```go +func IsDir(path string) bool +``` + +示例:[运行](https://go.dev/play/p/WkVwEKqtOWk) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + isDir := fileutil.IsDir("./") + fmt.Println(isDir) //true + + isDir = fileutil.IsDir("./test.txt") + fmt.Println(isDir) //false +} +``` + +### ListFileNames + +返回目录下所有文件名
+ +函数签名: + +```go +func ListFileNames(path string) ([]string, error) +``` + +示例:[运行](https://go.dev/play/p/Tjd7Y07rejl) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + fileNames, _ := fileutil.ListFileNames("./") + fmt.Println(fileNames) +} +``` + +### RemoveFile + +删除文件,支持传入删除前的回调函数。
+ +函数签名: + +```go +func RemoveFile(path string, onDelete ...func(path string)) error +``` + +示例:[运行](https://go.dev/play/p/P2y0XW8a1SH) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.RemoveFile("./test.txt") + if err != nil { + fmt.Println(err) + } +} +``` + +### RemoveDir + +删除目录,支持传入删除前的回调函数。
+ +函数签名: + +```go +func RemoveDir(path string, onDelete ...func(path string)) error +``` + +示例:[运行](https://go.dev/play/p/Oa6KnPek2uy) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + var deletedPaths []string + + err := fileutil.RemoveDir("./tempdir", func(p string) { + deletedPaths = append(deletedPaths, p) + }) + + if err != nil { + fmt.Println(err) + } + + fmt.Println(deletedPaths) +} +``` + +### ReadFileToString + +读取文件内容并返回字符串
+ +函数签名: + +```go +func ReadFileToString(path string) (string, error) +``` + +示例:[运行](https://go.dev/play/p/cmfwp_5SQTp) + +```go +package main + +import ( + "fmt" + "os" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + path := "./test.txt" + fileutil.CreateFile(path) + + f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) + f.WriteString("hello world") + + content, _ := fileutil.ReadFileToString(path) + fmt.Println(content) //hello world +} +``` + +### ReadFileByLine + +按行读取文件内容,返回字符串切片包含每一行
+ +函数签名: + +```go +func ReadFileByLine(path string)([]string, error) +``` + +示例:[运行](https://go.dev/play/p/svJP_7ZrBrD) + +```go +package main + +import ( + "fmt" + "os" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + path := "./text.txt" + fileutil.CreateFile(path) + + f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) + defer f.Close() + f.WriteString("hello\nworld") + + contents, _ := fileutil.ReadFileByLine(path) + fmt.Println(contents) //[]string{"hello", "world"} +} +``` + +### Zip + +zip压缩文件, fpath参数可以是文件或目录
+ +函数签名: + +```go +func Zip(fpath string, destPath string) error +``` + +示例:[运行](https://go.dev/play/p/j-3sWBp8ik_P) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.Zip("./test.txt", "./test.zip") + if err != nil { + fmt.Println(err) + } +} +``` + +### ZipAppendEntry + +通过将单个文件或目录追加到现有的zip文件
+ +函数签名: + +```go +func ZipAppendEntry(fpath string, destPath string) error +``` + +示例:[运行](https://go.dev/play/p/cxvaT8TRNQp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.ZipAppendEntry("./test.txt", "./test.zip") + if err != nil { + fmt.Println(err) + } +} +``` + +### UnZip + +zip解压缩文件并保存在目录中
+ +函数签名: + +```go +func UnZip(zipFile string, destPath string) error +``` + +示例:[运行](https://go.dev/play/p/g0w34kS7B8m) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.UnZip("./test.zip", "./test.txt") + if err != nil { + fmt.Println(err) + } +} +``` + +### IsZipFile + +判断文件是否是zip压缩文件。
+ +函数签名: + +```go +func IsZipFile(filepath string) bool +``` + +示例:[运行](https://go.dev/play/p/9M0g2j_uF_e) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + isZip := fileutil.IsZipFile("./zipfile.zip") + fmt.Println(isZip) +} +``` + +### FileSize + +返回文件字节大小。
+ +函数签名: + +```go +func FileSize(path string) (int64, error) +``` + +示例:[运行](https://go.dev/play/p/H9Z05uD-Jjc) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + size, err := fileutil.FileSize("./testdata/test.txt") + + fmt.Println(size) + fmt.Println(err) + + // Output: + // 20 + //返回文件修改时间(unix timestamp).
+ +函数签名: + +```go +func MTime(filepath string) (int64, error) +``` + +示例:[运行](https://go.dev/play/p/s_Tl7lZoAaY) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + mtime, err := fileutil.MTime("./testdata/test.txt") + + fmt.Println(mtime) + fmt.Println(err) + + // Output: + // 1682391110 + //返回文件sha值,参数`shaType` 应传值为: 1, 256,512.
+ +函数签名: + +```go +func Sha(filepath string, shaType ...int) (string, error) +``` + +示例:[运行](https://go.dev/play/p/VfEEcO2MJYf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + sha1, err := fileutil.Sha("./testdata/test.txt", 1) + sha256, _ := fileutil.Sha("./testdata/test.txt", 256) + sha512, _ := fileutil.Sha("./testdata/test.txt", 512) + + fmt.Println(sha1) + fmt.Println(sha256) + fmt.Println(sha512) + fmt.Println(err) + + // Output: + // dda3cf10c5a6ff6c6659a497bf7261b287af2bc7 + // aa6d0a3fbc3442c228d606da09e0c1dc98c69a1cac3da1909199e0266171df35 + // d22aba2a1b7a2e2f512756255cc1c3708905646920cb1eb95e45b531ba74774dbbb89baebf1f716220eb9cf4908f1cfc5b2a01267704d9a59f59d77cab609870 + //读取csv文件内容到切片
+ +函数签名: + +```go +func ReadCsvFile(filepath string, delimiter ...rune) ([][]string, error) +``` + +示例:[运行](https://go.dev/play/p/OExTkhGEd3_u) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + content, err := fileutil.ReadCsvFile("./testdata/test.csv") + + fmt.Println(content) + fmt.Println(err) + + // Output: + // [[Bob 12 male] [Duke 14 male] [Lucy 16 female]] + //向csv文件写入内容。
+ +函数签名: + +```go +func WriteCsvFile(filepath string, records [][]string, append bool, delimiter ...rune) error +``` + +示例:[运行](https://go.dev/play/p/dAXm58Q5U1o) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + fpath := "./test.csv" + fileutil.CreateFile(fpath) + + f, _ := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0777) + defer f.Close() + + data := [][]string{ + {"Lili", "22", "female"}, + {"Jim", "21", "male"}, + } + err := fileutil.WriteCsvFile(fpath, data, false) + + if err != nil { + return + } + + content, err := fileutil.ReadCsvFile(fpath) + + if err != nil { + return + } + fmt.Println(content) + + // Output: + // [[Lili 22 female] [Jim 21 male]] +} +``` + +### WriteMapsToCsv + +将map切片写入csv文件中。
+ +函数签名: + +```go +// filepath: CSV文件路径。 +// records: 写入文件的map切片。map值必须为基本类型。会以map键的字母顺序写入。 +// appendToExistingFile: 是否为追加写模式。 +// delimiter: CSV文件分割符。 +// headers: CSV文件表头顺序(需要与map key保持一致),不指定时按字母排序。 +func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune, headers ...[]string) error +``` + +示例:[运行](https://go.dev/play/p/umAIomZFV1c) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + fpath := "./test.csv" + fileutil.CreateFile(fpath) + + f, _ := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0777) + defer f.Close() + + records := []map[string]any{ + {"Name": "Lili", "Age": "22", "Gender": "female"}, + {"Name": "Jim", "Age": "21", "Gender": "male"}, + } + + headers := []string{"Name", "Age", "Gender"} + err := fileutil.WriteMapsToCsv(csvFilePath, records, false, ';', headers) + + if err != nil { + log.Fatal(err) + } + + content, err := fileutil.ReadCsvFile(csvFilePath, ';') + + fmt.Println(content) + + // Output: + // [[Name Age Gender] [Lili 22 female] [Jim 21 male]] +} +``` + +### WriteBytesToFile + +将bytes写入文件。
+ +函数签名: + +```go +func WriteBytesToFile(filepath string, content []byte) error +``` + +示例:[运行](https://go.dev/play/p/s7QlDxMj3P8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + filepath := "./bytes.txt" + + file, err := os.Create(filepath) + if err != nil { + return + } + + defer file.Close() + + err = fileutil.WriteBytesToFile(filepath, []byte("hello")) + if err != nil { + return + } + + content, err := fileutil.ReadFileToString(filepath) + if err != nil { + return + } + + os.Remove(filepath) + + fmt.Println(content) + + // Output: + // hello +} +``` + +### WriteStringToFile + +将字符串写入文件。
+ +函数签名: + +```go +func WriteStringToFile(filepath string, content string, append bool) error +``` + +示例:[运行](https://go.dev/play/p/GhLS6d8lH_g) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + filepath := "./test.txt" + + file, err := os.Create(filepath) + if err != nil { + return + } + + defer file.Close() + + err = fileutil.WriteStringToFile(filepath, "hello", true) + if err != nil { + return + } + + content, err := fileutil.ReadFileToString(filepath) + if err != nil { + return + } + + os.Remove(filepath) + + fmt.Println(content) + + // Output: + // hello +} +``` + +### ReadFile + +读取文件或者URL。
+ +函数签名: + +```go +func ReadFile(path string) (reader io.ReadCloser, closeFn func(), err error) +``` + +示例:[运行](https://go.dev/play/p/uNep3Tr8fqF) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + reader, fn, err := fileutil.ReadFile("https://httpbin.org/robots.txt") + if err != nil { + return + } + defer fn() + + dat, err := io.ReadAll(reader) + if err != nil { + return + } + + fmt.Println(string(dat)) + + // Output: + // User-agent: * + // Disallow: /deny +} +``` + +### ChunkRead + +从文件的指定偏移读取块并返回块内所有行。
+ +函数签名: + +```go +func ChunkRead(file *os.File, offset int64, size int, bufPool *sync.Pool) ([]string, error) +``` + +示例:[运行](https://go.dev/play/p/r0hPmKWhsgf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + const mb = 1024 * 1024 + const defaultChunkSizeMB = 100 + + // test1.csv file content: + // Lili,22,female + // Jim,21,male + filePath := "./testdata/test1.csv" // 替换为你的文件路径 + f, err := os.Open(filePath) + if err != nil { + return + } + + defer f.Close() + + var bufPool = sync.Pool{ + New: func() interface{} { + return make([]byte, 0, defaultChunkSizeMB*mb) + }, + } + + lines, err := fileutil.ChunkRead(f, 0, 100, &bufPool) + if err != nil { + return + } + + fmt.Println(lines[0]) + fmt.Println(lines[1]) + + // Output: + // Lili,22,female + // Jim,21,male +} +``` + +### ParallelChunkRead + +并行读取文件并将每个块的行发送到指定通道。
+ +函数签名: + +```go +// filePath:文件路径 +// chunkSizeMB: 分块的大小(单位MB,设置为0时使用默认100MB),设置过大反而不利,视情调整 +// maxGoroutine: 并发读取分块的数量,设置为0时使用CPU核心数 +// linesCh: 用于接收返回结果的通道。 +func ParallelChunkRead(filePath string, linesCh chan<- []string, chunkSizeMB, maxGoroutine int) error +``` + +示例:[运行](https://go.dev/play/p/teMXnCsdSEw) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + const mb = 1024 * 1024 + const defaultChunkSizeMB = 100 // 默认值 + + numParsers := runtime.NumCPU() + + linesCh := make(chan []string, numParsers) + + // test1.csv file content: + // Lili,22,female + // Jim,21,male + filePath := "./testdata/test1.csv" + + go fileutil.ParallelChunkRead(filePath, linesCh, defaultChunkSizeMB, numParsers) + + var totalLines int + for lines := range linesCh { + totalLines += len(lines) + + for _, line := range lines { + fmt.Println(line) + } + } + + fmt.Println(totalLines) + + // Output: + // Lili,22,female + // Jim,21,male + // 2 +} +``` + +### GetExeOrDllVersion + +返回exe,dll文件版本号(仅Window平台).
+ +函数签名: + +```go +func GetExeOrDllVersion(filePath string) (string, error) +``` + +示例:[运行](https://go.dev/play/p/iLRrDBhE38E) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + v, err := fileutil.GetExeOrDllVersion(`C:\Program Files\Tencent\WeChat\WeChat.exe`) + if err != nil { + panic(err) + } + fmt.Println(v) + // Output: + // 3.9.10.19 +} +``` diff --git a/docs/api/packages/formatter.md b/docs/api/packages/formatter.md new file mode 100644 index 00000000..9d33dcfb --- /dev/null +++ b/docs/api/packages/formatter.md @@ -0,0 +1,310 @@ +# Formatter + +formatter 格式化器包含一些数据格式化处理方法。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go) +- [https://github.com/duke-git/lancet/blob/main/formatter/byte.go](https://github.com/duke-git/lancet/blob/main/formatter/byte.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/formatter" +) +``` + + + +## 目录 + +- [Comma](#Comma) +- [Pretty](#Pretty) +- [PrettyToWriter](#PrettyToWriter) +- [DecimalBytes](#DecimalBytes) +- [BinaryBytes](#BinaryBytes) +- [ParseDecimalBytes](#ParseDecimalBytes) +- [ParseBinaryBytes](#ParseBinaryBytes) + + + +## 文档 + +### Comma + +用逗号每隔3位分割数字/字符串,支持添加前缀符号。参数value必须是数字或者可以转为数字的字符串, 否则返回空字符串
+ +函数签名: + +```go +func Comma[T constraints.Float | constraints.Integer | string](value T, prefixSymbol string) string +``` + +示例:[运行](https://go.dev/play/p/eRD5k2vzUVX) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + result1 := formatter.Comma("123", "") + result2 := formatter.Comma("12345", "$") + result3 := formatter.Comma(1234567, "¥") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 123 + // $12,345 + // ¥1,234,567 +} +``` + +### Pretty + +返回pretty JSON字符串.
+ +函数签名: + +```go +func Pretty(v any) (string, error) +``` + +示例:[运行](https://go.dev/play/p/YsciGj3FH2x) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + result1, _ := formatter.Pretty([]string{"a", "b", "c"}) + result2, _ := formatter.Pretty(map[string]int{"a": 1}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // [ + // "a", + // "b", + // "c" + // ] + // { + // "a": 1 + // } +} +``` + +### PrettyToWriter + +Pretty encode数据到writer。
+ +函数签名: + +```go +func PrettyToWriter(v any, out io.Writer) error +``` + +示例:[运行](https://go.dev/play/p/LPLZ3lDi5ma) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + type User struct { + Name string `json:"name"` + Aage uint `json:"age"` + } + user := User{Name: "King", Aage: 10000} + + buf := &bytes.Buffer{} + err := formatter.PrettyToWriter(user, buf) + + fmt.Println(buf) + fmt.Println(err) + + // Output: + // { + // "name": "King", + // "age": 10000 + // } + // + //返回十进制标准(以1000为基数)下的可读字节单位字符串。precision参数指定小数点后的位数,默认为4。
+ +函数签名: + +```go +func DecimalBytes(size float64, precision ...int) string +``` + +示例:[运行](https://go.dev/play/p/FPXs1suwRcs) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + result1 := formatter.DecimalBytes(1000) + result2 := formatter.DecimalBytes(1024) + result3 := formatter.DecimalBytes(1234567) + result4 := formatter.DecimalBytes(1234567, 3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 1KB + // 1.024KB + // 1.2346MB + // 1.235MB +} +``` + +### BinaryBytes + +返回binary标准(以1024为基数)下的可读字节单位字符串。precision参数指定小数点后的位数,默认为4。
+ +函数签名: + +```go +func BinaryBytes(size float64, precision ...int) string +``` + +示例:[运行](https://go.dev/play/p/G9oHHMCAZxP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + result1 := formatter.BinaryBytes(1024) + result2 := formatter.BinaryBytes(1024 * 1024) + result3 := formatter.BinaryBytes(1234567) + result4 := formatter.BinaryBytes(1234567, 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 1KiB + // 1MiB + // 1.1774MiB + // 1.18MiB +} +``` + +### ParseDecimalBytes + +将字节单位字符串转换成其所表示的字节数(以1000为基数)。
+ +函数签名: + +```go +func ParseDecimalBytes(size string) (uint64, error) +``` + +示例:[运行](https://go.dev/play/p/Am98ybWjvjj) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + result1, _ := formatter.ParseDecimalBytes("12") + result2, _ := formatter.ParseDecimalBytes("12k") + result3, _ := formatter.ParseDecimalBytes("12 Kb") + result4, _ := formatter.ParseDecimalBytes("12.2 kb") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 12 + // 12000 + // 12000 + // 12200 +} +``` + +### ParseBinaryBytes + +将字节单位字符串转换成其所表示的字节数(以1024为基数)。
+ +函数签名: + +```go +func ParseBinaryBytes(size string) (uint64, error) +``` + +示例:[运行](https://go.dev/play/p/69v1tTT62x8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + result1, _ := formatter.ParseBinaryBytes("12") + result2, _ := formatter.ParseBinaryBytes("12ki") + result3, _ := formatter.ParseBinaryBytes("12 KiB") + result4, _ := formatter.ParseBinaryBytes("12.2 kib") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 12 + // 12288 + // 12288 + // 12492 +} +``` diff --git a/docs/api/packages/function.md b/docs/api/packages/function.md new file mode 100644 index 00000000..c20e35bb --- /dev/null +++ b/docs/api/packages/function.md @@ -0,0 +1,786 @@ +# Function + +function 函数包控制函数执行流程,包含部分函数式编程。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go) +- [https://github.com/duke-git/lancet/blob/main/function/predicate.go](https://github.com/duke-git/lancet/blob/main/function/predicate.go) +- [https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/function" +) +``` + + + +## 目录 + +- [After](#After) +- [Before](#Before) +- [CurryFn](#CurryFn) +- [Compose](#Compose) +- [Debounce](#Debounce) +- [Debounceddeprecated](#Debounced) +- [Delay](#Delay) +- [Schedule](#Schedule) +- [Pipeline](#Pipeline) +- [Watcher](#Watcher) +- [And](#And) +- [Or](#Or) +- [Negate](#Negate) +- [Nor](#Nor) +- [Xnor](#Xnor) +- [Nand](#Nand) +- [AcceptIf](#AcceptIf) +- [Throttle](#Throttle) + + + + +## 文档 + +### After + +创建一个函数,当他被调用n或更多次之后将马上触发fn
+ +函数签名: + +```go +func After(n int, fn any) func(args ...any) []reflect.Value +``` + +示例:[运行](https://go.dev/play/p/eRD5k2vzUVX) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + fn := function.After(2, func() { + fmt.Println("hello") + }) + + fn() + fn() + + // Output: + // hello +} +``` + +### Before + +创建一个函数,调用次数不超过n次,之后再调用这个函数,将返回一次最后调用fn的结果
+ +函数签名: + +```go +func Before(n int, fn any) func(args ...any) []reflect.Value +``` + +示例:[运行](https://go.dev/play/p/0HqUDIFZ3IL) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + fn := function.Before(2, func() { + fmt.Println("hello") + }) + + fn() + fn() + fn() + fn() + + // Output: + // hello + // hello +} +``` + +### CurryFn + +创建柯里化函数
+ +函数签名: + +```go +type CurryFn[T any] func(...T) T +func (cf CurryFn[T]) New(val T) func(...T) T +``` + +示例:[运行](https://go.dev/play/p/5HopfDwANKX) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + add := func(a, b int) int { + return a + b + } + + var addCurry function.CurryFn[int] = func(values ...int) int { + return add(values[0], values[1]) + } + add1 := addCurry.New(1) + + result := add1(2) + + fmt.Println(result) + + // Output: + // 3 +} +``` + +### Compose + +从右至左组合函数列表fnList,返回组合后的函数
+ +函数签名: + +```go +func Compose[T any](fnList ...func(...T) T) func(...T) T +``` + +示例:[运行](https://go.dev/play/p/KKfugD4PKYF) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + toUpper := func(strs ...string) string { + return strings.ToUpper(strs[0]) + } + toLower := func(strs ...string) string { + return strings.ToLower(strs[0]) + } + transform := function.Compose(toUpper, toLower) + + result := transform("aBCde") + + fmt.Println(result) + + // Output: + // ABCDE +} +``` + +### Debounce + +创建一个函数的去抖动版本。该去抖动函数仅在上次调用后的指定延迟时间过去之后才会调用原始函数。支持取消去抖动。
+ +函数签名: + +```go +func Debounce(fn func(), delay time.Duration) (debouncedFn func(), cancelFn func()) +``` + +示例:[运行](https://go.dev/play/p/-dGFrYn_1Zi) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + callCount := 0 + fn := func() { + callCount++ + } + + debouncedFn, _ := function.Debounce(fn, 500*time.Millisecond) + + for i := 0; i < 10; i++ { + debouncedFn() + time.Sleep(50 * time.Millisecond) + } + + time.Sleep(1 * time.Second) + fmt.Println(callCount) + + debouncedFn() + + time.Sleep(1 * time.Second) + fmt.Println(callCount) + + // Output: + // 1 + // 2 +} +``` + +### Debounced + +创建一个函数的去抖动版本。
+ +> ⚠️ 本函数已弃用. 使用 `Debounce` 代替. + +函数签名: + +```go +func Debounced(fn func(), duration time.Duration) func() +``` + +示例:[运行](https://go.dev/play/p/absuEGB_GN7) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + count := 0 + + add := func() { + count++ + } + + debouncedAdd := function.Debounced(add, 50*time.Microsecond) + + debouncedAdd() + debouncedAdd() + debouncedAdd() + debouncedAdd() + + time.Sleep(100 * time.Millisecond) + + fmt.Println(count) + + debouncedAdd() + + time.Sleep(100 * time.Millisecond) + + fmt.Println(count) + + // Output: + // 1 + // 2 +} +``` + +### Delay + +延迟delay时间后调用函数
+ +函数签名: + +```go +func Delay(delay time.Duration, fn any, args ...any) +``` + +示例:[运行](https://go.dev/play/p/Ivtc2ZE-Tye) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + var print = func(s string) { + fmt.Println(s) + } + + function.Delay(2*time.Second, print, "hello") + + // Output: + // hello +} +``` + +### Schedule + +每次持续时间调用函数,直到关闭返回的 bool chan
+ +函数签名: + +```go +func Schedule(d time.Duration, fn any, args ...any) chan bool +``` + +示例:[运行](https://go.dev/play/p/hbON-Xeyn5N) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + count := 0 + + increase := func() { + count++ + } + + stop := function.Schedule(2*time.Second, increase) + + time.Sleep(2 * time.Second) + close(stop) + + fmt.Println(count) + + // Output: + // 2 +} +``` + +### Pipeline + +执行函数pipeline.
+ +函数签名: + +```go +func Pipeline[T any](funcs ...func(T) T) func(T) T +``` + +示例:[运行](https://go.dev/play/p/mPdUVvj6HD6) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + addOne := func(x int) int { + return x + 1 + } + double := func(x int) int { + return 2 * x + } + square := func(x int) int { + return x * x + } + + fn := function.Pipeline(addOne, double, square) + + result := fn(2) + + fmt.Println(result) + + // Output: + // 36 +} +``` + +### Watcher + +Watcher用于记录代码执行时间。可以启动/停止/重置手表定时器。获取函数执行的时间。
+ +函数签名: + +```go +type Watcher struct { + startTime int64 + stopTime int64 + excuting bool +} +func NewWatcher() *Watcher +func (w *Watcher) Start() +func (w *Watcher) Stop() +func (w *Watcher) Reset() +func (w *Watcher) GetElapsedTime() time.Duration + +``` + +示例:[运行](https://go.dev/play/p/l2yrOpCLd1I) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + w := function.NewWatcher() + + w.Start() + + longRunningTask() + + fmt.Println(w.excuting) //true + + w.Stop() + + eapsedTime := w.GetElapsedTime().Milliseconds() + + fmt.Println(eapsedTime) + + w.Reset() + +} + +func longRunningTask() { + var slice []int64 + for i := 0; i < 10000000; i++ { + slice = append(slice, int64(i)) + } +} + +``` + +### And + +返回一个复合谓词判断函数,该判断函数表示一组谓词的逻辑and操作。只有当所有谓词判断函数对于给定的值都返回true时,返回true, 否则返回false。
+ +函数签名: + +```go +func And[T any](predicates ...func(T) bool) func(T) bool +``` + +示例:[运行](https://go.dev/play/p/dTBHJMQ0zD2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + isNumericAndLength5 := function.And( + func(s string) bool { return strings.ContainsAny(s, "0123456789") }, + func(s string) bool { return len(s) == 5 }, + ) + + fmt.Println(isNumericAndLength5("12345")) + fmt.Println(isNumericAndLength5("1234")) + fmt.Println(isNumericAndLength5("abcde")) + + // Output: + // true + // false + // false +} +``` + +### Or + +返回一个复合谓词判断函数,该判断函数表示一组谓词的逻辑or操作。只有当所有谓词判断函数对于给定的值都返回false时,返回false, 否则返回true。
+ +函数签名: + +```go +func Or[T any](predicates ...func(T) bool) func(T) bool +``` + +示例:[运行](https://go.dev/play/p/LitCIsDFNDA) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + containsDigitOrSpecialChar := function.Or( + func(s string) bool { return strings.ContainsAny(s, "0123456789") }, + func(s string) bool { return strings.ContainsAny(s, "!@#$%") }, + ) + + fmt.Println(containsDigitOrSpecialChar("hello!")) + fmt.Println(containsDigitOrSpecialChar("hello")) + + // Output: + // true + // false +} +``` + +### Negate + +返回一个谓词函数,该谓词函数表示当前谓词的逻辑否定。
+ +函数签名: + +```go +func Negate[T any](predicate func(T) bool) func(T) bool +``` + +示例:[运行](https://go.dev/play/p/jbI8BtgFnVE) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + // Define some simple predicates for demonstration + isUpperCase := func(s string) bool { + return strings.ToUpper(s) == s + } + isLowerCase := func(s string) bool { + return strings.ToLower(s) == s + } + isMixedCase := function.Negate(function.Or(isUpperCase, isLowerCase)) + + fmt.Println(isMixedCase("ABC")) + fmt.Println(isMixedCase("AbC")) + + // Output: + // false + // true +} +``` + + +### Nor + +返回一个组合谓词函数,表示给定值上所有谓词逻辑非或 (nor) 的结果。只有当所有谓词函数对给定值都返回false时,该组合谓词函数才返回true。
+ +函数签名: + +```go +func Nor[T any](predicates ...func(T) bool) func(T) bool +``` + +示例:[运行](https://go.dev/play/p/2KdCoBEOq84) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + match := function.Nor( + func(s string) bool { return strings.ContainsAny(s, "0123456789") }, + func(s string) bool { return len(s) == 5 }, + ) + + fmt.Println(match("dbcdckkeee")) + + + match = function.Nor( + func(s string) bool { return strings.ContainsAny(s, "0123456789") }, + func(s string) bool { return len(s) == 5 }, + ) + + fmt.Println(match("0123456789")) + + // Output: + // true + // false +} +``` + +### Nand + +返回一个复合谓词函数,表示给定谓词函数列表的逻辑非与 (NAND)。仅当列表中所有函数对给定参数返回false时,才返回true,否则返回false。
+ +函数签名: + +```go +func Nand[T any](predicates ...func(T) bool) func(T) bool +``` + +示例:[运行](https://go.dev/play/p/Rb-FdNGpgSO) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + isNumericAndLength5 := function.Nand( + func(s string) bool { return strings.ContainsAny(s, "0123456789") }, + func(s string) bool { return len(s) == 5 }, + ) + + fmt.Println(isNumericAndLength5("12345")) + fmt.Println(isNumericAndLength5("1234")) + fmt.Println(isNumericAndLength5("abcdef")) + + // Output: + // false + // false + // true +} +``` + +### Xnor + +返回一个复合谓词函数,表示给定一组谓词函数的逻辑异或 (XNOR)。只有当所有 谓词函数对给参数都返回true或false时,该谓词函数才返回true。
+ +函数签名: + +```go +func Xnor[T any](predicates ...func(T) bool) func(T) bool +``` + +示例:[运行](https://go.dev/play/p/FJxko8SFbqc) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + isEven := func(i int) bool { return i%2 == 0 } + isPositive := func(i int) bool { return i > 0 } + + match := function.Xnor(isEven, isPositive) + + fmt.Println(match(2)) + fmt.Println(match(-3)) + fmt.Println(match(3)) + + // Output: + // true + // true + // false +} +``` + +### AcceptIf + +AcceptIf函数会返回另一个函数,该函数的签名与 apply 函数相同,但同时还会包含一个布尔值来表示成功或失败。
+ +函数签名: + +```go +func AcceptIf[T any](predicate func(T) bool, apply func(T) T) func(T) (T, bool) +``` + +示例:[运行](https://go.dev/play/p/XlXHHtzCf7d) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + adder := function.AcceptIf( + function.And( + func(x int) bool { + return x > 10 + }, func(x int) bool { + return x%2 == 0 + }), + func(x int) int { + return x + 1 + }, + ) + + result, ok := adder(20) + fmt.Println(result) + fmt.Println(ok) + + result, ok = adder(21) + fmt.Println(result) + fmt.Println(ok) + + // Output: + // 21 + // true + // 0 + // false +} + +``` + +### Throttle + +创建一个函数的节流版本。返回的函数保证在每个时间间隔内最多只会被调用一次。
+ +函数签名: + +```go +func Throttle(fn func(), interval time.Duration) func() +``` + +示例:[运行](https://go.dev/play/p/HpoMov-tJSN) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + callCount := 0 + + fn := func() { + callCount++ + } + + throttledFn := function.Throttle(fn, 1*time.Second) + + for i := 0; i < 5; i++ { + throttledFn() + } + + time.Sleep(1 * time.Second) + + fmt.Println(callCount) + + // Output: + // 1 +} +``` \ No newline at end of file diff --git a/docs/api/packages/maputil.md b/docs/api/packages/maputil.md new file mode 100644 index 00000000..daa8b1a5 --- /dev/null +++ b/docs/api/packages/maputil.md @@ -0,0 +1,2347 @@ +# Maputil + +maputil 包包括一些操作 map 的函数。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/maputil/map.go](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/concurrentmap.go) +- [https://github.com/duke-git/lancet/blob/main/maputil/orderedmap.go](https://github.com/duke-git/lancet/blob/main/maputil/orderedmap.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/maputil" +) +``` + + + +## 目录: + +- [MapTo](#MapTo) +- [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) +- [IsDisjoint](#IsDisjoint) +- [HasKey](#HasKey) +- [MapToStruct](#MapToStruct) +- [ToSortedSlicesDefault](#ToSortedSlicesDefault) +- [ToSortedSlicesWithComparator](#ToSortedSlicesWithComparator) +- [NewOrderedMap](#NewOrderedMap) +- [OrderedMap_Set](#OrderedMap_Set) +- [OrderedMap_Get](#OrderedMap_Get) +- [OrderedMap_Front](#OrderedMap_Front) +- [OrderedMap_Back](#OrderedMap_Back) +- [OrderedMap_Delete](#OrderedMap_Delete) +- [OrderedMap_Clear](#OrderedMap_Clear) +- [OrderedMap_Len](#OrderedMap_Len) +- [OrderedMap_Keys](#OrderedMap_Keys) +- [OrderedMap_Values](#OrderedMap_Values) +- [OrderedMap_Contains](#OrderedMap_Contains) +- [OrderedMap_Range](#OrderedMap_Range) +- [OrderedMap_Elements](#OrderedMap_Elements) +- [OrderedMap_Iter](#OrderedMap_Iter) +- [OrderedMap_ReverseIter](#OrderedMap_ReverseIter) +- [OrderedMap_SortByKey](#OrderedMap_SortByKey) +- [OrderedMap_MarshalJSON](#OrderedMap_MarshalJSON) +- [OrderedMap_UnmarshalJSON](#OrderedMap_UnmarshalJSON) +- [NewConcurrentMap](#NewConcurrentMap) +- [ConcurrentMap_Get](#ConcurrentMap_Get) +- [ConcurrentMap_Set](#ConcurrentMap_Set) +- [ConcurrentMap_GetOrSet](#ConcurrentMap_GetOrSet) +- [ConcurrentMap_Delete](#ConcurrentMap_Delete) +- [ConcurrentMap_GetAndDelete](#ConcurrentMap_GetAndDelete) +- [ConcurrentMap_Has](#ConcurrentMap_Has) +- [ConcurrentMap_Range](#ConcurrentMap_Range) +- [GetOrSet](#GetOrSet) +- [SortByKey](#SortByKey) +- [GetOrDefault](#GetOrDefault) +- [FindValuesBy](#FindValuesBy) + + + +## API 文档: + +### MapTo + +快速将map或者其他类型映射到结构体或者指定类型。
+ +函数签名: + +```go +func MapTo(src any, dst any) error +``` + +示例:[运行](https://go.dev/play/p/4K7KBEPgS5M) + +```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: + //对map中的每对key和value执行iteratee函数
+ +函数签名: + +```go +func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V)) +``` + +示例:[运行](https://go.dev/play/p/OaThj6iNVXK) + +```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 +``` + +示例:[运行](https://go.dev/play/p/fSvF3wxuNG7) + +```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 +``` + +示例:[运行](https://go.dev/play/p/7ov6BJHbVqh) + +```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 +``` + +示例:[运行](https://go.dev/play/p/P3-9MdcXegR) + +```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 +``` + +示例:[运行](https://go.dev/play/p/YJM4Hj5hNwm) + +```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 +``` + +示例:[运行](https://go.dev/play/p/jXGrWDBfSRp) + +```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 +``` + +示例:[运行](https://go.dev/play/p/XB7Y10uw20_U) + +```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 +``` + +示例:[运行](https://go.dev/play/p/Zld0oj3sjcC) + +```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 +``` + +示例:[运行](https://go.dev/play/p/xNB5bTb97Wd) + +```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 +``` + +示例:[运行](https://go.dev/play/p/H95LENF1uB-) + +```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 +``` + +示例:[运行](https://go.dev/play/p/3u5U9K7YZ9m) + +```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 +``` + +示例:[运行](https://go.dev/play/p/CBKdUc5FTW6) + +```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 +``` + +示例:[运行](https://go.dev/play/p/hI371iB8Up8) + +```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 +``` + +示例:[运行](https://go.dev/play/p/sg9-oRidh8f) + +```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 +``` + +示例:[运行](https://go.dev/play/p/8scDxWeBDKd) + +```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 +``` + +示例:[运行](https://go.dev/play/p/g92aY3fc7Iw) + +```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] +``` + +示例:[运行](https://go.dev/play/p/Ltb11LNcElY) + +```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 +``` + +示例:[运行](https://go.dev/play/p/C8L4ul9TVwf) + +```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 +``` + +示例:[运行](https://go.dev/play/p/P6ovfToM3zj) + +```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 +``` + +示例:[运行](https://go.dev/play/p/N9qgYg_Ho6f) + +```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 +``` + +示例:[运行](https://go.dev/play/p/isZZHOsDhFc) + +```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 +``` + +示例:[运行](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对应。
+ +函数签名: + +```go +func ToSortedSlicesDefault[K constraints.Ordered, V any](m map[K]V) ([]K, []V) +``` + +示例:[运行](https://go.dev/play/p/43gEM2po-qy) + +```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) +``` + +示例:[运行](https://go.dev/play/p/0nlPo6YLdt3) + +```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) +``` + +示例:[运行](https://go.dev/play/p/Y4ZJ_oOc1FU) + +```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) +``` + +示例:[运行](https://go.dev/play/p/Y4ZJ_oOc1FU) + +```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) +``` + +示例:[运行](https://go.dev/play/p/5bIi4yaZ3K-) + +```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() +``` + +示例:[运行](https://go.dev/play/p/8LwoJyEfuFr) + +```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) +``` + +示例:[运行](https://go.dev/play/p/ty57XSimpoe) + +```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) +``` + +示例:[运行](https://go.dev/play/p/rQMjp1yQmpa) + +```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) +``` + +示例:[运行](https://go.dev/play/p/U-KpORhc7LZ) + +```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 +``` + +示例:[运行](https://go.dev/play/p/Vv_y9ExKclA) + +```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 +``` + +示例:[运行](https://go.dev/play/p/TWj5n1-PUfx) + +```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 +``` + +示例:[运行](https://go.dev/play/p/4BHG4kKz6bB) + +```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 +``` + +示例:[运行](https://go.dev/play/p/cLe6z2VX5N-) + +```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 +``` + +示例:[运行](https://go.dev/play/p/QuwqqnzwDNX) + +```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 +} +``` + +示例:[运行](https://go.dev/play/p/tlq2tdvicPt) + +```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 +} +``` + +示例:[运行](https://go.dev/play/p/8Q0ssg6hZzO) + +```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) +``` + +示例:[运行](https://go.dev/play/p/N7hjD_alZPq) + +```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) +``` + +示例:[运行](https://go.dev/play/p/C-wAwydIAC7) + +```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 +``` + +示例:[运行](https://go.dev/play/p/8C3MvJ3-mut) + +```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] +``` + +示例:[运行](https://go.dev/play/p/3PenTPETJT0) + +```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) +``` + +示例:[运行](https://go.dev/play/p/3PenTPETJT0) + +```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) +``` + +示例:[运行](https://go.dev/play/p/3PenTPETJT0) + +```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) +``` + +示例:[运行](https://go.dev/play/p/aDcDApOK01a) + +```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) +``` + +示例:[运行](https://go.dev/play/p/uTIJZYhpVMS) + +```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) +``` + +示例:[运行](https://go.dev/play/p/ZyxeIXSZUiM) + +```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 +``` + +示例:[运行](https://go.dev/play/p/C8L4ul9TVwf) + +```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) +``` + +示例:[运行](https://go.dev/play/p/iqcy7P8P0Pr) + +```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 +``` + +示例:[运行](https://go.dev/play/p/IVQwO1OkEJC) + +```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) +``` + +示例:[运行](https://go.dev/play/p/PVdmBSnm6P_W) + +```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 +``` + +示例:[运行](https://go.dev/play/p/99QjSYSBdiM) + +```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 +} +``` + +### FindValuesBy + +返回一个切片,包含满足给定谓词判断函数的map中的值。
+ +函数签名: + +```go +func FindValuesBy[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) []V +``` + +示例:[运行](https://go.dev/play/p/bvNwNBZDm6v) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/maputil" +) + +func main() { + m := map[int]string{ + 1: "a", + 2: "b", + 3: "c", + 4: "d", + } + + result := maputil.FindValuesBy(m, func(k int, v string) bool { + return k%2 == 0 + }) + + fmt.Println(result) + + // Output: + // [b d] +} +``` diff --git a/docs/api/packages/mathutil.md b/docs/api/packages/mathutil.md new file mode 100644 index 00000000..2a4f2205 --- /dev/null +++ b/docs/api/packages/mathutil.md @@ -0,0 +1,1301 @@ +# Mathutil + +mathutil 包实现了一些数学计算的函数. + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/mathutil" +) +``` + + + +## 目录 + +- [Average](#Average) +- [Exponent](#Exponent) +- [Fibonacci](#Fibonacci) +- [Factorial](#Factorial) +- [Max](#Max) +- [MaxBy](#MaxBy) +- [Min](#Min) +- [MinBy](#MaxBy) +- [Percent](#Percent) +- [RoundToFloat](#RoundToFloat) +- [RoundToString](#RoundToString) +- [T运行cRound](#T运行cRound) +- [CeilToFloat](#CeilToFloat) +- [CeilToString](#CeilToString) +- [FloorToFloat](#FloorToFloat) +- [FloorToString](#FloorToString) +- [Range](#Range) +- [RangeWithStep](#RangeWithStep) +- [AngleToRadian](#AngleToRadian) +- [RadianToAngle](#RadianToAngle) +- [PointDistance](#PointDistance) +- [IsPrime](#IsPrime) +- [GCD](#GCD) +- [LCM](#LCM) +- [Cos](#Cos) +- [Sin](#Sin) +- [Log](#Log) +- [Sum](#Sum) +- [Abs](#Abs) +- [Div](#Div) +- [Variance](#Variance) +- [StdDev](#StdDev) +- [Permutation](#Permutation) +- [Combination](#Combination) + + + +## 文档 + +### Average + +计算平均数. 可能需要对结果调用RoundToFloat方法四舍五入
+ +函数签名: + +```go +func Average[T constraints.Integer | constraints.Float](numbers ...T) float64 +``` + +示例:[运行](https://go.dev/play/p/HFd70x4DrMj) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Average(1, 2) + + avg := mathutil.Average(1.2, 1.4) + result2 := mathutil.RoundToFloat(avg, 1) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1.5 + // 1.3 +} +``` + +### Exponent + +指数计算(x的n次方)
+ +函数签名: + +```go +func Exponent(x, n int64) int64 +``` + +示例:[运行](https://go.dev/play/p/Vv7LBwER-pz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Exponent(10, 0) + result2 := mathutil.Exponent(10, 1) + result3 := mathutil.Exponent(10, 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 1 + // 10 + // 100 +} +``` + +### Fibonacci + +计算斐波那契数列的第n个数
+ +函数签名: + +```go +func Fibonacci(first, second, n int) int +``` + +示例:[运行](https://go.dev/play/p/IscseUNMuUc) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Fibonacci(1, 1, 1) + result2 := mathutil.Fibonacci(1, 1, 2) + result3 := mathutil.Fibonacci(1, 1, 5) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 1 + // 1 + // 5 +} +``` + +### Factorial + +计算阶乘
+ +函数签名: + +```go +func Factorial(x uint) uint +``` + +示例:[运行](https://go.dev/play/p/tt6LdOK67Nx) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Factorial(1) + result2 := mathutil.Factorial(2) + result3 := mathutil.Factorial(3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 1 + // 2 + // 6 +} +``` + +### Max + +返回参数中的最大数
+ +函数签名: + +```go +func Max[T constraints.Integer | constraints.Float](numbers ...T) T +``` + +示例:[运行](https://go.dev/play/p/cN8DHI0rTkH) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Max(1, 2, 3) + result2 := mathutil.Max(1.2, 1.4, 1.1, 1.4) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 3 + // 1.4 +} +``` + +### MaxBy + +使用给定的比较器函数返回切片的最大值
+ +函数签名: + +```go +func MaxBy[T any](slice []T, comparator func(T, T) bool) T +``` + +示例:[运行](https://go.dev/play/p/pbe2MT-7DV2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.MaxBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool { + return len(v1) > len(v2) + }) + + result2 := mathutil.MaxBy([]string{"abd", "abc", "ab"}, func(v1, v2 string) bool { + return len(v1) > len(v2) + }) + + result3 := mathutil.MaxBy([]string{}, func(v1, v2 string) bool { + return len(v1) > len(v2) + }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // abc + // abd + // +} +``` + +### Min + +返回参数中的最小数
+ +函数签名: + +```go +func Min[T constraints.Integer | constraints.Float](numbers ...T) T +``` + +示例:[运行](https://go.dev/play/p/pbe2MT-7DV2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Min(1, 2, 3) + result2 := mathutil.Min(1.2, 1.4, 1.1, 1.4) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1 + // 1.1 +} +``` + +### MinBy + +使用给定的比较器函数返回切片的最小值
+ +函数签名: + +```go +func MinBy[T any](slice []T, comparator func(T, T) bool) T +``` + +示例:[运行](https://go.dev/play/p/N9qgYg_Ho6f) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.MinBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool { + return len(v1) < len(v2) + }) + + result2 := mathutil.MinBy([]string{"ab", "ac", "abc"}, func(v1, v2 string) bool { + return len(v1) < len(v2) + }) + + result3 := mathutil.MinBy([]string{}, func(v1, v2 string) bool { + return len(v1) < len(v2) + }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // a + // ab + // +} +``` + +### Percent + +计算百分比,保留n位小数
+ +函数签名: + +```go +func Percent(val, total float64, n int) float64 +``` + +示例:[运行](https://go.dev/play/p/s0NdFCtwuyd) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Percent(1, 2, 2) + result2 := mathutil.Percent(0.1, 0.3, 2) + result3 := mathutil.Percent(-30305, 408420, 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 50 + // 33.33 + // -7.42 +} +``` + +### RoundToFloat + +四舍五入,保留n位小数
+ +函数签名: + +```go +func RoundToFloat[T constraints.Float | constraints.Integer](x T, n int) float64 +``` + +示例:[运行](https://go.dev/play/p/ghyb528JRJL) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.RoundToFloat(0.124, 2) + result2 := mathutil.RoundToFloat(0.125, 2) + result3 := mathutil.RoundToFloat(0.125, 3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 0.12 + // 0.13 + // 0.125 +} +``` + +### RoundToString + +四舍五入,保留n位小数,返回字符串
+ +函数签名: + +```go +func RoundToString[T constraints.Float | constraints.Integer](x T, n int) string +``` + +示例:[运行](https://go.dev/play/p/kZwpBRAcllO) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.RoundToString(0.124, 2) + result2 := mathutil.RoundToString(0.125, 2) + result3 := mathutil.RoundToString(0.125, 3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 0.12 + // 0.13 + // 0.125 +} +``` + +### TruncRound + +截短n位小数(不进行四舍五入)
+ +函数签名: + +```go +func TruncRound[T constraints.Float | constraints.Integer](x T, n int) T +``` + +示例:[运行](https://go.dev/play/p/aumarSHIGzP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.TruncRound(0.124, 2) + result2 := mathutil.TruncRound(0.125, 2) + result3 := mathutil.TruncRound(0.125, 3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 0.12 + // 0.12 + // 0.125 +} +``` + +### CeilToFloat + +向上舍入(进一法),保留n位小数。
+ +函数签名: + +```go +func CeilToFloat[T constraints.Float | constraints.Integer](x T, n int) float64 +``` + +示例:[运行](https://go.dev/play/p/8hOeSADZPCo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.CeilToFloat(3.14159, 1) + result2 := mathutil.CeilToFloat(3.14159, 2) + result3 := mathutil.CeilToFloat(5, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 3.2 + // 3.15 + // 5 +} +``` + +### CeilToString + +向上舍入(进一法),保留n位小数,返回字符串。
+ +函数签名: + +```go +func CeilToString[T constraints.Float | constraints.Integer](x T, n int) string +``` + +示例:[运行](https://go.dev/play/p/wy5bYEyUKKG) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.CeilToString(3.14159, 1) + result2 := mathutil.CeilToString(3.14159, 2) + result3 := mathutil.CeilToString(5, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 3.2 + // 3.15 + // 5.0000 +} +``` + +### FloorToFloat + +向下舍入(去尾法),保留n位小数。
+ +函数签名: + +```go +func FloorToFloat[T constraints.Float | constraints.Integer](x T, n int) float64 +``` + +示例:[运行](https://go.dev/play/p/vbCBrQHZEED) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.FloorToFloat(3.14159, 1) + result2 := mathutil.FloorToFloat(3.14159, 2) + result3 := mathutil.FloorToFloat(5, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 3.1 + // 3.14 + // 5 +} +``` + +### FloorToString + +向下舍入(去尾法),保留n位小数,返回字符串。
+ +函数签名: + +```go +func FloorToString[T constraints.Float | constraints.Integer](x T, n int) string +``` + +示例:[运行](https://go.dev/play/p/Qk9KPd2IdDb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.FloorToString(3.14159, 1) + result2 := mathutil.FloorToString(3.14159, 2) + result3 := mathutil.FloorToString(5, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 3.1 + // 3.14 + // 5.0000 +} +``` + +### Range + +根据指定的起始值和数量,创建一个数字切片。
+ +函数签名: + +```go +func Range[T constraints.Integer | constraints.Float](start T, count int) []T +``` + +示例:[运行](https://go.dev/play/p/9ke2opxa8ZP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Range(1, 4) + result2 := mathutil.Range(1, -4) + result3 := mathutil.Range(-4, 4) + result4 := mathutil.Range(1.0, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [1 2 3 4] + // [1 2 3 4] + // [-4 -3 -2 -1] + // [1 2 3 4] +} +``` + +### RangeWithStep + +根据指定的起始值,结束值,步长,创建一个数字切片。
+ +函数签名: + +```go +func RangeWithStep[T constraints.Integer | constraints.Float](start, end, step T) []T +``` + +示例:[运行](https://go.dev/play/p/akLWz0EqOSM) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.RangeWithStep(1, 4, 1) + result2 := mathutil.RangeWithStep(1, -1, 0) + result3 := mathutil.RangeWithStep(-4, 1, 2) + result4 := mathutil.RangeWithStep(1.0, 4.0, 1.1) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [1 2 3] + // [] + // [-4 -2 0] + // [1 2.1 3.2] +} +``` + +### AngleToRadian + +将角度值转为弧度值
+ +函数签名: + +```go +func AngleToRadian(angle float64) float64 +``` + +示例:[运行](https://go.dev/play/p/CIvlICqrHql) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.AngleToRadian(45) + result2 := mathutil.AngleToRadian(90) + result3 := mathutil.AngleToRadian(180) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 0.7853981633974483 + // 1.5707963267948966 + // 3.141592653589793 +} +``` + +### RadianToAngle + +将弧度值转为角度值
+ +函数签名: + +```go +func RadianToAngle(radian float64) float64 +``` + +示例:[运行](https://go.dev/play/p/dQtmOTUOMgi) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.RadianToAngle(math.Pi) + result2 := mathutil.RadianToAngle(math.Pi / 2) + result3 := mathutil.RadianToAngle(math.Pi / 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 180 + // 90 + // 45 +} +``` + +### PointDistance + +计算两个坐标点的距离
+ +函数签名: + +```go +func PointDistance(x1, y1, x2, y2 float64) float64 +``` + +示例:[运行](https://go.dev/play/p/RrG4JIaziM8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.PointDistance(1, 1, 4, 5) + + fmt.Println(result1) + + // Output: + // 5 +} +``` + +### IsPrime + +判断质数。
+ +函数签名: + +```go +func IsPrime(n int) bool +``` + +示例:[运行](https://go.dev/play/p/Rdd8UTHZJ7u) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.IsPrime(-1) + result2 := mathutil.IsPrime(0) + result3 := mathutil.IsPrime(1) + result4 := mathutil.IsPrime(2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // false + // true +} +``` + +### GCD + +计算最大公约数。
+ +函数签名: + +```go +func GCD[T constraints.Integer](integers ...T) T +``` + +示例:[运行](https://go.dev/play/p/CiEceLSoAKB) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.GCD(1, 1) + result2 := mathutil.GCD(1, -1) + result3 := mathutil.GCD(-1, 1) + result4 := mathutil.GCD(-1, -1) + result5 := mathutil.GCD(3, 6, 9) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // 1 + // 1 + // -1 + // -1 + // 3 +} +``` + +### LCM + +计算最小公倍数。
+ +函数签名: + +```go +func LCM[T constraints.Integer](integers ...T) T +``` + +示例:[运行](https://go.dev/play/p/EjcZxfY7G_g) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.LCM(1, 1) + result2 := mathutil.LCM(1, 2) + result3 := mathutil.LCM(3, 6, 9) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 1 + // 2 + // 18 +} +``` + +### Cos + +计算弧度的余弦值
+ +函数签名: + +```go +func Cos(radian float64, precision ...int) float64 +``` + +示例:[运行](https://go.dev/play/p/Sm89LoIfvFq) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Cos(0) + result2 := mathutil.Cos(90) + result3 := mathutil.Cos(180) + result4 := mathutil.Cos(math.Pi) + result5 := mathutil.Cos(math.Pi / 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // 1 + // -0.447 + // -0.598 + // -1 + // 0 +} +``` + +### Sin + +计算弧度的正弦值
+ +函数签名: + +```go +func Sin(radian float64, precision ...int) float64 +``` + +示例:[运行](https://go.dev/play/p/TWMQlMywDsP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Sin(0) + result2 := mathutil.Sin(90) + result3 := mathutil.Sin(180) + result4 := mathutil.Sin(math.Pi) + result5 := mathutil.Sin(math.Pi / 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // 0 + // 0.894 + // -0.801 + // 0 + // 1 +} +``` + +### Log + +计算以base为底n的对数。
+ +函数签名: + +```go +func Log(n, base float64) float64 +``` + +示例:[运行](https://go.dev/play/p/_d4bi8oyhat) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Log(8, 2) + result2 := mathutil.T运行cRound(mathutil.Log(5, 2), 2) + result3 := mathutil.T运行cRound(mathutil.Log(27, 3), 0) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 3 + // 2.32 + // 3 +} +``` + +### Sum + +求传入参数之和。
+ +函数签名: + +```go +func Sum[T constraints.Integer | constraints.Float](numbers ...T) T +``` + +示例:[运行](https://go.dev/play/p/1To2ImAMJA7) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Sum(1, 2) + result2 := mathutil.Sum(0.1, float64(1)) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 3 + // 1.1 +} +``` + +### Abs + +求绝对值。
+ +函数签名: + +```go +func Abs[T constraints.Integer | constraints.Float](x T) T +``` + +示例:[运行](https://go.dev/play/p/fsyBh1Os-1d) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := Abs(-1) + result2 := Abs(-0.1) + result3 := Abs(float32(0.2)) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 1 + // 0.1 + // 0.2 +} +``` + +### Div + +除法运算。
+ +函数签名: + +```go +func Div[T constraints.Float | constraints.Integer](x T, y T) float64 +``` + +示例:[运行](https://go.dev/play/p/WLxDdGXXYat) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Div(9, 4) + result2 := mathutil.Div(1, 2) + result3 := mathutil.Div(0, 666) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 2.25 + // 0.5 + // 0 +} +``` + +### Variance + +计算方差。
+ +函数签名: + +```go +func Variance[T constraints.Float | constraints.Integer](numbers []T) float64 +``` + +示例:[示例](https://go.dev/play/p/uHuV4YgXf8F) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Variance([]int{1, 2, 3, 4, 5}) + result2 := mathutil.Variance([]float64{1.1, 2.2, 3.3, 4.4, 5.5}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 2 + // 2.42 +} +``` + +### StdDev + +计算标准差。
+ +函数签名: + +```go +func StdDev[T constraints.Float | constraints.Integer](numbers []T) float64 +``` + +示例:[运行](https://go.dev/play/p/FkNZDXvHD2l) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.TruncRound(mathutil.StdDev([]int{1, 2, 3, 4, 5}), 2) + result2 := mathutil.TruncRound(mathutil.StdDev([]float64{1.1, 2.2, 3.3, 4.4, 5.5}), 2) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1.41 + // 1.55 +} +``` + +### Permutation + +计算排列数P(n, k)。
+ +函数签名: + +```go +func Permutation(n, k uint) uint +``` + +示例:[运行](https://go.dev/play/p/MgobwH_FOxj) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Permutation(5, 3) + result2 := mathutil.Permutation(5, 5) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 60 + // 120 +} +``` + +### Combination + +计算组合数C(n, k)。
+ +函数签名: + +```go +func Combination(n, k uint) uint +``` + +示例:[运行](https://go.dev/play/p/ENFQRDQUFi9) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Combination(5, 3) + result2 := mathutil.Combination(5, 5) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 10 + // 1 +} +``` \ No newline at end of file diff --git a/docs/api/packages/netutil.md b/docs/api/packages/netutil.md new file mode 100644 index 00000000..7be8c18b --- /dev/null +++ b/docs/api/packages/netutil.md @@ -0,0 +1,1115 @@ +# Netutil + +netutil 网络包支持获取 ip 地址,发送 http 请求。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go) + +- [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/netutil" +) +``` + + + +## 目录 + +- [ConvertMapToQueryString](#ConvertMapToQueryString) +- [EncodeUrl](#EncodeUrl) +- [GetInternalIp](#GetInternalIp) +- [GetIps](#GetIps) +- [GetMacAddrs](#GetMacAddrs) +- [GetPublicIpInfo](#GetPublicIpInfo) +- [GetRequestPublicIp](#GetRequestPublicIp) +- [IsPublicIP](#IsPublicIP) +- [IsInternalIP](#IsInternalIP) +- [HttpRequest](#HttpRequest) +- [HttpClient](#HttpClient) +- [SendRequest](#SendRequest) +- [DecodeResponse](#DecodeResponse) +- [StructToUrlValues](#StructToUrlValues) +- [HttpGetDeprecated](#HttpGet) +- [HttpDeleteDeprecated](#HttpDelete) +- [HttpPostDeprecated](#HttpPost) +- [HttpPutDeprecated](#HttpPut) +- [HttpPatchDeprecated](#HttpPatch) +- [ParseHttpResponse](#ParseHttpResponse) +- [DownloadFile](#DownloadFile) +- [UploadFile](#UploadFile) +- [IsPingConnected](#IsPingConnected) +- [IsTelnetConnected](#IsTelnetConnected) +- [BuildUrl](#BuildUrl) +- [AddQueryParams](#AddQueryParams) + + + +## 文档 + +### ConvertMapToQueryString + +将map转换成http查询字符串.
+ +函数签名: + +```go +func ConvertMapToQueryString(param map[string]any) string +``` + +示例:[运行](https://go.dev/play/p/jnNt_qoSnRi) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + var m = map[string]any{ + "c": 3, + "a": 1, + "b": 2, + } + qs := netutil.ConvertMapToQueryString(m) + + fmt.Println(qs) + + // Output: + // a=1&b=2&c=3 +} +``` + +### EncodeUrl + +编码url query string的值
+ +函数签名: + +```go +func EncodeUrl(urlStr string) (string, error) +``` + +示例:[运行](https://go.dev/play/p/bsZ6BRC4uKI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + urlAddr := "http://www.lancet.com?a=1&b=[2]" + encodedUrl, err := netutil.EncodeUrl(urlAddr) + + if err != nil { + fmt.Println(err) + } + + fmt.Println(encodedUrl) + + // Output: + // http://www.lancet.com?a=1&b=%5B2%5D +} +``` + +### GetInternalIp + +获取内部ip
+ +函数签名: + +```go +func GetInternalIp() string +``` + +示例:[运行](https://go.dev/play/p/fxnna_LLD9u) + +```go +package main + +import ( + "fmt" + "net" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + internalIp := netutil.GetInternalIp() + ip := net.ParseIP(internalIp) + + fmt.Println(ip) + + // Output: + // 192.168.1.9 +} +``` + +### GetIps + +获取ipv4地址列表
+ +函数签名: + +```go +func GetIps() []string +``` + +示例:[运行](https://go.dev/play/p/NUFfcEmukx1) + +```go +package main + +import ( + "fmt" + "net" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + ips := netutil.GetIps() + fmt.Println(ips) + + // Output: + // [192.168.1.9] +} +``` + +### GetMacAddrs + +获取mac地址列
+ +函数签名: + +```go +func GetMacAddrs() []string { +``` + +示例:[运行](https://go.dev/play/p/Rq9UUBS_Xp1) + +```go +package main + +import ( + "fmt" + "net" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + macAddrs := netutil.GetMacAddrs() + fmt.Println(macAddrs) + + // Output: + // [18:31:bf:09:d1:56 76:ee:2a:e6:2e:0f 74:ee:2a:e6:2e:0f 74:ee:2a:e6:2e:0f] +} +``` + +### GetPublicIpInfo + +获取公网ip信息
+ +函数签名: + +```go +func GetPublicIpInfo() (*PublicIpInfo, error) +type PublicIpInfo struct { + Status string `json:"status"` + Country string `json:"country"` + CountryCode string `json:"countryCode"` + Region string `json:"region"` + RegionName string `json:"regionName"` + City string `json:"city"` + Lat float64 `json:"lat"` + Lon float64 `json:"lon"` + Isp string `json:"isp"` + Org string `json:"org"` + As string `json:"as"` + Ip string `json:"query"` +} +``` + +示例:[运行](https://go.dev/play/p/YDxIfozsRHR) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + publicIpInfo, err := netutil.GetPublicIpInfo() + if err != nil { + fmt.Println(err) + } + + fmt.Println(publicIpInfo) +} +``` + +### GetRequestPublicIp + +获取http请求ip
+ +函数签名: + +```go +func GetRequestPublicIp(req *http.Request) string +``` + +示例:[运行](https://go.dev/play/p/kxU-YDc_eBo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + ip := "36.112.24.10" + + request := http.Request{ + Method: "GET", + Header: http.Header{ + "X-Forwarded-For": {ip}, + }, + } + publicIp := netutil.GetRequestPublicIp(&request) + + fmt.Println(publicIp) + + // Output: + // 36.112.24.10 +} +``` + +### IsPublicIP + +判断ip是否是公共ip
+ +函数签名: + +```go +func IsPublicIP(IP net.IP) bool +``` + +示例:[运行](https://go.dev/play/p/nmktSQpJZnn) + +```go +package main + +import ( + "fmt" + "net" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + ip1 := netutil.IsPublicIP(net.ParseIP("127.0.0.1")) + ip2 := netutil.IsPublicIP(net.ParseIP("192.168.0.1")) + ip3 := netutil.IsPublicIP(net.ParseIP("36.112.24.10")) + + fmt.Println(ip1) + fmt.Println(ip2) + fmt.Println(ip3) + + // Output: + // false + // false + // true +} +``` + +### IsInternalIP + +判断ip是否是局域网ip.
+ +函数签名: + +```go +func IsInternalIP(IP net.IP) bool +``` + +示例:[运行](https://go.dev/play/p/sYGhXbgO4Cb) + +```go +package main + +import ( + "fmt" + "net" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + ip1 := netutil.IsInternalIP(net.ParseIP("127.0.0.1")) + ip2 := netutil.IsInternalIP(net.ParseIP("192.168.0.1")) + ip3 := netutil.IsInternalIP(net.ParseIP("36.112.24.10")) + + fmt.Println(ip1) + fmt.Println(ip2) + fmt.Println(ip3) + + // Output: + // true + // true + // false +} +``` + +### HttpRequest + +HttpRequest用于抽象HTTP请求实体的结构
+ +函数签名: + +```go +type HttpRequest struct { + RawURL string + Method string + Headers http.Header + QueryParams url.Values + FormData url.Values + Body []byte +} +``` + +示例:[运行](https://go.dev/play/p/jUSgynekH7G) + +```go +package main + +import ( + "fmt" + "net" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + header := http.Header{} + header.Add("Content-Type", "multipart/form-data") + + postData := url.Values{} + postData.Add("userId", "1") + postData.Add("title", "testItem") + + request := &netutil.HttpRequest{ + RawURL: "https://jsonplaceholder.typicode.com/todos", + Method: "POST", + Headers: header, + FormData: postData, + } +} +``` + +### HttpClient + +HttpClient是用于发送HTTP请求的结构体。它可以用一些配置参数或无配置实例化.
+ +函数签名: + +```go +type HttpClient struct { + *http.Client + TLS *tls.Config + Request *http.Request + Config HttpClientConfig +} + +type HttpClientConfig struct { + SSLEnabled bool + TLSConfig *tls.Config + Compressed bool + HandshakeTimeout time.Duration + ResponseTimeout time.Duration + Verbose bool +} + +func NewHttpClient() *HttpClient + +func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient + +``` + +示例:[运行](https://go.dev/play/p/jUSgynekH7G) + +```go +package main + +import ( + "fmt" + "net" + "time" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + httpClientCfg := netutil.HttpClientConfig{ + SSLEnabled: true, + HandshakeTimeout:10 * time.Second + } + httpClient := netutil.NewHttpClientWithConfig(&httpClientCfg) +} +``` + +### SendRequest + +HttpClient发送http请求
+ +函数签名: + +```go +func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error) +``` + +示例:[运行](https://go.dev/play/p/jUSgynekH7G) + +```go +package main + +import ( + "fmt" + "net" + "time" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + request := &netutil.HttpRequest{ + RawURL: "https://jsonplaceholder.typicode.com/todos/1", + Method: "GET", + } + + httpClient := netutil.NewHttpClient() + resp, err := httpClient.SendRequest(request) + if err != nil || resp.StatusCode != 200 { + return + } + + type Todo struct { + UserId int `json:"userId"` + Id int `json:"id"` + Title string `json:"title"` + Completed bool `json:"completed"` + } + + var todo Todo + err = httpClient.DecodeResponse(resp, &todo) + if err != nil { + return + } + + fmt.Println(todo.Id) + + // Output: + // 1 +} +``` + +### DecodeResponse + +解析http响应体到目标结构体
+ +函数签名: + +```go +func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error +``` + +示例:[运行](https://go.dev/play/p/jUSgynekH7G) + +```go +package main + +import ( + "fmt" + "net" + "time" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + request := &netutil.HttpRequest{ + RawURL: "https://jsonplaceholder.typicode.com/todos/1", + Method: "GET", + } + + httpClient := netutil.NewHttpClient() + resp, err := httpClient.SendRequest(request) + if err != nil || resp.StatusCode != 200 { + return + } + + type Todo struct { + UserId int `json:"userId"` + Id int `json:"id"` + Title string `json:"title"` + Completed bool `json:"completed"` + } + + var todo Todo + err = httpClient.DecodeResponse(resp, &todo) + if err != nil { + return + } + + fmt.Println(todo.Id) + + // Output: + // 1 +} +``` + +### StructToUrlValues + +将结构体转为url values, 仅转化结构体导出字段并且包含`json` tag
+ +函数签名: + +```go +func StructToUrlValues(targetStruct any) url.Values +``` + +示例:[运行](https://go.dev/play/p/pFqMkM40w9z) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + type TodoQuery struct { + Id int `json:"id"` + UserId int `json:"userId"` + Name string `json:"name,omitempty"` + Status string + } + item := TodoQuery{ + Id: 1, + UserId: 123, + Name: "test", + Status: "completed", + } + queryValues := netutil.StructToUrlValues(item) + + fmt.Println(todoValues.Get("id")) + fmt.Println(todoValues.Get("userId")) + fmt.Println(todoValues.Get("name")) + fmt.Println(todoValues.Get("status")) + + // Output: + // 1 + // 123 + // test + // +} +``` + +### HttpGet + +发送http get请求。
+ +> ⚠️ 本函数已弃用,使用`SendRequest`代替。 + +函数签名: + +```go +// params[0] http请求header,类型必须是http.Header或者map[string]string +// params[1] http查询字符串,类型必须是url.Values或者map[string]string +// params[2] post请求体,类型必须是[]byte +// params[3] http client,类型必须是http.Client +func HttpGet(url string, params ...any) (*http.Response, error) +``` + +示例: + +```go +package main + +import ( + "fmt" + "io/ioutil" + "log" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + url := "https://jsonplaceholder.typicode.com/todos/1" + header := map[string]string{ + "Content-Type": "application/json", + } + + resp, err := netutil.HttpGet(url, header) + if err != nil { + log.Fatal(err) + } + + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println(body) +} +``` + +### HttpPost + +发送http post请求。
+ +> ⚠️ 本函数已弃用,使用`SendRequest`代替。 + +函数签名: + +```go +// params[0] http请求header,类型必须是http.Header或者map[string]string +// params[1] http查询字符串,类型必须是url.Values或者map[string]string +// params[2] post请求体,类型必须是[]byte +// params[3] http client,类型必须是http.Client +func HttpPost(url string, params ...any) (*http.Response, error) +``` + +示例: + +```go +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + url := "https://jsonplaceholder.typicode.com/todos" + header := map[string]string{ + "Content-Type": "application/x-www-form-urlencoded", + } + + postData := url.Values{} + postData.Add("userId", "1") + postData.Add("title", "TestToDo") + + resp, err := netutil.HttpPost(apiUrl, header, nil, postData) + if err != nil { + log.Fatal(err) + } + + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println(body) +} +``` + +### HttpPut + +发送http put请求。
+ +> ⚠️ 本函数已弃用,使用`SendRequest`代替。 + +函数签名: + +```go +// params[0] http请求header,类型必须是http.Header或者map[string]string +// params[1] http查询字符串,类型必须是url.Values或者map[string]string +// params[2] post请求体,类型必须是[]byte +// params[3] http client,类型必须是http.Client +func HttpPut(url string, params ...any) (*http.Response, error) +``` + +示例: + +```go +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + url := "https://jsonplaceholder.typicode.com/todos/1" + header := map[string]string{ + "Content-Type": "application/json", + } + type Todo struct { + Id int `json:"id"` + UserId int `json:"userId"` + Title string `json:"title"` + } + todo := Todo{1, 1, "TestPutToDo"} + bodyParams, _ := json.Marshal(todo) + + resp, err := netutil.HttpPut(url, header, nil, bodyParams) + if err != nil { + log.Fatal(err) + } + + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println(body) +} +``` + +### HttpDelete + +发送http delete请求。
+ +> ⚠️ 本函数已弃用,使用`SendRequest`代替。 + +函数签名: + +```go +// params[0] http请求header,类型必须是http.Header或者map[string]string +// params[1] http查询字符串,类型必须是url.Values或者map[string]string +// params[2] post请求体,类型必须是[]byte +// params[3] http client,类型必须是http.Client +func HttpDelete(url string, params ...any) (*http.Response, error) +``` + +示例: + +```go +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + url := "https://jsonplaceholder.typicode.com/todos/1" + resp, err := netutil.HttpDelete(url) + if err != nil { + log.Fatal(err) + } + + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println(body) +} +``` + +### HttpPatch + +发送http patch请求。
+ +> ⚠️ 本函数已弃用,使用`SendRequest`代替。 + +函数签名: + +```go +// params[0] http请求header,类型必须是http.Header或者map[string]string +// params[1] http查询字符串,类型必须是url.Values或者map[string]string +// params[2] post请求体,类型必须是[]byte +// params[3] http client,类型必须是http.Client +func HttpPatch(url string, params ...any) (*http.Response, error) +``` + +示例: + +```go +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + url := "https://jsonplaceholder.typicode.com/todos/1" + header := map[string]string{ + "Content-Type": "application/json", + } + type Todo struct { + Id int `json:"id"` + UserId int `json:"userId"` + Title string `json:"title"` + } + todo := Todo{1, 1, "TestPatchToDo"} + bodyParams, _ := json.Marshal(todo) + + resp, err := netutil.HttpPatch(url, header, nil, bodyParams) + if err != nil { + log.Fatal(err) + } + + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println(body) +} +``` + +### ParseHttpResponse + +将http请求响应解码成特定struct值
+ +函数签名: + +```go +func ParseHttpResponse(resp *http.Response, obj any) error +``` + +示例: + +```go +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + url := "https://jsonplaceholder.typicode.com/todos/1" + header := map[string]string{ + "Content-Type": "application/json", + } + + resp, err := netutil.HttpGet(url, header) + if err != nil { + log.Fatal(err) + } + + type Todo struct { + Id int `json:"id"` + UserId int `json:"userId"` + Title string `json:"title"` + Completed bool `json:"completed"` + } + + toDoResp := &Todo{} + err = netutil.ParseHttpResponse(resp, toDoResp) + if err != nil { + log.Fatal(err) + } + + fmt.Println(toDoResp) +} +``` + +### DownloadFile + +从指定的server地址下载文件。
+ +函数签名: + +```go +func DownloadFile(filepath string, url string) error +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + err := netutil.DownloadFile("./lancet_logo.jpg", "https://picx.zhimg.com/v2-fc82a4199749de9cfb71e32e54f489d3_720w.jpg?source=172ae18b") + + fmt.Println(err) +} +``` + +### UploadFile + +将文件上传指定的server地址。
+ +函数签名: + +```go +func UploadFile(filepath string, server string) (bool, error) +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + ok, err := netutil.UploadFile("./a.jpg", "http://www.xxx.com/bucket/test") + + fmt.Println(ok) + fmt.Println(err) +} +``` + +### IsPingConnected + +检查能否ping通主机。
+ +函数签名: + +```go +func IsPingConnected(host string) bool +``` + +示例:[运行](https://go.dev/play/p/q8OzTijsA87) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + result1 := netutil.IsPingConnected("www.baidu.com") + result2 := netutil.IsPingConnected("www.!@#&&&.com") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsTelnetConnected + +检查能否telnet到主机。
+ +函数签名: + +```go +func IsTelnetConnected(host string, port string) bool +``` + +示例:[运行](https://go.dev/play/p/yiLCGtQv_ZG) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + result1 := netutil.IsTelnetConnected("www.baidu.com", "80") + result2 := netutil.IsTelnetConnected("www.baidu.com", "123") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### BuildUrl + +创建url字符串。
+ +函数签名: + +```go +func BuildUrl(scheme, host, path string, query map[string][]string) (string, error) +``` + +示例:[运行](https://go.dev/play/p/JLXl1hZK7l4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + urlStr, err := netutil.BuildUrl( + "https", + "example.com", + "query", + map[string][]string{ + "a": {"foo", "bar"}, + "b": {"baz"}, + }, + ) + + fmt.Println(urlStr) + fmt.Println(err) + + // Output: + // https://example.com/query?a=foo&a=bar&b=baz + //向url添加查询参数。
+ +函数签名: + +```go +func AddQueryParams(urlStr string, params map[string][]string) (string, error) +``` + +示例:[运行](https://go.dev/play/p/JLXl1hZK7l4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + urlStr, err := netutil.BuildUrl( + "https", + "example.com", + "query", + map[string][]string{ + "a": {"foo", "bar"}, + "b": {"baz"}, + }, + ) + + fmt.Println(urlStr) + fmt.Println(err) + + // Output: + // https://example.com/query?a=foo&a=bar&b=baz + //返回传入参数的指针值。
+ +函数签名: + +```go +func Of[T any](v T) *T +``` + +示例:[运行](https://go.dev/play/p/HFd70x4DrMj) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/pointer" +) + +func main() { + result1 := pointer.Of(123) + result2 := pointer.Of("abc") + + fmt.Println(*result1) + fmt.Println(*result2) + + // Output: + // 123 + // abc +} +``` + +### Unwrap + +返回传入指针指向的值。
+ +函数签名: + +```go +func Unwrap[T any](p *T) T +``` + +示例:[运行](https://go.dev/play/p/cgeu3g7cjWb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/pointer" +) + +func main() { + a := 123 + b := "abc" + + result1 := pointer.Unwrap(&a) + result2 := pointer.Unwrap(&b) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 123 + // abc +} +``` + +### ExtractPointer + +返回传入interface的底层值。
+ +函数签名: + +```go +func ExtractPointer(value any) any +``` + +示例:[运行](https://go.dev/play/p/D7HFjeWU2ZP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/pointer" +) + +func main() { + a := 1 + b := &a + c := &b + d := &c + + result := pointer.ExtractPointer(d) + + fmt.Println(result) + + // Output: + // 1 +} +``` + +### UnwrapOr + +返回指针的值,如果指针为零值,则返回fallback。
+ +函数签名: + +```go +UnwrapOr[T any](p *T, fallback T) T +``` + +示例:[运行](https://go.dev/play/p/mmNaLC38W8C) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/pointer" +) + +func main() { + a := 123 + b := "abc" + + var c *int + var d *string + + result1 := pointer.UnwrapOr(&a, 456) + result2 := pointer.UnwrapOr(&b, "abc") + result3 := pointer.UnwrapOr(c, 456) + result4 := pointer.UnwrapOr(d, "def") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 123 + // abc + // 456 + // def +} +``` + +### UnwrapOrDefault + +返回指针的值,如果指针为零值,则返回相应零值。
+ +函数签名: + +```go +UnwrapOrDefault[T any](p *T) T +``` + +示例:[运行](https://go.dev/play/p/ZnGIHf8_o4E) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/pointer" +) + +func main() { + a := 123 + b := "abc" + + var c *int + var d *string + + result1 := pointer.UnwrapOrDefault(&a) + result2 := pointer.UnwrapOrDefault(&b) + result3 := pointer.UnwrapOrDefault(c) + result4 := pointer.UnwrapOrDefault(d) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 123 + // abc + // 0 + // +} +``` diff --git a/docs/api/packages/random.md b/docs/api/packages/random.md new file mode 100644 index 00000000..3c2aa83b --- /dev/null +++ b/docs/api/packages/random.md @@ -0,0 +1,551 @@ +# Random + +random 随机数生成器包,可以生成随机[]bytes, int, string。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/random" +) +``` + + + +## 目录 + +- [RandBytes](#RandBytes) +- [RandInt](#RandInt) +- [RandString](#RandString) +- [RandFromGivenSlice](#RandFromGivenSlice) +- [RandSliceFromGivenSlice](#RandSliceFromGivenSlice) +- [RandUpper](#RandUpper) +- [RandLower](#RandLower) +- [RandNumeral](#RandNumeral) +- [RandNumeralOrLetter](#RandNumeralOrLetter) +- [RandSymbolChar](#RandSymbolChar) +- [UUIdV4](#UUIdV4) +- [RandIntSlice](#RandIntSlice) +- [RandUniqueIntSlice](#RandUniqueIntSlice) +- [RandFloat](#RandFloat) +- [RandFloats](#RandFloats) +- [RandStringSlice](#RandStringSlice) +- [RandBool](#RandBool) +- [RandBoolSlice](#RandBoolSlice) +- [RandNumberOfLength](#RandNumberOfLength) + + + + +## 文档 + +### RandBytes + +生成随机字节切片
+ +函数签名: + +```go +func RandBytes(length int) []byte +``` + +示例:[运行](https://go.dev/play/p/EkiLESeXf8d) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randBytes := random.RandBytes(4) + fmt.Println(randBytes) +} +``` + +### RandInt + +生成随机int, 范围[min, max)
+ +函数签名: + +```go +func RandInt(min, max int) int +``` + +示例:[运行](https://go.dev/play/p/pXyyAAI5YxD) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + rInt := random.RandInt(1, 10) + fmt.Println(rInt) +} +``` + +### RandString + +生成给定长度的随机字符串,只包含字母(a-zA-Z)
+ +函数签名: + +```go +func RandString(length int) string +``` + +示例:[运行](https://go.dev/play/p/W2xvRUXA7Mi) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randStr := random.RandString(6) + fmt.Println(randStr) //pGWsze +} +``` + +### RandFromGivenSlice + +从给定切片中随机生成元素。
+ +函数签名: + +```go +func RandFromGivenSlice[T any](slice []T) T +``` + +示例:[运行](https://go.dev/play/p/UrkWueF6yYo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + nicknames := []string{"张三", "李四", "王五", "赵六", "钱七"} + randElm := random.RandFromGivenSlice(nicknames) + fmt.Println(randElm) +} +``` + +### RandSliceFromGivenSlice + +从给定切片中生成长度为 num 的随机切片。
+ +函数签名: + +```go +func RandSliceFromGivenSlice[T any](slice []T, num int, repeatable bool) []T +``` + +示例:[运行](https://go.dev/play/p/68UikN9d6VT) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + goods := []string{"apple", "banana", "cherry", "elderberry", "fig", "grape", "honeydew", "kiwi", "lemon","mango", "nectarine", "orange"} + + chosen3goods := random.RandSliceFromGivenSlice(goods, 3, false) + + fmt.Println(chosen3goods) +} +``` + +### RandUpper + +生成给定长度的随机大写字母字符串
+ +函数签名: + +```go +func RandUpper(length int) string +``` + +示例:[运行](https://go.dev/play/p/29QfOh0DVuh) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randStr := random.RandString(6) + fmt.Println(randStr) //PACWGF +} +``` + +### RandLower + +生成给定长度的随机小写字母字符串
+ +函数签名: + +```go +func RandLower(length int) string +``` + +示例:[运行](https://go.dev/play/p/XJtZ471cmtI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randStr := random.RandLower(6) + fmt.Println(randStr) //siqbew +} +``` + +### RandNumeral + +生成给定长度的随机数字字符串
+ +函数签名: + +```go +func RandNumeral(length int) string +``` + +示例:[运行](https://go.dev/play/p/g4JWVpHsJcf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randStr := random.RandNumeral(6) + fmt.Println(randStr) //035172 +} +``` + +### RandNumeralOrLetter + +生成给定长度的随机字符串(数字+字母)
+ +函数签名: + +```go +func RandNumeralOrLetter(length int) string +``` + +示例:[运行](https://go.dev/play/p/19CEQvpx2jD) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randStr := random.RandNumeralOrLetter(6) + fmt.Println(randStr) //0aW7cQ +} +``` + +### RandSymbolChar + +生成给定长度的随机符号字符串。
+ +函数签名: + +```go +func RandSymbolChar(length int) string +``` + +示例:[运行](https://go.dev/play/p/Im6ZJxAykOm) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randStr := random.RandSymbolChar(6) + fmt.Println(randStr) // 随机特殊字符字符串,例如: @#(_") +} +``` + +### UUIdV4 + +生成UUID v4字符串
+ +函数签名: + +```go +func UUIdV4() (string, error) +``` + +示例:[运行](https://go.dev/play/p/_Z9SFmr28ft) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + uuid, err := random.UUIdV4() + if err != nil { + return + } + fmt.Println(uuid) +} +``` + +### RandIntSlice + +生成一个特定长度的随机int切片,数值范围[min, max)。
+ +函数签名: + +```go +func RandIntSlice(length, min, max int) []int +``` + +示例:[运行](https://go.dev/play/p/GATTQ5xTEG8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + result := random.RandIntSlice(5, 0, 10) + fmt.Println(result) //[1 2 7 1 5] (random) +} +``` + +### RandUniqueIntSlice + +生成一个特定长度的,数值不重复的随机int切片,数值范围[min, max)。
+ +函数签名: + +```go +func RandUniqueIntSlice(length, min, max int) []int +``` + +示例:[运行](https://go.dev/play/p/uBkRSOz73Ec) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + result := random.RandUniqueIntSlice(5, 0, 10) + fmt.Println(result) //[0 4 7 1 5] (random) +} +``` + +### RandFloat + +生成一个随机float64数值,可以指定精度。数值范围[min, max)。
+ +函数签名: + +```go +func RandFloat(min, max float64, precision int) float64 +``` + +实例:[运行](https://go.dev/play/p/zbD_tuobJtr) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + floatNumber := random.RandFloat(1.0, 5.0, 2) + fmt.Println(floatNumber) //2.14 (random number) +} +``` + +### RandFloats + +生成一个特定长度的随机float64切片,可以指定数值精度。数值范围[min, max)。
+ +函数签名: + +```go +func RandFloats(n int, min, max float64, precision int) []float64 +``` + +实例:[运行](https://go.dev/play/p/I3yndUQ-rhh) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + floatNumbers := random.RandFloats(5, 1.0, 5.0, 2) + fmt.Println(floatNumber) //[3.42 3.99 1.3 2.38 4.23] (random) +} +``` + +### RandStringSlice + +生成随机字符串slice. 字符串类型需要是以下几种或者它们的组合: random.Numeral, random.LowwerLetters, random.UpperLetters random.Letters, random.SymbolChars, random.AllChars。
+ +函数签名: + +```go +func RandStringSlice(charset string, sliceLen, strLen int) []string +``` + +实例:[运行](https://go.dev/play/p/2_-PiDv3tGn) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + strs := random.RandStringSlice(random.Letters, 4, 6) + fmt.Println(strs) + + // output random string slice like below: + //[CooSMq RUFjDz FAeMPf heRyGv] +} +``` + +### RandBool + +生成随机bool值(true or false)。
+ +函数签名: + +```go +func RandBool() bool +``` + +实例:[运行](https://go.dev/play/p/to6BLc26wBv) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + result := random.RandBool() + fmt.Println(result) // true or false (random) +} +``` + +### RandBoolSlice + +生成特定长度的随机bool slice。
+ +函数签名: + +```go +func RandBoolSlice(length int) []bool +``` + +实例:[运行](https://go.dev/play/p/o-VSjPjnILI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + result := random.RandBoolSlice(2) + fmt.Println(result) // [true false] (random) +} +``` +### RandNumberOfLength + +生成指定长度的随机数。
+ +函数签名: + +```go +func RandNumberOfLength(len int) int +``` + +实例:[运行](https://go.dev/play/p/oyZbuV7bu7b) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + i := random.RandNumberOfLength(2) + fmt.Println(i) // 21 (random number of length 2) +} +``` \ No newline at end of file diff --git a/docs/api/packages/retry.md b/docs/api/packages/retry.md new file mode 100644 index 00000000..165bd737 --- /dev/null +++ b/docs/api/packages/retry.md @@ -0,0 +1,418 @@ +# Retry + +retry 重试执行函数直到函数运行成功或被 context cancel。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/retry" +) +``` + + + +## 目录 + +- [Context](#Context) +- [Retry](#Retry) +- [RetryFunc](#RetryFunc) +- [RetryDuration](#RetryDuration) +- [RetryTimes](#RetryTimes) +- [BackoffStrategy](#BackoffStrategy) +- [RetryWithCustomBackoff](#RetryWithCustomBackoff) +- [RetryWithLinearBackoff](#RetryWithLinearBackoff) +- [RetryWithExponentialWithJitterBackoff](#RetryWithExponentialWithJitterBackoff) + + + + +## 文档 + +### Context + +设置重试context参数
+ +函数签名: + +```go +func Context(ctx context.Context) +``` + +示例:[运行](https://go.dev/play/p/xnAOOXv9GkS) + +```go +import ( + "context" + "errors" + "fmt" + "lancet-demo/retry" + "time" +) + +func main() { + ctx, cancel := context.WithCancel(context.TODO()) + + number := 0 + increaseNumber := func() error { + number++ + if number > 3 { + cancel() + } + return errors.New("error occurs") + } + + duration := retry.RetryWithLinearBackoff(time.Microsecond*50) + + retry.Retry(increaseNumber, + duration, + retry.Context(ctx), + ) + + fmt.Println(number) + + // Output: + // 4 +} +``` + +### RetryFunc + +被重试执行的函数
+ +函数签名: + +```go +type RetryFunc func() error +``` + +示例:[运行](https://go.dev/play/p/nk2XRmagfVF) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +func main() { + number := 0 + var increaseNumber retry.RetryFunc = func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + duration := retry.RetryWithLinearBackoff(time.Microsecond*50) + + err := retry.Retry(increaseNumber, duration) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` + +### RetryTimes + +设置重试次数,默认5
+ +函数签名: + +```go +func RetryTimes(n uint) +``` + +示例:[运行](https://go.dev/play/p/ssfVeU2SwLO) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +func main() { + number := 0 + + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + err := retry.Retry(increaseNumber, retry.RetryTimes(2)) + if err != nil { + fmt.Println(err) + } + + // Output: + // function main.main.func1 run failed after 2 times retry +} +``` + +### Retry + +重试执行函数retryFunc,直到函数运行成功,或被context停止
+ +函数签名: + +```go +func Retry(retryFunc RetryFunc, opts ...Option) error +``` + +示例:[运行](https://go.dev/play/p/nk2XRmagfVF) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +func main() { + number := 0 + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + duration := retry.RetryWithLinearBackoff(time.Microsecond*50) + + err := retry.Retry(increaseNumber, duration) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` + +### BackoffStrategy + +定义计算退避间隔的方法的接口。
+ +函数签名: + +```go +// BackoffStrategy is an interface that defines a method for calculating backoff intervals. +type BackoffStrategy interface { + // CalculateInterval returns the time.Duration after which the next retry attempt should be made. + CalculateInterval() time.Duration +} +``` + +示例: + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +type ExampleCustomBackoffStrategy struct { + interval time.Duration +} + +func (c *ExampleCustomBackoffStrategy) CalculateInterval() time.Duration { + return c.interval + 1 +} + +func main() { + number := 0 + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + err := retry,Retry(increaseNumber, retry.RetryWithCustomBackoff(&示例CustomBackoffStrategy{interval: time.Microsecond * 50})) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` + +### RetryWithCustomBackoff + +设置自定义退避策略。
+ +函数签名: + +```go +func RetryWithCustomBackoff(backoffStrategy BackoffStrategy) Option +``` + +示例:[运行](https://go.dev/play/p/jIm_o2vb5Y4) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +type ExampleCustomBackoffStrategy struct { + interval time.Duration +} + +func (c *ExampleCustomBackoffStrategy) CalculateInterval() time.Duration { + return c.interval + 1 +} + +func main() { + number := 0 + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + err := retry,Retry(increaseNumber, retry.RetryWithCustomBackoff(&示例CustomBackoffStrategy{interval: time.Microsecond * 50})) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` + + +### RetryWithLinearBackoff + +设置线性策略退避。
+ +函数签名: + +```go +func RetryWithLinearBackoff(interval time.Duration) Option +``` + +示例:[运行](https://go.dev/play/p/PDet2ZQZwcB) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +func main() { + number := 0 + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + err := retry.Retry(increaseNumber, retry.RetryWithLinearBackoff(time.Microsecond*50)) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` + + +### RetryWithExponentialWithJitterBackoff + +设置指数策略退避。
+ +函数签名: + +```go +func RetryWithExponentialWithJitterBackoff(interval time.Duration, base uint64, maxJitter time.Duration) Option +``` + +示例:[运行](https://go.dev/play/p/xp1avQmn16X) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +func main() { + number := 0 + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + err := retry.Retry(increaseNumber, retry.RetryWithExponentialWithJitterBackoff(time.Microsecond*50, 2, time.Microsecond*25)) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` diff --git a/docs/api/packages/slice.md b/docs/api/packages/slice.md new file mode 100644 index 00000000..7787c3d5 --- /dev/null +++ b/docs/api/packages/slice.md @@ -0,0 +1,3164 @@ +# Slice + +slice 包包含操作切片的方法集合。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go) +- [https://github.com/duke-git/lancet/blob/main/slice/slice_concurrent.go](https://github.com/duke-git/lancet/blob/main/slice/slice_concurrent.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/slice" +) +``` + + + +## 目录 + +- [AppendIfAbsent](#AppendIfAbsent) +- [Contain](#Contain) +- [ContainBy](#ContainBy) +- [ContainSubSlice](#ContainSubSlice) +- [Chunk](#Chunk) +- [Compact](#Compact) +- [Concat](#Concat) +- [Count](#Count) +- [CountBy](#CountBy) +- [Difference](#Difference) +- [DifferenceBy](#DifferenceBy) +- [DifferenceWith](#DifferenceWith) +- [DeleteAt](#DeleteAt) +- [DeleteRange](#DeleteRange) +- [Drop](#Drop) +- [DropRight](#DropRight) +- [DropWhile](#DropWhile) +- [DropRightWhile](#DropRightWhile) +- [Every](#Every) +- [Equal](#Equal) +- [EqualWith](#EqualWith) +- [EqualUnordered](#EqualUnordered) +- [Filter](#Filter) +- [FilterConcurrent](#FilterConcurrent) +- [Finddeprecated](#Find) +- [FindBy](#FindBy) +- [FindLastdeprecated](#FindLast) +- [FindLastBy](#FindLastBy) +- [Flatten](#Flatten) +- [FlattenDeep](#FlattenDeep) +- [ForEach](#ForEach) +- [ForEachConcurrent](#ForEachConcurrent) +- [ForEachWithBreak](#ForEachWithBreak) +- [GroupBy](#GroupBy) +- [GroupWith](#GroupWith) +- [IntSlicedeprecated](#IntSlice) +- [InterfaceSlicedeprecated](#InterfaceSlice) +- [Intersection](#Intersection) +- [InsertAt](#InsertAt) +- [IndexOf](#IndexOf) +- [LastIndexOf](#LastIndexOf) +- [Map](#Map) +- [MapConcurrent](#MapConcurrent) +- [FilterMap](#FilterMap) +- [FlatMap](#FlatMap) +- [Merge](#Merge) +- [Reverse](#Reverse) +- [ReverseCopy](#ReverseCopy) +- [Reducedeprecated](#Reduce) +- [ReduceConcurrent](#ReduceConcurrent) +- [ReduceBy](#ReduceBy) +- [ReduceRight](#ReduceRight) +- [Replace](#Replace) +- [ReplaceAll](#ReplaceAll) +- [Repeat](#Repeat) +- [Shuffle](#Shuffle) +- [ShuffleCopy](#ShuffleCopy) +- [IsAscending](#IsAscending) +- [IsDescending](#IsDescending) +- [IsSorted](#IsSorted) +- [IsSortedByKey](#IsSortedByKey) +- [Sort](#Sort) +- [SortBy](#SortBy) +- [SortByField](#SortByField) +- [Some](#Some) +- [StringSlicedeprecated](#StringSlice) +- [SymmetricDifference](#SymmetricDifference) +- [ToSlice](#ToSlice) +- [ToSlicePointer](#ToSlicePointer) +- [Unique](#Unique) +- [UniqueBy](#UniqueBy) +- [UniqueByComparator](#UniqueByComparator) +- [UniqueByField](#UniqueByField) +- [UniqueByConcurrent](#UniqueByConcurrent) +- [Union](#Union) +- [UnionBy](#UnionBy) +- [UpdateAt](#UpdateAt) +- [Without](#Without) +- [KeyBy](#KeyBy) +- [Join](#Join) +- [Partition](#Partition) +- [SetToDefaultIf](#SetToDefaultIf) +- [Break](#Break) +- [RightPadding](#RightPadding) +- [LeftPadding](#LeftPadding) +- [Frequency](#Frequency) +- [JoinFunc](#JoinFunc) +- [ConcatBy](#ConcatBy) + + + + + +## 文档 + +### AppendIfAbsent + +当前切片中不包含值时,将该值追加到切片中
+ +函数签名: + +```go +func AppendIfAbsent[T comparable](slice []T, item T) []T +``` + +示例:[运行](https://go.dev/play/p/GNdv7Jg2Taj) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.AppendIfAbsent([]string{"a", "b"}, "b") + result2 := slice.AppendIfAbsent([]string{"a", "b"}, "c") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // [a b] + // [a b c] +} +``` + +### Contain + +判断slice是否包含value
+ +函数签名: + +```go +func Contain[T comparable](slice []T, target T) bool +``` + +示例:[运行](https://go.dev/play/p/_454yEHcNjf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.Contain([]string{"a", "b", "c"}, "a") + result2 := slice.Contain([]int{1, 2, 3}, 4) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### ContainBy + +根据predicate函数判断切片是否包含某个值。
+ +函数签名: + +```go +func ContainBy[T any](slice []T, predicate func(item T) bool) bool +``` + +示例:[运行](https://go.dev/play/p/49tkHfX4GNc) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + type foo struct { + A string + B int + } + + array1 := []foo{{A: "1", B: 1}, {A: "2", B: 2}} + result1 := slice.ContainBy(array1, func(f foo) bool { return f.A == "1" && f.B == 1 }) + result2 := slice.ContainBy(array1, func(f foo) bool { return f.A == "2" && f.B == 1 }) + + array2 := []string{"a", "b", "c"} + result3 := slice.ContainBy(array2, func(t string) bool { return t == "a" }) + result4 := slice.ContainBy(array2, func(t string) bool { return t == "d" }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // false + // true + // false +} +``` + +### ContainSubSlice + +判断slice是否包含subslice
+ +函数签名: + +```go +func ContainSubSlice[T comparable](slice, subSlice []T) bool +``` + +示例:[运行](https://go.dev/play/p/bcuQ3UT6Sev) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.ContainSubSlice([]string{"a", "b", "c"}, []string{"a", "b"}) + result2 := slice.ContainSubSlice([]string{"a", "b", "c"}, []string{"a", "d"}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### Chunk + +按照size参数均分slice
+ +函数签名: + +```go +func Chunk[T any](slice []T, size int) [][]T +``` + +示例:[运行](https://go.dev/play/p/b4Pou5j2L_C) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + arr := []string{"a", "b", "c", "d", "e"} + + result1 := slice.Chunk(arr, 1) + result2 := slice.Chunk(arr, 2) + result3 := slice.Chunk(arr, 3) + result4 := slice.Chunk(arr, 4) + result5 := slice.Chunk(arr, 5) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // [[a] [b] [c] [d] [e]] + // [[a b] [c d] [e]] + // [[a b c] [d e]] + // [[a b c d] [e]] + // [[a b c d e]] +} +``` + +### Compact + +去除slice中的假值(false values are false, nil, 0, "")
+ +函数签名: + +```go +func Compact[T comparable](slice []T) []T +``` + +示例:[运行](https://go.dev/play/p/pO5AnxEr3TK) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.Compact([]int{0}) + result2 := slice.Compact([]int{0, 1, 2, 3}) + result3 := slice.Compact([]string{"", "a", "b", "0"}) + result4 := slice.Compact([]bool{false, true, true}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [] + // [1 2 3] + // [a b 0] + // [true true] +} +``` + +### Concat + +创建一个新的切片,将传入的切片拼接起来返回。
+ +函数签名: + +```go +func Concat[T any](slices ...[]T) []T +``` + +示例:[运行](https://go.dev/play/p/gPt-q7zr5mk) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.Concat([]int{1, 2}, []int{3, 4}) + result2 := slice.Concat([]string{"a", "b"}, []string{"c"}, []string{"d"}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // [1 2 3 4] + // [a b c d] +} +``` + +### Count + +返回切片中指定元素的个数
+ +函数签名: + +```go +func Count[T comparable](slice []T, item T) int +``` + +示例:[运行](https://go.dev/play/p/Mj4oiEnQvRJ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 3, 4} + + result1 := slice.Count(nums, 1) + result2 := slice.Count(nums, 3) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1 + // 2 +} +``` + +### CountBy + +遍历切片,对每个元素执行函数predicate. 返回符合函数返回值为true的元素的个数.
+ +函数签名: + +```go +func CountBy[T any](slice []T, predicate func(index int, item T) bool) int +``` + +示例:[运行](https://go.dev/play/p/tHOccTMDZCC) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result := slice.CountBy(nums, isEven) + + fmt.Println(result) + + // Output: + // 2 +} +``` + +### Difference + +创建一个切片,其元素不包含在另一个给定切片中
+ +函数签名: + +```go +func Difference[T comparable](slice, comparedSlice []T) []T +``` + +示例:[运行](https://go.dev/play/p/VXvadzLzhDa) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + s1 := []int{1, 2, 3, 4, 5} + s2 := []int{4, 5, 6} + + result := slice.Difference(s1, s2) + + fmt.Println(result) + + // Output: + // [1 2 3] +} +``` + +### DifferenceBy + +将两个slice中的每个元素调用iteratee函数,并比较它们的返回值,如果不相等返回在slice中对应的值
+ +函数签名: + +```go +func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T +``` + +示例:[运行](https://go.dev/play/p/DiivgwM5OnC) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + s1 := []int{1, 2, 3, 4, 5} + s2 := []int{3, 4, 5} + + addOne := func(i int, v int) int { + return v + 1 + } + + result := slice.DifferenceBy(s1, s2, addOne) + + fmt.Println(result) + + // Output: + // [1 2] +} +``` + +### DifferenceWith + +接受比较器函数,该比较器被调用以将切片的元素与值进行比较。 结果值的顺序和引用由第一个切片确定
+ +函数签名: + +```go +func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T +``` + +示例:[运行](https://go.dev/play/p/v2U2deugKuV) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + s1 := []int{1, 2, 3, 4, 5} + s2 := []int{4, 5, 6, 7, 8} + + isDouble := func(v1, v2 int) bool { + return v2 == 2*v1 + } + + result := slice.DifferenceWith(s1, s2, isDouble) + + fmt.Println(result) + + // Output: + // [1 5] +} +``` + +### DeleteAt + +删除切片中指定索引的元素(不修改原切片)。
+ +函数签名: + +```go +func DeleteAt[T any](slice []T, index int) []T +``` + +示例:[运行](https://go.dev/play/p/800B1dPBYyd) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + chars := []string{"a", "b", "c", "d", "e"} + + result1 := slice.DeleteAt(chars, 0) + result2 := slice.DeleteAt(chars, 4) + result3 := slice.DeleteAt(chars, 5) + result4 := slice.DeleteAt(chars, 6) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [b c d e] + // [a b c d] + // [a b c d] + // [a b c d] + +} +``` + +### DeleteRange + +删除切片中指定索引范围的元素(不修改原切片)。
+ +函数签名: + +```go +func DeleteRange[T any](slice []T, start, end int) []T +``` + +示例:[运行](https://go.dev/play/p/945HwiNrnle) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + chars := []string{"a", "b", "c", "d", "e"} + + result1 := DeleteRange(chars, 0, 0) + result2 := DeleteRange(chars, 0, 1) + result3 := DeleteRange(chars, 0, 3) + result4 := DeleteRange(chars, 0, 4) + result5 := DeleteRange(chars, 0, 5) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // [a b c d e] + // [b c d e] + // [d e] + // [e] + // [] + +} +``` + +### Drop + +从切片的头部删除n个元素。
+ +函数签名: + +```go +func Drop[T any](slice []T, n int) []T +``` + +示例:[运行](https://go.dev/play/p/jnPO2yQsT8H) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.Drop([]string{"a", "b", "c"}, 0) + result2 := slice.Drop([]string{"a", "b", "c"}, 1) + result3 := slice.Drop([]string{"a", "b", "c"}, -1) + result4 := slice.Drop([]string{"a", "b", "c"}, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [a b c] + // [b c] + // [a b c] + // [] +} +``` + +### DropRight + +从切片的尾部删除n个元素。
+ +函数签名: + +```go +func DropRight[T any](slice []T, n int) []T +``` + +示例:[运行](https://go.dev/play/p/8bcXvywZezG) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.DropRight([]string{"a", "b", "c"}, 0) + result2 := slice.DropRight([]string{"a", "b", "c"}, 1) + result3 := slice.DropRight([]string{"a", "b", "c"}, -1) + result4 := slice.DropRight([]string{"a", "b", "c"}, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [a b c] + // [a b] + // [a b c] + // [] +} +``` + +### DropWhile + +从切片的头部删除n个元素,这个n个元素满足predicate函数返回true。
+ +函数签名: + +```go +func DropWhile[T any](slice []T, predicate func(item T) bool) []T +``` + +示例:[运行](https://go.dev/play/p/4rt252UV_qs) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.DropWhile(numbers, func(n int) bool { + return n != 2 + }) + result2 := slice.DropWhile(numbers, func(n int) bool { + return true + }) + result3 := slice.DropWhile(numbers, func(n int) bool { + return n == 0 + }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // [2 3 4 5] + // [] + // [1 2 3 4 5] +} +``` + +### DropRightWhile + +从切片的尾部删除n个元素,这个n个元素满足predicate函数返回true。
+ +函数签名: + +```go +func DropRightWhile[T any](slice []T, predicate func(item T) bool) []T +``` + +示例:[运行](https://go.dev/play/p/6wyK3zMY56e) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + numbers := []int{1, 2, 3, 4, 5} + + result1 := slice.DropRightWhile(numbers, func(n int) bool { + return n != 2 + }) + result2 := slice.DropRightWhile(numbers, func(n int) bool { + return true + }) + result3 := slice.DropRightWhile(numbers, func(n int) bool { + return n == 0 + }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // [1 2] + // [] + // [1 2 3 4 5] +} +``` + +### Every + +如果切片中的所有值都通过谓词函数,则返回true。 函数签名应该是func(index int, value any) bool
+ +函数签名: + +```go +func Every[T any](slice []T, predicate func(index int, item T) bool) bool +``` + +示例:[运行](https://go.dev/play/p/R8U6Sl-j8cD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result := slice.Every(nums, isEven) + + fmt.Println(result) + + // Output: + // false +} +``` + +### Equal + +检查两个切片是否相等,相等条件:切片长度相同,元素顺序和值都相同
+ +函数签名: + +```go +func Equal[T comparable](slice1, slice2 []T) bool +``` + +示例:[运行](https://go.dev/play/p/WcRQJ37ifPa) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + s1 := []int{1, 2, 3} + s2 := []int{1, 2, 3} + s3 := []int{1, 3, 2} + + result1 := slice.Equal(s1, s2) + result2 := slice.Equal(s1, s3) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### EqualWith + +检查两个切片是否相等,相等条件:对两个切片的元素调用比较函数comparator,返回true
+ +函数签名: + +```go +func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool +``` + +示例:[运行](https://go.dev/play/p/b9iygtgsHI1) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + s1 := []int{1, 2, 3} + s2 := []int{2, 4, 6} + + isDouble := func(a, b int) bool { + return b == a*2 + } + + result := slice.EqualWith(s1, s2, isDouble) + + fmt.Println(result) + + // Output: + // true +} +``` + +### EqualUnordered + +检查两个切片是否相等,元素数量相同,值相等,不考虑元素顺序。
+ +函数签名: + +```go +func EqualUnordered[T comparable](slice1, slice2 []T) bool +``` + +示例:[运行](https://go.dev/play/p/n8fSc2w8ZgX) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.EqualUnordered([]int{1, 2, 3}, []int{3, 2, 1}) + result2 := slice.EqualUnordered([]int{1, 2, 3}, []int{4, 5, 6}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### Filter + +返回切片中通过predicate函数真值测试的所有元素
+ +函数签名: + +```go +func Filter[T any](slice []T, predicate func(index int, item T) bool) []T +``` + +示例:[运行](https://go.dev/play/p/SdPna-7qK4T) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result := slice.Filter(nums, isEven) + + fmt.Println(result) + + // Output: + // [2 4] +} +``` + +### FilterConcurrent + +对slice并发执行filter操作。
+ +函数签名: + +```go +func FilterConcurrent[T any](slice []T, predicate func(index int, item T) bool, numThreads int) []T +``` + +示例:[运行](https://go.dev/play/p/t_pkwerIRVx) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result := slice.FilterConcurrent(nums, isEven, 2) + + fmt.Println(result) + + // Output: + // [2 4] +} +``` + +### Find + +遍历slice的元素,返回第一个通过predicate函数真值测试的元素
+ +> ⚠️ 本函数已弃用,使用`FindBy`代替。 + +函数签名: + +```go +func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) +``` + +示例:[运行](https://go.dev/play/p/CBKeBoHVLgq) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result, ok := slice.Find(nums, isEven) + + fmt.Println(*result) + fmt.Println(ok) + + // Output: + // 2 + // true +} +``` + +### FindBy + +遍历slice的元素,返回第一个通过predicate函数真值测试的元素
+ +函数签名: + +```go +func FindBy[T any](slice []T, predicate func(index int, item T) bool) (v T, ok bool) +``` + +示例:[运行](https://go.dev/play/p/n1lysBYl-GB) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result, ok := slice.FindBy(nums, isEven) + + fmt.Println(result) + fmt.Println(ok) + + // Output: + // 2 + // true +} +``` + +### FindLast + +遍历slice的元素,返回最后一个通过predicate函数真值测试的元素。
+ +> ⚠️ 本函数已弃用,使用`FindLastBy`代替。 + +函数签名: + +```go +func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) +``` + +示例:[运行](https://go.dev/play/p/FFDPV_j7URd) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result, ok := slice.FindLast(nums, isEven) + + fmt.Println(*result) + fmt.Println(ok) + + // Output: + // 4 + // true +} +``` + +### FindLastBy + +从遍历slice的元素,返回最后一个通过predicate函数真值测试的元素。
+ +函数签名: + +```go +func FindLastBy[T any](slice []T, predicate func(index int, item T) bool) (v T, ok bool) +``` + +示例:[运行](https://go.dev/play/p/8iqomzyCl_s) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result, ok := slice.FindLastBy(nums, isEven) + + fmt.Println(result) + fmt.Println(ok) + + // Output: + // 4 + // true +} +``` + +### Flatten + +将切片压平一层
+ +函数签名: + +```go +func Flatten(slice any) any +``` + +示例:[运行](https://go.dev/play/p/hYa3cBEevtm) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + arrs := [][][]string{{{"a", "b"}}, {{"c", "d"}}} + + result := slice.Flatten(arrs) + + fmt.Println(result) + + // Output: + // [[a b] [c d]] +} +``` + +### FlattenDeep + +flattens slice recursive.
+ +函数签名: + +```go +func FlattenDeep(slice any) any +``` + +示例:[运行](https://go.dev/play/p/yjYNHPyCFaF) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + arrs := [][][]string{{{"a", "b"}}, {{"c", "d"}}} + + result := slice.FlattenDeep(arrs) + + fmt.Println(result) + + // Output: + // [a b c d] +} +``` + +### ForEach + +遍历切片的元素并为每个元素调用iteratee函数
+ +函数签名: + +```go +func ForEach[T any](slice []T, iteratee func(index int, item T)) +``` + +示例:[运行](https://go.dev/play/p/DrPaa4YsHRF) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3} + + var result []int + addOne := func(_ int, v int) { + result = append(result, v+1) + } + + slice.ForEach(nums, addOne) + + fmt.Println(result) + + // Output: + // [2 3 4] +} +``` + +### ForEachConcurrent + +对slice并发执行foreach操作。
+ +函数签名: + +```go +func ForEachConcurrent[T any](slice []T, iteratee func(index int, item T), numThreads int) +``` + +示例:[运行](https://go.dev/play/p/kT4XW7DKVoV) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5, 6, 7, 8} + + result := make([]int, len(nums)) + + addOne := func(index int, value int) { + result[index] = value + 1 + } + + slice.ForEachConcurrent(nums, addOne, 4) + + fmt.Println(result) + + // Output: + // [2 3 4 5 6 7 8 9] +} +``` + + +### ForEachWithBreak + +遍历切片的元素并为每个元素调用iteratee函数,当iteratee函数返回false时,终止遍历。
+ +函数签名: + +```go +func ForEachWithBreak[T any](slice []T, iteratee func(index int, item T) bool) +``` + +示例:[运行](https://go.dev/play/p/qScs39f3D9W) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + numbers := []int{1, 2, 3, 4, 5} + + var sum int + + slice.ForEachWithBreak(numbers, func(_, n int) bool { + if n > 3 { + return false + } + sum += n + return true + }) + + fmt.Println(sum) + + // Output: + // 6 +} +``` + +### GroupBy + +迭代切片的元素,每个元素将按条件分组,返回两个切片
+ +函数签名: + +```go +func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T) +``` + +示例:[运行](https://go.dev/play/p/QVkPxzPR0iA) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + even, odd := slice.GroupBy(nums, isEven) + + fmt.Println(even) + fmt.Println(odd) + + // Output: + // [2 4] + // [1 3 5] +} +``` + +### GroupWith + +创建一个map,key是iteratee遍历slice中的每个元素返回的结果。 分组值的顺序是由他们出现在slice中的顺序确定的。每个键对应的值负责生成key的元素组成的数组。iteratee调用1个参数: (value)
+ +函数签名: + +```go +func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T +``` + +示例:[运行](https://go.dev/play/p/ApCvMNTLO8a) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []float64{6.1, 4.2, 6.3} + + floor := func(num float64) float64 { + return math.Floor(num) + } + + result := slice.GroupWith(nums, floor) //map[float64][]float64 + + fmt.Println(result) + + // Output: + // map[4:[4.2] 6:[6.1 6.3]] +} +``` + +### IntSlice + +将接口切片转换为int切片
+ +> ⚠️ 本函数已弃用,使用go1.18+泛型代替。 + +函数签名: + +```go +func IntSlice(slice any) []int +``` + +示例:[运行](https://go.dev/play/p/UQDj-on9TGN) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []interface{}{1, 2, 3} + + result := slice.IntSlice(nums) //[]int{1, 2, 3} + fmt.Println(result) + + // Output: + // [1 2 3] +} +``` + +### InterfaceSlice + +将值转换为接口切片
+ +> ⚠️ 本函数已弃用,使用go1.18+泛型代替。 + +函数签名: + +```go +func InterfaceSlice(slice any) []any +``` + +示例:[运行](https://go.dev/play/p/FdQXF0Vvqs-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "b", "c"} + + result := slice.InterfaceSlice(strs) //[]interface{}{"a", "b", "c"} + fmt.Println(result) + + // Output: + // [a b c] +} +``` + +### Intersection + +多个切片的交集
+ +函数签名: + +```go +func Intersection[T comparable](slices ...[]T) []T +``` + +示例:[运行](https://go.dev/play/p/anJXfB5wq_t) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums1 := []int{1, 2, 3} + nums2 := []int{2, 3, 4} + + result := slice.Intersection(nums1, nums2) + + fmt.Println(result) + + // Output: + // [2 3] +} +``` + +### InsertAt + +将元素插入到索引处的切片中
+ +函数签名: + +```go +func InsertAt[T any](slice []T, index int, value any) []T +``` + +示例:[运行](https://go.dev/play/p/hMLNxPEGJVE) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.InsertAt([]string{"a", "b", "c"}, 0, "1") + result2 := slice.InsertAt([]string{"a", "b", "c"}, 1, "1") + result3 := slice.InsertAt([]string{"a", "b", "c"}, 2, "1") + result4 := slice.InsertAt([]string{"a", "b", "c"}, 3, "1") + result5 := slice.InsertAt([]string{"a", "b", "c"}, 0, []string{"1", "2", "3"}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // [1 a b c] + // [a 1 b c] + // [a b 1 c] + // [a b c 1] + // [1 2 3 a b c] +} +``` + +### IndexOf + +返回在切片中找到值的第一个匹配项的索引,如果找不到值,则返回-1
+ +函数签名: + +```go +func IndexOf[T comparable](slice []T, item T) int +``` + +示例:[运行](https://go.dev/play/p/MRN1f0FpABb) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "a", "b", "c"} + + result1 := slice.IndexOf(strs, "a") + result2 := slice.IndexOf(strs, "d") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // -1 +} +``` + +### LastIndexOf + +返回在切片中找到最后一个值的索引,如果找不到该值,则返回-1
+ +函数签名: + +```go +func LastIndexOf[T comparable](slice []T, item T) int +``` + +示例:[运行](https://go.dev/play/p/DokM4cf1IKH) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "a", "b", "c"} + + result1 := slice.LastIndexOf(strs, "a") + result2 := slice.LastIndexOf(strs, "d") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1 + // -1 +} +``` + +### Map + +对slice中的每个元素执行map函数以创建一个新切片。
+ +函数签名: + +```go +func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U +``` + +示例:[运行](https://go.dev/play/p/biaTefqPquw) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3} + + addOne := func(_ int, v int) int { + return v + 1 + } + + result := slice.Map(nums, addOne) + + fmt.Println(result) + + // Output: + // [2 3 4] +} +``` + +### MapConcurrent + +对slice并发执行map操作。
+ +函数签名: + +```go +func MapConcurrent[T any, U any](slice []T, iteratee func(index int, item T) U, numThreads int) []U +``` + +示例:[运行](https://go.dev/play/p/H1ehfPkPen0) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5, 6} + + result := slice.MapConcurrent(nums, func(_, n int) int { + return n * n + }, 4) + + fmt.Println(result) + + // Output: + // [1 4 9 16 25 36] +} +``` + +### FilterMap + +返回一个将filter和map操作应用于给定切片的切片。 iteratee回调函数应该返回两个值:1,结果值。2,结果值是否应该被包含在返回的切片中。
+ +函数签名: + +```go +func FilterMap[T any, U any](slice []T, iteratee func(index int, item T) (U, bool)) []U +``` + +示例:[运行](https://go.dev/play/p/J94SZ_9MiIe) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + getEvenNumStr := func(i, num int) (string, bool) { + if num%2 == 0 { + return strconv.FormatInt(int64(num), 10), true + } + return "", false + } + + result := slice.FilterMap(nums, getEvenNumStr) + + fmt.Printf("%#v", result) + + // Output: + // []string{"2", "4"} +} +``` + +### FlatMap + +将切片转换为其它类型切片。
+ +函数签名: + +```go +func FlatMap[T any, U any](slice []T, iteratee func(index int, item T) []U) []U +``` + +示例:[运行](https://go.dev/play/p/_QARWlWs1N_F) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4} + + result := slice.FlatMap(nums, func(i int, num int) []string { + s := "hi-" + strconv.FormatInt(int64(num), 10) + return []string{s} + }) + + fmt.Printf("%#v", result) + + // Output: + // []string{"hi-1", "hi-2", "hi-3", "hi-4"} +} +``` + +### Merge + +合并多个切片(不会消除重复元素).
+ +> ⚠️ 本函数已弃用,使用`Concat`代替。 + +函数签名: + +```go +func Merge[T any](slices ...[]T) []T +``` + +示例:[运行](https://go.dev/play/p/lbjFp784r9N) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums1 := []int{1, 2, 3} + nums2 := []int{3, 4} + + result := slice.Merge(nums1, nums2) + + fmt.Println(result) + + // Output: + // [1 2 3 3 4] +} +``` + +### Reverse + +反转切片中的元素顺序
+ +函数签名: + +```go +func Reverse[T any](slice []T) +``` + +示例:[运行](https://go.dev/play/p/8uI8f1lwNrQ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "b", "c", "d"} + + slice.Reverse(strs) + + fmt.Println(strs) + + // Output: + // [d c b a] +} +``` + +### ReverseCopy + +反转切片中的元素顺序, 不改变原slice。
+ +函数签名: + +```go +func ReverseCopy[T any](slice []T) []T +``` + +示例:[运行](https://go.dev/play/p/c9arEaP7Cg-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "b", "c", "d"} + + reversedStrs := slice.ReverseCopy(strs) + + fmt.Println(reversedStrs) + fmt.Println(strs) + + // Output: + // [d c b a] + // [a b c d] +} +``` + +### Reduce + +将切片中的元素依次运行iteratee函数,返回运行结果。
+ +> ⚠️ 本函数已弃用,使用`ReduceBy`代替。 + +函数签名: + +```go +func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T +``` + +示例:[运行](https://go.dev/play/p/_RfXJJWIsIm) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3} + + sum := func(_ int, v1, v2 int) int { + return v1 + v2 + } + + result := slice.Reduce(nums, sum, 0) + + fmt.Println(result) + + // Output: + // 6 +} +``` + +### ReduceConcurrent + +对切片元素执行并发reduce操作。
+ +函数签名: + +```go +func ReduceConcurrent[T any](slice []T, initial T, reducer func(index int, item T, agg T) T, numThreads int) T +``` + +示例:[运行](https://go.dev/play/p/Tjwe6OtaG07) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + + result := slice.ReduceConcurrent(nums, 0, func(_ int, item, agg int) int { + return agg + item + }, 1) + + fmt.Println(result) + + // Output: + // 55 +} +``` + +### ReduceBy + +对切片元素执行reduce操作。
+ +函数签名: + +```go +func ReduceBy[T any, U any](slice []T, initial U, reducer func(index int, item T, agg U) U) U +``` + +示例:[运行](https://go.dev/play/p/YKDpLi7gtee) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.ReduceBy([]int{1, 2, 3, 4}, 0, func(_ int, item int, agg int) int { + return agg + item + }) + + result2 := slice.ReduceBy([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string { + return agg + fmt.Sprintf("%v", item) + }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 10 + // 1234 +} +``` + +### ReduceRight + +类似ReduceBy操作,迭代切片元素顺序从右至左。
+ +函数签名: + +```go +func ReduceRight[T any, U any](slice []T, initial U, reducer func(index int, item T, agg U) U) U +``` + +示例:[运行](https://go.dev/play/p/qT9dZC03A1K) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.ReduceRight([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string { + return agg + fmt.Sprintf("%v", item) + }) + + fmt.Println(result) + + // Output: + // 4321 +} +``` + +### Replace + +返回切片的副本,其中前n个不重叠的old替换为new
+ +函数签名: + +```go +func Replace[T comparable](slice []T, old T, new T, n int) []T +``` + +示例:[运行](https://go.dev/play/p/P5mZp7IhOFo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "b", "c", "a"} + + result1 := slice.Replace(strs, "a", "x", 0) + result2 := slice.Replace(strs, "a", "x", 1) + result3 := slice.Replace(strs, "a", "x", 2) + result4 := slice.Replace(strs, "a", "x", 3) + result5 := slice.Replace(strs, "a", "x", -1) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // [a b c a] + // [x b c a] + // [x b c x] + // [x b c x] + // [x b c x] +} +``` + +### ReplaceAll + +返回切片的副本,将其中old全部替换为new
+ +函数签名: + +```go +func ReplaceAll[T comparable](slice []T, old T, new T) []T +``` + +示例:[运行](https://go.dev/play/p/CzqXMsuYUrx) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.ReplaceAll([]string{"a", "b", "c", "a"}, "a", "x") + + fmt.Println(result) + + // Output: + // [x b c x] +} +``` + +### Repeat + +创建一个切片,包含n个传入的item
+ +函数签名: + +```go +func Repeat[T any](item T, n int) []T +``` + +示例:[运行](https://go.dev/play/p/1CbOmtgILUU) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.Repeat("a", 3) + + fmt.Println(result) + + // Output: + // [a a a] +} +``` + +### Shuffle + +随机打乱切片中的元素顺序。
+ +函数签名: + +```go +func Shuffle[T any](slice []T) []T +``` + +示例:[运行](https://go.dev/play/p/YHvhnWGU3Ge) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + result := slice.Shuffle(nums) + + fmt.Println(res) + + // Output: + // [3 1 5 4 2] (random order) +} +``` + +### ShuffleCopy + +随机打乱切片中的元素顺序, 不改变原切片。
+ +函数签名: + +```go +func ShuffleCopy[T any](slice []T) []T +``` + +示例:[运行](https://go.dev/play/p/vqDa-Gs1vT0) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + result := slice.ShuffleCopy(nums) + + fmt.Println(result) + fmt.Println(nums) + + // Output: + // [3 1 5 4 2] (random order) + // [1 2 3 4 5] +} +``` + +### IsAscending + +检查切片元素是否按升序排列。
+ +函数签名: + +```go +func IsAscending[T constraints.Ordered](slice []T) bool +``` + +示例:[运行](https://go.dev/play/p/9CtsFjet4SH) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.IsAscending([]int{1, 2, 3, 4, 5}) + result2 := slice.IsAscending([]int{5, 4, 3, 2, 1}) + result3 := slice.IsAscending([]int{2, 1, 3, 4, 5}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsDescending + +检查切片元素是否按降序排列。
+ +函数签名: + +```go +func IsDescending[T constraints.Ordered](slice []T) bool +``` + +示例:[运行](https://go.dev/play/p/U_LljFXma14) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.IsDescending([]int{5, 4, 3, 2, 1}) + result2 := slice.IsDescending([]int{1, 2, 3, 4, 5}) + result3 := slice.IsDescending([]int{2, 1, 3, 4, 5}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsSorted + +检查切片元素是否是有序的(升序或降序)。
+ +函数签名: + +```go +func IsSorted[T constraints.Ordered](slice []T) bool +``` + +示例:[运行](https://go.dev/play/p/nCE8wPLwSA-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.IsSorted([]int{5, 4, 3, 2, 1}) + result2 := slice.IsSorted([]int{1, 2, 3, 4, 5}) + result3 := slice.IsSorted([]int{2, 1, 3, 4, 5}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### IsSortedByKey + +通过iteratee函数,检查切片元素是否是有序的。
+ +函数签名: + +```go +func IsSortedByKey[T any, K constraints.Ordered](slice []T, iteratee func(item T) K) bool +``` + +示例:[运行](https://go.dev/play/p/tUoGB7DOHI4) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.IsSortedByKey([]string{"a", "ab", "abc"}, func(s string) int { + return len(s) + }) + result2 := slice.IsSortedByKey([]string{"abc", "ab", "a"}, func(s string) int { + return len(s) + }) + result3 := slice.IsSortedByKey([]string{"abc", "a", "ab"}, func(s string) int { + return len(s) + }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### Sort + +对任何有序类型(数字或字符串)的切片进行排序,使用快速排序算法。 默认排序顺序为升序 (asc),如果需要降序,请将参数 `sortOrder` 设置为 `desc`。 Ordered类型:数字(所有整数浮点数)或字符串。
+ +函数签名: + +```go +func Sort[T constraints.Ordered](slice []T, sortOrder ...string) +``` + +示例:[运行](https://go.dev/play/p/V9AVjzf_4Fk) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + numbers := []int{1, 4, 3, 2, 5} + + slice.Sort(numbers) + fmt.Println(numbers) // [1 2 3 4 5] + + slice.Sort(numbers, "desc") + fmt.Println(numbers) // [5 4 3 2 1] + + strings := []string{"a", "d", "c", "b", "e"} + + slice.Sort(strings) + fmt.Println(strings) //[a b c d e} + + slice.Sort(strings, "desc") + fmt.Println(strings) //[e d c b a] +} +``` + +### SortBy + +按照less函数确定的升序规则对切片进行排序。排序不保证稳定性
+ +函数签名: + +```go +func SortBy[T any](slice []T, less func(a, b T) bool) +``` + +示例:[运行](https://go.dev/play/p/DAhLQSZEumm) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + numbers := []int{1, 4, 3, 2, 5} + + slice.SortBy(numbers, func(a, b int) bool { + return a < b + }) + fmt.Println(numbers) // [1 2 3 4 5] + + type User struct { + Name string + Age uint + } + + users := []User{ + {Name: "a", Age: 21}, + {Name: "b", Age: 15}, + {Name: "c", Age: 100}} + + slice.SortBy(users, func(a, b User) bool { + return a.Age < b.Age + }) + + fmt.Printf("sort users by age: %v", users) + + // output + // [{b 15} {a 21} {c 100}] +} +``` + +### SortByField + +按字段对结构体切片进行排序。slice元素应为struct,排序字段field类型应为int、uint、string或bool。 默认排序类型是升序(asc),如果是降序,设置 sortType 为 desc
+ +函数签名: + +```go +func SortByField(slice any, field string, sortType ...string) error +``` + +示例:[运行](https://go.dev/play/p/fU1prOBP9p1) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + type User struct { + Name string + Age uint + } + + users := []User{ + {Name: "a", Age: 21}, + {Name: "b", Age: 15}, + {Name: "c", Age: 100}} + + err := slice.SortByField(users, "Age", "desc") + if err != nil { + return + } + + fmt.Println(users) + + // Output: + // [{c 100} {a 21} {b 15}] +} +``` + +### Some + +如果列表中的任何值通过谓词函数,则返回true
+ +函数签名: + +```go +func Some[T any](slice []T, predicate func(index int, item T) bool) bool +``` + +示例:[运行](https://go.dev/play/p/4pO9Xf9NDGS) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result := slice.Some(nums, isEven) + + fmt.Println(result) + + // Output: + // true +} +``` + +### StringSlice + +将接口切片转换为字符串切片
+ +> ⚠️ 本函数已弃用,使用go1.18+泛型代替。 + +函数签名: + +```go +func StringSlice(slice any) []string +``` + +示例:[运行](https://go.dev/play/p/W0TZDWCPFcI) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []interface{}{"a", "b", "c"} + + result := slice.StringSlice(strs) //[]string{"a", "b", "c"} + fmt.Println(result) + + // Output: + // [a b c] +} +``` + +### SymmetricDifference + +返回一个切片,其中的元素存在于参数切片中,但不同时存储在于参数切片中(交集取反)
+ +函数签名: + +```go +func SymmetricDifference[T comparable](slices ...[]T) []T +``` + +示例:[运行](https://go.dev/play/p/1CbOmtgILUU) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums1 := []int{1, 2, 3} + nums2 := []int{1, 2, 4} + + result := slice.SymmetricDifference(nums1, nums2) + + fmt.Println(result) + + // Output: + // [3 4] +} +``` + +### ToSlice + +将可变参数转为切片
+ +函数签名: + +```go +func ToSlice[T any](items ...T) []T +``` + +示例:[运行](https://go.dev/play/p/YzbzVq5kscN) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.ToSlice("a", "b", "c") + + fmt.Println(result) + + // Output: + // [a b c] +} +``` + +### ToSlicePointer + +将可变参数转为指针切片
+ +函数签名: + +```go +func ToSlicePointer[T any](items ...T) []*T +``` + +示例:[运行](https://go.dev/play/p/gx4tr6_VXSF) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + str1 := "a" + str2 := "b" + + result := slice.ToSlicePointer(str1, str2) + + expect := []*string{&str1, &str2} + + isEqual := reflect.DeepEqual(result, expect) + + fmt.Println(isEqual) + + // Output: + // true +} +``` + +### Unique + +删除切片中的重复元素
+ +函数签名: + +```go +func Unique[T comparable](slice []T) []T +``` + +示例:[运行](https://go.dev/play/p/AXw0R3ZTE6a) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.Unique([]string{"a", "a", "b"}) + fmt.Println(result) + + // Output: + // [a b] +} +``` + +### UniqueBy + +根据迭代函数返回的值,从输入切片中移除重复元素。此函数保持元素的顺序。
+ +函数签名: + +```go +func UniqueBy[T any, U comparable](slice []T, iteratee func(item T) U) []T +``` + +示例:[运行](https://go.dev/play/p/GY7JE4yikrl) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5, 6} + result := slice.UniqueBy(nums, func(val int) int { + return val % 3 + }) + + fmt.Println(result) + + // Output: + // [1 2 3] +} +``` + +### UniqueByComparator + +使用提供的比较器函数从输入切片中移除重复元素。此函数保持元素的顺序。
+ +函数签名: + +```go +func UniqueByComparator[T comparable](slice []T, comparator func(item T, other T) bool) []T +``` + +示例:[运行](https://go.dev/play/p/rwSacr-ZHsR) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/slice" +) + +func main() { + uniqueNums := slice.UniqueByComparator([]int{1, 2, 3, 1, 2, 4, 5, 6, 4}, func(item int, other int) bool { + return item == other + }) + + caseInsensitiveStrings := slice.UniqueByComparator([]string{"apple", "banana", "Apple", "cherry", "Banana", "date"}, func(item string, other string) bool { + return strings.ToLower(item) == strings.ToLower(other) + }) + + fmt.Println(uniqueNums) + fmt.Println(caseInsensitiveStrings) + + // Output: + // [1 2 3 4 5 6] + // [apple banana cherry date] +} +``` + +### UniqueByConcurrent + +并发的从输入切片中移除重复元素,结果保持元素的顺序。
+ +函数签名: + +```go +func UniqueByConcurrent[T comparable](slice []T, comparator func(item T, other T) bool, numThreads int) []T +``` + +示例:[运行](https://go.dev/play/p/wXZ7LcYRMGL) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/slice" +) + +func main() { + nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7} + comparator := func(item int, other int) bool { return item == other } + + result := slice.UniqueByConcurrent(nums, comparator, 4) + + fmt.Println(result) + // Output: + // [1 2 3 4 5 6 7] +} +``` + +### UniqueByField + +根据struct字段对struct切片去重复。
+ +函数签名: + +```go +func UniqueByField[T any](slice []T, field string) ([]T, error) +``` + +示例:[运行](https://go.dev/play/p/6cifcZSPIGu) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/slice" +) + +func main() { + type User struct { + ID int `json:"id"` + Name string `json:"name"` + } + + users := []User{ + {ID: 1, Name: "a"}, + {ID: 2, Name: "b"}, + {ID: 1, Name: "c"}, + } + + result, err := slice.UniqueByField(users, "ID") + if err != nil { + } + + fmt.Println(result) + + // Output: + // [{1 a} {2 b}] +} +``` + +### Union + +合并多个切片
+ +函数签名: + +```go +func Union[T comparable](slices ...[]T) []T +``` + +示例:[运行](https://go.dev/play/p/hfXV1iRIZOf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums1 := []int{1, 3, 4, 6} + nums2 := []int{1, 2, 5, 6} + + result := slice.Union(nums1, nums2) + + fmt.Println(result) + + // Output: + // [1 3 4 6 2 5] +} +``` + +### UnionBy + +对切片的每个元素调用函数后,合并多个切片
+ +函数签名: + +```go +func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T +``` + +示例:[运行](https://go.dev/play/p/HGKHfxKQsFi) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4} + + divideTwo := func(n int) int { + return n / 2 + } + result := slice.UnionBy(divideTwo, nums) + + fmt.Println(result) + + // Output: + // [1 2 4] +} +``` + +### UpdateAt + +更新索引处的切片元素。 如果index < 0或 index <= len(slice),将返回错误
+ +函数签名: + +```go +func UpdateAt[T any](slice []T, index int, value T) []T +``` + +示例:[运行](https://go.dev/play/p/f3mh2KloWVm) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.UpdateAt([]string{"a", "b", "c"}, -1, "1") + result2 := slice.UpdateAt([]string{"a", "b", "c"}, 0, "1") + result3 := slice.UpdateAt([]string{"a", "b", "c"}, 1, "1") + result4 := slice.UpdateAt([]string{"a", "b", "c"}, 2, "1") + result5 := slice.UpdateAt([]string{"a", "b", "c"}, 3, "1") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // [a b c] + // [1 b c] + // [a 1 c] + // [a b 1] + // [a b c] +} +``` + +### Without + +创建一个不包括所有给定值的切片
+ +函数签名: + +```go +func Without[T comparable](slice []T, items ...T) []T +``` + +示例:[运行](https://go.dev/play/p/bwhEXEypThg) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.Without([]int{1, 2, 3, 4}, 1, 2) + + fmt.Println(result) + + // Output: + // [3 4] +} +``` + +### KeyBy + +将切片每个元素调用函数后转为map。
+ +函数签名: + +```go +func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T +``` + +示例:[运行](https://go.dev/play/p/uXod2LWD1Kg) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.KeyBy([]string{"a", "ab", "abc"}, func(str string) int { + return len(str) + }) + + fmt.Println(result) + + // Output: + // map[1:a 2:ab 3:abc] +} +``` + +### Join + +用指定的分隔符链接切片元素。
+ +函数签名: + +```go +func Join[T any](s []T, separator string) string +``` + +示例:[运行](https://go.dev/play/p/huKzqwNDD7V) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + result1 := slice.Join(nums, ",") + result2 := slice.Join(nums, "-") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1,2,3,4,5 + // 1-2-3-4-5 +} +``` + +### Partition + +根据给定的predicate判断函数分组切片元素。
+ +函数签名: + +```go +func Partition[T any](slice []T, predicates ...func(item T) bool) [][]T +``` + +示例:[运行](https://go.dev/play/p/lkQ3Ri2NQhV) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + result1 := slice.Partition(nums) + result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 }) + result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // [[1 2 3 4 5]] + // [[2 4] [1 3 5]] + // [[1 2] [3 4] [5]] +} +``` + + +### Random + +随机返回切片中元素以及下标, 当切片长度为0时返回下标-1
+ +函数签名: + +```go +func Random[T any](slice []T) (val T, idx int) +``` + +示例:[运行](https://go.dev/play/p/UzpGQptWppw) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + val, idx := slice.Random(nums) + if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) { + fmt.Println("okk") + } + // Output: + // okk +} +``` + +### SetToDefaultIf + +根据给定给定的predicate判定函数来修改切片中的元素。对于满足的元素,将其替换为指定的默认值,同时保持元素在切片中的位置不变。函数返回修改后的切片以及被修改的元素个数。
+ +函数签名: + +```go +func SetToDefaultIf[T any](slice []T, predicate func(T) bool) ([]T, int) +``` + +示例:[运行](https://go.dev/play/p/9AXGlPRC0-A) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "b", "a", "c", "d", "a"} + modifiedStrs, count := slice.SetToDefaultIf(strs, func(s string) bool { return "a" == s }) + + fmt.Println(modifiedStrs) + fmt.Println(count) + + // Output: + // [ b c d ] + // 3 +} +``` + +### Break + +根据判断函数将切片分成两部分。它开始附加到与函数匹配的第一个元素之后的第二个切片。第一个匹配之后的所有元素都包含在第二个切片中,无论它们是否与函数匹配。
+ +函数签名: + +```go +func Break[T any](values []T, predicate func(T) bool) ([]T, []T) +``` + +示例:[运行](https://go.dev/play/p/yLYcBTyeQIz) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + even := func(n int) bool { return n%2 == 0 } + + resultEven, resultAfterFirstEven := slice.Break(nums, even) + + fmt.Println(resultEven) + fmt.Println(resultAfterFirstEven) + + // Output: + // [1] + // [2 3 4 5] +} +``` + +### RightPadding + +在切片的右部添加元素。
+ +函数签名: + +```go +func RightPadding[T any](slice []T, paddingValue T, paddingLength int) []T +``` + +示例:[运行](https://go.dev/play/p/0_2rlLEMBXL) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + padded := slice.RightPadding(nums, 0, 3) + fmt.Println(padded) + // Output: + // [1 2 3 4 5 0 0 0] +} +``` + +### LeftPadding + +在切片的左部添加元素。
+ +函数签名: + +```go +func LeftPadding[T any](slice []T, paddingValue T, paddingLength int) []T +``` + +示例:[运行](https://go.dev/play/p/jlQVoelLl2k) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + padded := slice.LeftPadding(nums, 0, 3) + fmt.Println(padded) + // Output: + // [0 0 0 1 2 3 4 5] +} +``` + +### Frequency + +计算切片中每个元素出现的频率。
+ +函数签名: + +```go +func Frequency[T comparable](slice []T) map[T]int +``` + +示例:[运行](https://go.dev/play/p/CW3UVNdUZOq) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "b", "b", "c", "c", "c"} + result := slice.Frequency(strs) + + fmt.Println(result) + + // Output: + // map[a:1 b:2 c:3] +} +``` + +### JoinFunc + +将切片元素用给定的分隔符连接成一个单一的字符串。
+ +函数签名: + +```go +func JoinFunc[T any](slice []T, sep string, transform func(T) T) string +``` + +示例:[运行](https://go.dev/play/p/55ib3SB5fM2) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.JoinFunc([]string{"a", "b", "c"}, ", ", func(s string) string { + return strings.ToUpper(s) + }) + + fmt.Println(result) + + // Output: + // A, B, C +} +``` + +### ConcatBy + +将切片中的元素连接成一个值,使用指定的分隔符和连接器函数。
+ +函数签名: + +```go +func ConcatBy[T any](slice []T, sep T, connector func(T, T) T) T +``` + +示例:[运行](https://go.dev/play/p/6QcUpcY4UMW) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + type Person struct { + Name string + Age int + } + + people := []Person{ + {Name: "Alice", Age: 30}, + {Name: "Bob", Age: 25}, + {Name: "Charlie", Age: 35}, + } + + sep := Person{Name: " | ", Age: 0} + + personConnector := func(a, b Person) Person { + return Person{Name: a.Name + b.Name, Age: a.Age + b.Age} + } + + result := slice.ConcatBy(people, sep, personConnector) + + fmt.Println(result.Name) + fmt.Println(result.Age) + + // Output: + // Alice | Bob | Charlie + // 90 +} +``` \ No newline at end of file diff --git a/docs/api/packages/stream.md b/docs/api/packages/stream.md new file mode 100644 index 00000000..ea4a4097 --- /dev/null +++ b/docs/api/packages/stream.md @@ -0,0 +1,1008 @@ +# Stream + +Stream流,该包仅验证简单stream实现,功能有限。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/stream/stream.go](https://github.com/duke-git/lancet/blob/main/stream/stream.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/stream" +) +``` + + + +## 目录 + +- [Of](#Of) +- [FromSlice](#FromSlice) +- [FromChannel](#FromChannel) +- [FromRange](#FromRange) +- [Generate](#Generate) +- [Concat](#Concat) +- [Distinct](#Distinct) +- [Filter](#Filter) +- [Map](#Map) +- [Peek](#Peek) +- [Skip](#Skip) +- [Limit](#Limit) +- [Reverse](#Reverse) +- [Range](#Range) +- [Sorted](#Sorted) +- [ForEach](#ForEach) +- [Reduce](#Reduce) +- [FindFirst](#FindFirst) +- [FindLast](#FindLast) +- [Max](#Max) +- [Min](#Min) +- [AllMatch](#AllMatch) +- [AnyMatch](#AnyMatch) +- [NoneMatch](#NoneMatch) +- [Count](#Count) +- [ToSlice](#ToSlice) +- [IndexOf](#IndexOf) +- [LastIndexOf](#LastIndexOf) + + + +## 文档 + +### Of + +创建元素为指定值的stream。
+ +函数签名: + +```go +func Of[T any](elems ...T) stream[T] +``` + +示例:[运行](https://go.dev/play/p/jI6_iZZuVFE) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s := stream.Of(1, 2, 3) + + data := s.ToSlice() + + fmt.Println(data) + + // Output: + // [1 2 3] +} +``` + +### FromSlice + +从切片创建stream。
+ +函数签名: + +```go +func FromSlice[T any](source []T) stream[T] +``` + +示例:[运行](https://go.dev/play/p/wywTO0XZtI4) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s := stream.FromSlice([]int{1, 2, 3}) + + data := s.ToSlice() + + fmt.Println(data) + + // Output: + // [1 2 3] +} +``` + +### FromChannel + +从通道创建stream。
+ +函数签名: + +```go +func FromChannel[T any](source <-chan T) stream[T] +``` + +示例:[运行](https://go.dev/play/p/9TZYugGMhXZ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + ch := make(chan int) + go func() { + for i := 1; i < 4; i++ { + ch <- i + } + close(ch) + }() + + s := stream.FromChannel(ch) + + data := s.ToSlice() + + fmt.Println(data) + + // Output: + // [1 2 3] +} +``` + +### FromRange + +指定一个范围创建stream, 范围两端点值都包括在内。
+ +函数签名: + +```go +func FromRange[T constraints.Integer | constraints.Float](start, end, step T) stream[T] +``` + +示例:[运行](https://go.dev/play/p/9Ex1-zcg-B-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s := stream.FromRange(1, 5, 1) + + data := s.ToSlice() + fmt.Println(data) + + // Output: + // [1 2 3 4 5] +} +``` + +### Generate + +创建一个stream,其中每个元素都由提供的生成器函数生成
+ +函数签名: + +```go +func Generate[T any](generator func() func() (item T, ok bool)) stream[T] +``` + +示例:[运行](https://go.dev/play/p/rkOWL1yA3j9) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + n := 0 + max := 4 + + generator := func() func() (int, bool) { + return func() (int, bool) { + n++ + return n, n < max + } + } + + s := stream.Generate(generator) + + data := s.ToSlice() + + fmt.Println(data) + + // Output: + // [1 2 3] +} +``` + +### Concat + +创建一个延迟连接stream,其元素是第一个stream的所有元素,后跟第二个stream的全部元素。
+ +函数签名: + +```go +func Concat[T any](a, b stream[T]) stream[T] +``` + +示例:[运行](https://go.dev/play/p/HM4OlYk_OUC) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s1 := stream.FromSlice([]int{1, 2, 3}) + s2 := stream.FromSlice([]int{4, 5, 6}) + + s := Concat(s1, s2) + + data := s.ToSlice() + + fmt.Println(data) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### Distinct + +创建并返回一个stream,用于删除重复的项。 支持链式操作
+ +函数签名: + +```go +func (s stream[T]) Distinct() stream[T] +``` + +示例:[运行](https://go.dev/play/p/eGkOSrm64cB) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 2, 3, 3, 3}) + distinct := original.Distinct() + + data1 := original.ToSlice() + data2 := distinct.ToSlice() + + fmt.Println(data1) + fmt.Println(data2) + + // Output: + // [1 2 2 3 3 3] + // [1 2 3] +} +``` + +### Filter + +返回一个通过判定函数的stream 支持链式操作
+ +函数签名: + +```go +func (s stream[T]) Filter(predicate func(item T) bool) stream[T] +``` + +示例:[运行](https://go.dev/play/p/MFlSANo-buc) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3, 4, 5}) + + isEven := func(n int) bool { + return n%2 == 0 + } + + even := original.Filter(isEven) + + fmt.Println(even.ToSlice()) + + // Output: + // [2 4] +} +``` + +### Map + +返回一个stream,该stream由将给定函数应用于源stream元素的元素组成。支持链式操作
+ +函数签名: + +```go +func (s stream[T]) Map(mapper func(item T) T) stream[T] +``` + +示例:[运行](https://go.dev/play/p/OtNQUImdYko) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + addOne := func(n int) int { + return n + 1 + } + + increament := original.Map(addOne) + + fmt.Println(increament.ToSlice()) + + // Output: + // [2 3 4] +} +``` + +### Peek + +返回一个由源stream的元素组成的stream,并在从生成的stream中消耗元素时对每个元素执行所提供的操作。 支持链式操作
+ +函数签名: + +```go +func (s stream[T]) Peek(consumer func(item T)) stream[T] +``` + +示例:[运行](https://go.dev/play/p/u1VNzHs6cb2) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + data := []string{} + peekStream := original.Peek(func(n int) { + data = append(data, fmt.Sprint("value", n)) + }) + + fmt.Println(original.ToSlice()) + fmt.Println(peekStream.ToSlice()) + fmt.Println(data) + + // Output: + // [1 2 3] + // [1 2 3] + // [value1 value2 value3] +} +``` + +### Skip + +在丢弃stream的前n个元素后,返回由源stream的其余元素组成的stream。如果此stream包含的元素少于n个,则将返回一个空stream。支持链式操作
+ +函数签名: + +```go +func (s stream[T]) Skip(n int) stream[T] +``` + +示例:[运行](https://go.dev/play/p/fNdHbqjahum) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3, 4}) + + s1 := original.Skip(-1) + s2 := original.Skip(0) + s3 := original.Skip(1) + s4 := original.Skip(5) + + fmt.Println(s1.ToSlice()) + fmt.Println(s2.ToSlice()) + fmt.Println(s3.ToSlice()) + fmt.Println(s4.ToSlice()) + + // Output: + // [1 2 3 4] + // [1 2 3 4] + // [2 3 4] + // [] +} +``` + +### Limit + +返回由源stream的元素组成的stream,该stream被截断为长度不超过maxSize。支持链式操作
+ +函数签名: + +```go +func (s stream[T]) Limit(maxSize int) stream[T] +``` + +示例:[运行](https://go.dev/play/p/qsO4aniDcGf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3, 4}) + + s1 := original.Limit(-1) + s2 := original.Limit(0) + s3 := original.Limit(1) + s4 := original.Limit(5) + + fmt.Println(s1.ToSlice()) + fmt.Println(s2.ToSlice()) + fmt.Println(s3.ToSlice()) + fmt.Println(s4.ToSlice()) + + // Output: + // [] + // [] + // [1] + // [1 2 3 4] +} +``` + +### Reverse + +返回元素与源stream的顺序相反的stream。支持链式操作
+ +函数签名: + +```go +func (s stream[T]) Reverse() stream[T] +``` + +示例:[运行](https://go.dev/play/p/A8_zkJnLHm4) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + reverse := original.Reverse() + + fmt.Println(reverse.ToSlice()) + + // Output: + // [3 2 1] +} +``` + +### Range + +返回一个stream,该stream的元素在从源stream的开始(包含)到结束(排除)的范围内。支持链式操作
+ +函数签名: + +```go +func (s stream[T]) Range(start, end int) stream[T] +``` + +示例:[运行](https://go.dev/play/p/indZY5V2f4j) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + s1 := original.Range(0, 0) + s2 := original.Range(0, 1) + s3 := original.Range(0, 3) + s4 := original.Range(1, 2) + + fmt.Println(s1.ToSlice()) + fmt.Println(s2.ToSlice()) + fmt.Println(s3.ToSlice()) + fmt.Println(s4.ToSlice()) + + // Output: + // [] + // [1] + // [1 2 3] + // [2] +} +``` + +### Sorted + +返回一个stream,该stream由源stream的元素组成,并根据提供的less函数进行排序。支持链式操作
+ +函数签名: + +```go +func (s stream[T]) Sorted(less func(a, b T) bool) stream[T] +``` + +示例:[运行](https://go.dev/play/p/XXtng5uonFj) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{4, 2, 1, 3}) + + sorted := original.Sorted(func(a, b int) bool { return a < b }) + + fmt.Println(original.ToSlice()) + fmt.Println(sorted.ToSlice()) + + // Output: + // [4 2 1 3] + // [1 2 3 4] +} +``` + +### ForEach + +对stream的每个元素执行一个操作。
+ +函数签名: + +```go +func (s stream[T]) ForEach(action func(item T)) +``` + +示例:[运行](https://go.dev/play/p/Dsm0fPqcidk) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + result := 0 + original.ForEach(func(item int) { + result += item + }) + + fmt.Println(result) + + // Output: + // 6 +} +``` + +### Reduce + +使用关联累加函数对stream的元素执行reduce操作,并reduce操作结果(如果有)。
+ +函数签名: + +```go +func (s stream[T]) Reduce(initial T, accumulator func(a, b T) T) T +``` + +示例:[运行](https://go.dev/play/p/6uzZjq_DJLU) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + result := original.Reduce(0, func(a, b int) int { + return a + b + }) + + fmt.Println(result) + + // Output: + // 6 +} +``` + +### FindFirst + +返回此stream的第一个元素和true,如果stream为空,则返回零值和false。
+ +函数签名: + +```go +func (s stream[T]) FindFirst() (T, bool) +``` + +示例:[运行](https://go.dev/play/p/9xEf0-6C1e3) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + result, ok := original.FindFirst() + + fmt.Println(result) + fmt.Println(ok) + + // Output: + // 1 + // true +} +``` + +### FindLast + +返回此stream最后一个元素和true,如果stream为空,则返回零值和false。
+ +函数签名: + +```go +func (s stream[T]) FindLast() (T, bool) +``` + +示例:[运行](https://go.dev/play/p/WZD2rDAW-2h) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{3, 2, 1}) + + result, ok := original.FindLast() + + fmt.Println(result) + fmt.Println(ok) + + // Output: + // 1 + // true +} +``` + +### Max + +根据提供的less函数返回stream的最大元素。less 函数: a > b
+ +函数签名: + +```go +func (s stream[T]) Max(less func(a, b T) bool) (T, bool) +``` + +示例:[运行](https://go.dev/play/p/fm-1KOPtGzn) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{4, 2, 1, 3}) + + max, ok := original.Max(func(a, b int) bool { return a > b }) + + fmt.Println(max) + fmt.Println(ok) + + // Output: + // 4 + // true +} +``` + +### Min + +根据提供的less函数返回stream的最小元素。less函数: a < b
+ +函数签名: + +```go +func (s stream[T]) Min(less func(a, b T) bool) (T, bool) +``` + +示例:[运行](https://go.dev/play/p/vZfIDgGNRe_0) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{4, 2, 1, 3}) + + min, ok := original.Min(func(a, b int) bool { return a < b }) + + fmt.Println(min) + fmt.Println(ok) + + // Output: + // 1 + // true +} +``` + +### AllMatch + +判断stream的所有元素是否全部匹配指定判定函数。
+ +函数签名: + +```go +func (s stream[T]) AllMatch(predicate func(item T) bool) bool +``` + +示例:[运行](https://go.dev/play/p/V5TBpVRs-Cx) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + result1 := original.AllMatch(func(item int) bool { + return item > 0 + }) + + result2 := original.AllMatch(func(item int) bool { + return item > 1 + }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### AnyMatch + +判断stream是否包含匹配指定判定函数的元素。
+ +函数签名: + +```go +func (s stream[T]) AnyMatch(predicate func(item T) bool) bool +``` + +示例:[运行](https://go.dev/play/p/PTCnWn4OxSn) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + result1 := original.AnyMatch(func(item int) bool { + return item > 1 + }) + + result2 := original.AnyMatch(func(item int) bool { + return item > 3 + }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### NoneMatch + +判断stream的元素是否全部不匹配指定的判定函数。
+ +函数签名: + +```go +func (s stream[T]) NoneMatch(predicate func(item T) bool) bool +``` + +示例:[运行](https://go.dev/play/p/iWS64pL1oo3) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + result1 := original.NoneMatch(func(item int) bool { + return item > 3 + }) + + result2 := original.NoneMatch(func(item int) bool { + return item > 1 + }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### Count + +返回stream中元素的数量。
+ +函数签名: + +```go +func (s stream[T]) Count() int +``` + +示例:[运行](https://go.dev/play/p/r3koY6y_Xo-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s1 := stream.FromSlice([]int{1, 2, 3}) + s2 := stream.FromSlice([]int{}) + + fmt.Println(s1.Count()) + fmt.Println(s2.Count()) + + // Output: + // 3 + // 0 +} +``` + +### ToSlice + +返回stream中的元素切片。
+ +函数签名: + +```go +func (s stream[T]) ToSlice() []T +``` + +示例:[运行](https://go.dev/play/p/jI6_iZZuVFE) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s := stream.Of(1, 2, 3) + + data := s.ToSlice() + + fmt.Println(data) + + // Output: + // [1 2 3] +} +``` + +### IndexOf + +返回在stream中找到值的第一个匹配项的索引,如果找不到值,则返回-1。
+ +函数签名: + +```go +func (s Stream[T]) IndexOf(target T, equal func(a, b T) bool) int +``` + +示例:[运行](https://go.dev/play/p/tBV5Nc-XDX2) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s := stream.FromSlice([]int{1, 2, 3, 2}) + + result1 := s.IndexOf(0, func(a, b int) bool { return a == b }) + result2 := s.IndexOf(2, func(a, b int) bool { return a == b }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // -1 + // 1 +} +``` + +### LastIndexOf + +返回在stream中找到值的最后一个匹配项的索引,如果找不到值,则返回-1。
+ +函数签名: + +```go +func (s Stream[T]) LastIndexOf(target T, equal func(a, b T) bool) int +``` + +示例:[运行](https://go.dev/play/p/CjeoNw2eac_G) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s := stream.FromSlice([]int{1, 2, 3, 2}) + + result1 := s.LastIndexOf(0, func(a, b int) bool { return a == b }) + result2 := s.LastIndexOf(2, func(a, b int) bool { return a == b }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // -1 + // 3 +} +``` \ No newline at end of file diff --git a/docs/api/packages/struct.md b/docs/api/packages/struct.md new file mode 100644 index 00000000..8555796c --- /dev/null +++ b/docs/api/packages/struct.md @@ -0,0 +1,576 @@ +# Structs + +structs 包封装了一个抽象的`Struct`结构体,提供了操作`struct`的相关函数 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/structs/struct.go](https://github.com/duke-git/lancet/blob/main/structs/struct.go) + +- [https://github.com/duke-git/lancet/blob/main/structs/field.go](https://github.com/duke-git/lancet/blob/main/structs/field.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/structs" +) +``` + + + +## 目录: + +- [New](#New) +- [ToMap](#ToMap) +- [Fields](#Fields) +- [Field](#Field) +- [IsStruct](#IsStruct) +- [Tag](#Tag) +- [Name](#Name) +- [Value](#Value) +- [Kind](#Kind) +- [IsEmbedded](#IsEmbedded) +- [IsExported](#IsExported) +- [IsZero](#IsZero) +- [IsSlice](#IsSlice) +- [IsTargetType](#IsTargetType) + + + +## API 文档: + +### New + +`Struct`结构体的构造函数
+ +函数签名: + +```go +func New(value any, tagName ...string) *Struct +``` + +示例: + +```go +package main + +import ( + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type People struct { + Name string `json:"name"` + } + p1 := &People{Name: "11"} + s := structs.New(p1) + // to do something +} +``` + +### ToMap + +将一个合法的struct对象转换为map[string]any
+ +函数签名: + +```go +func (s *Struct) ToMap() (map[string]any, error) +``` + +除此之外,提供一个便捷的静态方法 ToMap + +```go +func ToMap(v any) (map[string]any, error) +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type People struct { + Name string `json:"name"` + } + p1 := &People{Name: "11"} + s1 := structs.New(p1) + m1, _ := s1.ToMap() + + fmt.Println(m1) + + // 如果不需要Struct更多的方法,可以直接使用ToMap + m2, _ := structs.ToMap(p1) + + fmt.Println(m2) + + // Output: + // map[name:11] + // map[name:11] +} +``` + +### Fields + +获取一个struct对象的属性列表
+ +函数签名: + +```go +func (s *Struct) Fields() []*Field +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type People struct { + Name string `json:"name"` + } + p1 := &People{Name: "11"} + s := structs.New(p1) + fields := s.Fields() + + fmt.Println(len(fields)) + + // Output: + // 1 +} +``` + +### Field + +根据属性名获取一个struct对象的属性
+ +函数签名: + +```go +func (s *Struct) Field(name string) *Field +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type People struct { + Name string `json:"name"` + } + p1 := &People{Name: "11"} + s := structs.New(p1) + f := s.Field("Name") + + fmt.Println(f.Value()) + + // Output: + // 11 +} +``` + +### IsStruct + +判断是否为一个合法的struct对象
+ +函数签名: + +```go +func (s *Struct) IsStruct() bool +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type People struct { + Name string `json:"name"` + } + p1 := &People{Name: "11"} + s := structs.New(p1) + + fmt.Println(s.IsStruct()) + + // Output: + // true +} +``` + +### Tag + +获取`Field`的`Tag`,默认的tag key是json
+ +函数签名: + +```go +func (f *Field) Tag() *Tag +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string `json:"name,omitempty"` + } + p1 := &Parent{"111"} + + s := structs.New(p1) + n, _ := s.Field("Name") + tag := n.Tag() + + fmt.Println(tag.Name) + + // Output: + // name +} +``` + +### Value + +获取`Field`属性的值
+ +函数签名: + +```go +func (f *Field) Value() any +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string `json:"name,omitempty"` + } + p1 := &Parent{"111"} + + s := structs.New(p1) + n, _ := s.Field("Name") + + fmt.Println(n.Value()) + + // Output: + // 111 +} +``` + +### IsEmbedded + +判断属性是否为嵌入
+ +函数签名: + +```go +func (f *Field) IsEmbedded() bool +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + } + type Child struct { + Parent + Age int + } + c1 := &Child{} + c1.Name = "111" + c1.Age = 11 + + s := structs.New(c1) + n, _ := s.Field("Name") + a, _ := s.Field("Age") + + fmt.Println(n.IsEmbedded()) + fmt.Println(a.IsEmbedded()) + + // Output: + // true + // false +} +``` + +### IsExported + +判断属性是否导出
+ +函数签名: + +```go +func (f *Field) IsExported() bool +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + age int + } + p1 := &Parent{Name: "11", age: 11} + s := structs.New(p1) + n, _ := s.Field("Name") + a, _ := s.Field("age") + + fmt.Println(n.IsExported()) + fmt.Println(a.IsExported()) + + // Output: + // true + // false +} +``` + +### IsZero + +判断属性是否为零值
+ +函数签名: + +```go +func (f *Field) IsZero() bool +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + Age int + } + p1 := &Parent{Age: 11} + s := structs.New(p1) + n, _ := s.Field("Name") + a, _ := s.Field("Age") + + fmt.Println(n.IsZero()) + fmt.Println(a.IsZero()) + + // Output: + // true + // false +} +``` + +### Name + +获取属性名
+ +函数签名: + +```go +func (f *Field) Name() string +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + Age int + } + p1 := &Parent{Age: 11} + s := structs.New(p1) + n, _ := s.Field("Name") + a, _ := s.Field("Age") + + fmt.Println(n.Name()) + fmt.Println(a.Name()) + + // Output: + // Name + // Age +} +``` + +### Kind + +获取属性Kind
+ +函数签名: + +```go +func (f *Field) Kind() reflect.Kind +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + Age int + } + p1 := &Parent{Age: 11} + s := structs.New(p1) + n, _ := s.Field("Name") + a, _ := s.Field("Age") + + fmt.Println(n.Kind()) + fmt.Println(a.Kind()) + + // Output: + // string + // int +} +``` + +### IsSlice + +判断属性是否是切片
+ +函数签名: + +```go +func (f *Field) IsSlice() bool +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + arr []int + } + + p1 := &Parent{arr: []int{1, 2, 3}} + s := structs.New(p1) + a, _ := s.Field("arr") + + fmt.Println(a.IsSlice()) + + // Output: + // true +} +``` + +### IsTargetType + +判断属性是否是目标类型
+ +函数签名: + +```go +func (f *Field) IsTargetType(targetType reflect.Kind) bool +``` + +示例: + +```go +package main + +import ( + "fmt" + "reflect" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + arr []int + } + + p1 := &Parent{arr: []int{1, 2, 3}} + s := structs.New(p1) + n, _ := s.Field("Name") + a, _ := s.Field("arr") + + fmt.Println(n.IsTargetType(reflect.String)) + fmt.Println(a.IsTargetType(reflect.Slice)) + + // Output: + // true + // true +} +``` \ No newline at end of file diff --git a/docs/api/packages/strutil.md b/docs/api/packages/strutil.md new file mode 100644 index 00000000..b5d370be --- /dev/null +++ b/docs/api/packages/strutil.md @@ -0,0 +1,1791 @@ +# Strutil + +strutil 包含处理字符串的相关函数。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/strutil/string.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/strutil" +) +``` + + + +## 目录 + +- [After](#After) +- [AfterLast](#AfterLast) +- [Before](#Before) +- [BeforeLast](#BeforeLast) +- [CamelCase](#CamelCase) +- [Capitalize](#Capitalize) +- [IsString](#IsString) +- [KebabCase](#KebabCase) +- [UpperKebabCase](#UpperKebabCase) +- [LowerFirst](#LowerFirst) +- [UpperFirst](#UpperFirst) +- [Pad](#Pad) +- [PadEnd](#PadEnd) +- [PadStart](#PadStart) +- [Reverse](#Reverse) +- [SnakeCase](#SnakeCase) +- [UpperSnakeCase](#UpperSnakeCase) +- [SplitEx](#SplitEx) +- [Substring](#Substring) +- [Wrap](#Wrap) +- [Unwrap](#Unwrap) +- [SplitWords](#SplitWords) +- [WordCount](#WordCount) +- [RemoveNonPrintable](#RemoveNonPrintable) +- [StringToBytes](#StringToBytes) +- [BytesToString](#BytesToString) +- [IsBlank](#IsBlank) +- [IsNotBlank](#IsNotBlank) +- [HasPrefixAny](#HasPrefixAny) +- [HasSuffixAny](#HasSuffixAny) +- [IndexOffset](#IndexOffset) +- [ReplaceWithMap](#ReplaceWithMap) +- [Trim](#Trim) +- [SplitAndTrim](#SplitAndTrim) +- [HideString](#HideString) +- [ContainsAll](#ContainsAll) +- [ContainsAny](#ContainsAny) +- [RemoveWhiteSpace](#RemoveWhiteSpace) +- [SubInBetween](#SubInBetween) +- [HammingDistance](#HammingDistance) +- [Concat](#Concat) +- [Ellipsis](#Ellipsis) +- [Shuffle](#Shuffle) +- [Rotate](#Rotate) +- [TemplateReplace](#TemplateReplace) +- [RegexMatchAllGroups](#RegexMatchAllGroups) +- [ExtractContent](#ExtractContent) +- [FindAllOccurrences](#FindAllOccurrences) + + + + +## 文档 + +### After + +返回源字符串中特定字符串首次出现时的位置之后的子字符串。
+ +函数签名: + +```go +func After(s, char string) string +``` + +示例:[运行](https://go.dev/play/p/RbCOQqCDA7m) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.After("foo", "") + result2 := strutil.After("foo", "foo") + result3 := strutil.After("foo/bar", "foo") + result4 := strutil.After("foo/bar", "/") + result5 := strutil.After("foo/bar/baz", "/") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // foo + // + // /bar + // bar + // bar/baz +} +``` + +### AfterLast + +返回源字符串中指定字符串最后一次出现时的位置之后的子字符串。
+ +函数签名: + +```go +func AfterLast(s, char string) string +``` + +示例:[运行](https://go.dev/play/p/1TegARrb8Yn) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.AfterLast("foo", "") + result2 := strutil.AfterLast("foo", "foo") + result3 := strutil.AfterLast("foo/bar", "/") + result4 := strutil.AfterLast("foo/bar/baz", "/") + result5 := strutil.AfterLast("foo/bar/foo/baz", "foo") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // foo + // + // bar + // baz + // /baz +} +``` + +### Before + +返回源字符串中指定字符串第一次出现时的位置之前的子字符串。
+ +函数签名: + +```go +func Before(s, char string) string +``` + +示例:[运行](https://go.dev/play/p/JAWTZDS4F5w) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Before("foo", "") + result2 := strutil.Before("foo", "foo") + result3 := strutil.Before("foo/bar", "/") + result4 := strutil.Before("foo/bar/baz", "/") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // foo + // + // foo + // foo +} +``` + +### BeforeLast + +返回源字符串中指定字符串最后一次出现时的位置之前的子字符串。
+ +函数签名: + +```go +func BeforeLast(s, char string) string +``` + +示例:[运行](https://go.dev/play/p/pJfXXAoG_Te) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.BeforeLast("foo", "") + result2 := strutil.BeforeLast("foo", "foo") + result3 := strutil.BeforeLast("foo/bar", "/") + result4 := strutil.BeforeLast("foo/bar/baz", "/") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // foo + // + // foo + // foo/bar +} +``` + +### CamelCase + +将字符串转换为驼峰式字符串, 非字母和数字会被忽略。
+ +函数签名: + +```go +func CamelCase(s string) string +``` + +示例:[运行](https://go.dev/play/p/9eXP3tn2tUy) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "foobar", "&FOO:BAR$BAZ", "$foo%", "Foo-#1😄$_%^&*(1bar"} + + for _, v := range strings { + s := strutil.CamelCase(v) + fmt.Println(s) + } + + // Output: + // + // foobar + // fooBarBaz + // foo + // foo11Bar +} +``` + +### KebabCase + +将字符串转换为kebab-case, 非字母和数字会被忽略。
+ +函数签名: + +```go +func KebabCase(s string) string +``` + +示例:[运行](https://go.dev/play/p/dcZM9Oahw-Y) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "foo-bar", "Foo Bar-", "FOOBAR", "Foo-#1😄$_%^&*(1bar"} + + for _, v := range strings { + s := strutil.KebabCase(v) + fmt.Println(s) + } + + // Output: + // + // foo-bar + // foo-bar + // foobar + // foo-1-1-bar +} +``` + +### UpperKebabCase + +将字符串转换为大写KEBAB-CASE, 非字母和数字会被忽略。
+ +函数签名: + +```go +func UpperKebabCase(s string) string +``` + +示例:[运行](https://go.dev/play/p/zDyKNneyQXk) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "foo-bar", "Foo Bar-", "FooBAR", "Foo-#1😄$_%^&*(1bar"} + + for _, v := range strings { + s := strutil.UpperKebabCase(v) + fmt.Println(s) + } + + // Output: + // + // FOO-BAR + // FOO-BAR + // FOO-BAR + // FOO-1-1-BAR +} +``` + +### Capitalize + +将字符串的第一个字符转换为大写。
+ +函数签名: + +```go +func Capitalize(s string) string +``` + +示例:[运行](https://go.dev/play/p/2OAjgbmAqHZ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "Foo", "_foo", "fooBar", "foo-bar"} + + for _, v := range strings { + s := strutil.Capitalize(v) + fmt.Println(s) + } + + // Output: + // + // Foo + // _foo + // Foobar + // Foo-bar +} +``` + +### IsString + +判断传入参数的数据类型是否为字符串。
+ +函数签名: + +```go +func IsString(v any) bool +``` + +示例:[运行](https://go.dev/play/p/IOgq7oF9ERm) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.IsString("") + result2 := strutil.IsString("a") + result3 := strutil.IsString(1) + result4 := strutil.IsString(true) + result5 := strutil.IsString([]string{"a"}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // true + // true + // false + // false + // false +} +``` + +### LowerFirst + +将字符串的第一个字符转换为小写。
+ +函数签名: + +```go +func LowerFirst(s string) string +``` + +示例:[运行](https://go.dev/play/p/CbzAyZmtJwL) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "bar", "BAr", "Bar大"} + + for _, v := range strings { + s := strutil.LowerFirst(v) + fmt.Println(s) + } + + // Output: + // + // bar + // bAr + // bar大 +} +``` + +### UpperFirst + +将字符串的第一个字符转换为大写形式。
+ +函数签名: + +```go +func UpperFirst(s string) string +``` + +示例:[运行](https://go.dev/play/p/sBbBxRbs8MM) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "bar", "BAr", "bar大"} + + for _, v := range strings { + s := strutil.UpperFirst(v) + fmt.Println(s) + } + + // Output: + // + // Bar + // BAr + // Bar大 +} +``` + +### Pad + +如果字符串长度短于size,则在左右两侧填充字符串。
+ +函数签名: + +```go +func Pad(source string, size int, padStr string) string +``` + +示例:[运行](https://go.dev/play/p/NzImQq-VF8q) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Pad("foo", 1, "bar") + result2 := strutil.Pad("foo", 2, "bar") + result3 := strutil.Pad("foo", 3, "bar") + result4 := strutil.Pad("foo", 4, "bar") + result5 := strutil.Pad("foo", 5, "bar") + result6 := strutil.Pad("foo", 6, "bar") + result7 := strutil.Pad("foo", 7, "bar") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + // Output: + // foo + // foo + // foo + // foob + // bfoob + // bfooba + // bafooba +} +``` + +### PadEnd + +如果字符串长度短于size,则在右侧填充字符串。
+ +函数签名: + +```go +func PadEnd(source string, size int, padStr string) string +``` + +示例:[运行](https://go.dev/play/p/9xP8rN0vz--) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.PadEnd("foo", 1, "bar") + result2 := strutil.PadEnd("foo", 2, "bar") + result3 := strutil.PadEnd("foo", 3, "bar") + result4 := strutil.PadEnd("foo", 4, "bar") + result5 := strutil.PadEnd("foo", 5, "bar") + result6 := strutil.PadEnd("foo", 6, "bar") + result7 := strutil.PadEnd("foo", 7, "bar") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + + // Output: + // foo + // foo + // foo + // foob + // fooba + // foobar + // foobarb +} +``` + +### PadStart + +如果字符串长度短于size,则在左侧填充字符串。
+ +函数签名: + +```go +func PadStart(source string, size int, padStr string) string +``` + +示例:[运行](https://go.dev/play/p/xpTfzArDfvT) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.PadStart("foo", 1, "bar") + result2 := strutil.PadStart("foo", 2, "bar") + result3 := strutil.PadStart("foo", 3, "bar") + result4 := strutil.PadStart("foo", 4, "bar") + result5 := strutil.PadStart("foo", 5, "bar") + result6 := strutil.PadStart("foo", 6, "bar") + result7 := strutil.PadStart("foo", 7, "bar") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + + // Output: + // foo + // foo + // foo + // bfoo + // bafoo + // barfoo + // barbfoo +} +``` + +### Reverse + +返回字符顺序与给定字符串相反的字符串。
+ +函数签名: + +```go +func Reverse(s string) string +``` + +示例:[运行](https://go.dev/play/p/adfwalJiecD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + s := "foo" + rs := strutil.Reverse(s) + + fmt.Println(s) + fmt.Println(rs) + + // Output: + // foo + // oof +} +``` + +### SnakeCase + +将字符串转换为snake_case形式, 非字母和数字会被忽略。
+ +函数签名: + +```go +func SnakeCase(s string) string +``` + +示例:[运行](https://go.dev/play/p/tgzQG11qBuN) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "foo-bar", "Foo Bar-", "FOOBAR", "Foo-#1😄$_%^&*(1bar"} + + for _, v := range strings { + s := strutil.SnakeCase(v) + fmt.Println(s) + } + + // Output: + // + // foo_bar + // foo_bar + // foobar + // foo_1_1_bar +} +``` + +### UpperSnakeCase + +将字符串转换为大写SNAKE_CASE形式, 非字母和数字会被忽略。
+ +函数签名: + +```go +func UpperSnakeCase(s string) string +``` + +示例:[运行](https://go.dev/play/p/4COPHpnLx38) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "foo-bar", "Foo Bar-", "FooBAR", "Foo-#1😄$_%^&*(1bar"} + + for _, v := range strings { + s := strutil.UpperSnakeCase(v) + fmt.Println(s) + } + + // Output: + // + // FOO_BAR + // FOO_BAR + // FOO_BAR + // FOO_1_1_BAR +} +``` + +### SplitEx + +分割字符串为切片,removeEmptyString参数指定是否去除空字符串。
+ +函数签名: + +```go +func SplitEx(s, sep string, removeEmptyString bool) []string +``` + +示例:[运行](https://go.dev/play/p/Us-ySSbWh-3) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.SplitEx(" a b c ", "", true) + + result2 := strutil.SplitEx(" a b c ", " ", false) + result3 := strutil.SplitEx(" a b c ", " ", true) + + result4 := strutil.SplitEx("a = b = c = ", " = ", false) + result5 := strutil.SplitEx("a = b = c = ", " = ", true) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // [] + // [ a b c ] + // [a b c] + // [a b c ] +} +``` + +### Substring + +根据指定的位置和长度截取字符串。
+ +函数签名: + +```go +func Substring(s string, offset int, length uint) string +``` + +示例:[运行](https://go.dev/play/p/q3sM6ehnPDp) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Substring("abcde", 1, 3) + result2 := strutil.Substring("abcde", 1, 5) + result3 := strutil.Substring("abcde", -1, 3) + result4 := strutil.Substring("abcde", -2, 2) + result5 := strutil.Substring("abcde", -2, 3) + result6 := strutil.Substring("你好,欢迎你", 0, 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // bcd + // bcde + // e + // de + // de + // 你好 +} +``` + +### Wrap + +用另一个字符串包裹一个字符串。
+ +函数签名: + +```go +func Wrap(str string, wrapWith string) string +``` + +示例:[运行](https://go.dev/play/p/KoZOlZDDt9y) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Wrap("foo", "") + result2 := strutil.Wrap("foo", "*") + result3 := strutil.Wrap("'foo'", "'") + result4 := strutil.Wrap("", "*") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // foo + // *foo* + // ''foo'' + // +} +``` + +### Unwrap + +用另一个字符串解开包裹一个字符串。
+ +函数签名: + +```go +func Unwrap(str string, wrapToken string) string +``` + +示例:[运行](https://go.dev/play/p/Ec2q4BzCpG-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Unwrap("foo", "") + result2 := strutil.Unwrap("*foo*", "*") + result3 := strutil.Unwrap("*foo", "*") + result4 := strutil.Unwrap("foo*", "*") + result5 := strutil.Unwrap("**foo**", "*") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // foo + // foo + // *foo + // foo* + // *foo* +} +``` + +### SplitWords + +将字符串拆分为单词,只支持字母字符单词。
+ +函数签名: + +```go +func SplitWords(s string) []string +``` + +示例:[运行](https://go.dev/play/p/KLiX4WiysMM) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.SplitWords("a word") + result2 := strutil.SplitWords("I'am a programmer") + result3 := strutil.SplitWords("Bonjour, je suis programmeur") + result4 := strutil.SplitWords("a -b-c' 'd'e") + result5 := strutil.SplitWords("你好,我是一名码农") + result6 := strutil.SplitWords("こんにちは,私はプログラマーです") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // [a word] + // [I'am a programmer] + // [Bonjour je suis programmeur] + // [a b-c' d'e] + // [] + // [] +} +``` + +### WordCount + +返回有意义单词的数量,只支持字母字符单词。
+ +函数签名: + +```go +func WordCount(s string) int +``` + +示例:[运行](https://go.dev/play/p/bj7_odx3vRf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.WordCount("a word") + result2 := strutil.WordCount("I'am a programmer") + result3 := strutil.WordCount("Bonjour, je suis programmeur") + result4 := strutil.WordCount("a -b-c' 'd'e") + result5 := strutil.WordCount("你好,我是一名码农") + result6 := strutil.WordCount("こんにちは,私はプログラマーです") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // 2 + // 3 + // 4 + // 3 + // 0 + // 0 +} +``` + +### RemoveNonPrintable + +删除字符串中不可打印的字符。
+ +函数签名: + +```go +func RemoveNonPrintable(str string) string +``` + +示例:[运行](https://go.dev/play/p/og47F5x_jTZ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.RemoveNonPrintable("hello\u00a0 \u200bworld\n") + result2 := strutil.RemoveNonPrintable("你好😄") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // hello world + // 你好😄 +} +``` + +### StringToBytes + +在不分配内存的情况下将字符串转换为字节片。
+ +函数签名: + +```go +func StringToBytes(str string) (b []byte) +``` + +示例:[运行](https://go.dev/play/p/7OyFBrf9AxA) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.StringToBytes("abc") + result2 := reflect.DeepEqual(result1, []byte{'a', 'b', 'c'}) + + fmt.Println(result1) + fmt.Println(result2) + // Output: + // [97 98 99] + // true +} +``` + +### BytesToString + +在不分配内存的情况下将字节切片转换为字符串。
+ +函数签名: + +```go +func BytesToString(bytes []byte) string +``` + +示例:[运行](https://go.dev/play/p/6c68HRvJecH) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + bytes := []byte{'a', 'b', 'c'} + result := strutil.BytesToString(bytes) + + fmt.Println(result) + + // Output: + // abc +} +``` + +### IsBlank + +检查字符串是否为空格或空。
+ +函数签名: + +```go +func IsBlank(str string) bool +``` + +示例:[运行](https://go.dev/play/p/6zXRH_c0Qd3) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.IsBlank("") + result2 := strutil.IsBlank("\t\v\f\n") + result3 := strutil.IsBlank(" 中文") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### IsNotBlank + +Checks if a string is not whitespace or not empty.
+ +函数签名: + +```go +func IsNotBlank(str string) bool +``` + +示例:[运行](https://go.dev/play/p/e_oJW0RAquA) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.IsNotBlank("") + result2 := strutil.IsNotBlank(" ") + result3 := strutil.IsNotBlank("\t\v\f\n") + result4 := strutil.IsNotBlank(" 中文") + result5 := strutil.IsNotBlank(" world ") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + // Output: + // false + // false + // false + // true + // true +} +``` + +### HasPrefixAny + +检查字符串是否以指定字符串数组中的任何一个开头。
+ +函数签名: + +```go +func HasPrefixAny(str string, prefixes []string) bool +``` + +示例:[运行](https://go.dev/play/p/8UUTl2C5slo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.HasPrefixAny("foo bar", []string{"fo", "xyz", "hello"}) + result2 := strutil.HasPrefixAny("foo bar", []string{"oom", "world"}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### HasSuffixAny + +检查字符串是否以指定字符串数组中的任何一个结尾。
+ +函数签名: + +```go +func HasSuffixAny(str string, suffixes []string) bool +``` + +示例:[运行](https://go.dev/play/p/sKWpCQdOVkx) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.HasSuffixAny("foo bar", []string{"bar", "xyz", "hello"}) + result2 := strutil.HasSuffixAny("foo bar", []string{"oom", "world"}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IndexOffset + +将字符串偏移idxFrom后,返回字符串中第一个 substr 实例的索引,如果字符串中不存在 substr,则返回 -1。
+ +函数签名: + +```go +func IndexOffset(str string, substr string, idxFrom int) int +``` + +示例:[运行](https://go.dev/play/p/qZo4lV2fomB) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := "foo bar hello world" + + result1 := strutil.IndexOffset(str, "o", 5) + result2 := strutil.IndexOffset(str, "o", 0) + result3 := strutil.IndexOffset(str, "d", len(str)-1) + result4 := strutil.IndexOffset(str, "d", len(str)) + result5 := strutil.IndexOffset(str, "f", -1) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // 12 + // 1 + // 18 + // -1 + // -1 +} +``` + +### ReplaceWithMap + +返回`str`的副本,以无序的方式被map替换,区分大小写。
+ +函数签名: + +```go +func ReplaceWithMap(str string, replaces map[string]string) string +``` + +示例:[运行](https://go.dev/play/p/h3t7CNj2Vvu) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := "ac ab ab ac" + replaces := map[string]string{ + "a": "1", + "b": "2", + } + + result := strutil.ReplaceWithMap(str, replaces) + + fmt.Println(result) + // Output: + // 1c 12 12 1c +} +``` + +### Trim + +从字符串的开头和结尾去除空格(或其他字符)。 可选参数 characterMask 指定额外的剥离字符。
+ +函数签名: + +```go +func Trim(str string, characterMask ...string) string +``` + +示例:[运行](https://go.dev/play/p/Y0ilP0NRV3j) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Trim("\nabcd") + + str := "$ ab cd $ " + + result2 := strutil.Trim(str) + result3 := strutil.Trim(str, "$") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // abcd + // $ ab cd $ + // ab cd +} +``` + +### SplitAndTrim + +将字符串str按字符串delimiter拆分为一个切片,并对该数组的每个元素调用Trim。忽略Trim后为空的元素。
+ +函数签名: + +```go +func SplitAndTrim(str, delimiter string, characterMask ...string) []string +``` + +示例:[运行](https://go.dev/play/p/ZNL6o4SkYQ7) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := " a,b, c,d,$1 " + + result1 := strutil.SplitAndTrim(str, ",") + result2 := strutil.SplitAndTrim(str, ",", "$") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // [a b c d $1] + // [a b c d 1] +} +``` + +### HideString + +使用参数`replaceChar`隐藏源字符串中的一些字符。替换范围是 origin[start : end]。
+ +函数签名: + +```go +func HideString(origin string, start, end int, replaceChar string) string +``` + +示例:[运行](https://go.dev/play/p/pzbaIVCTreZ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := "13242658976" + + result1 := strutil.HideString(str, 3, 3, "*") + result2 := strutil.HideString(str, 3, 4, "*") + result3 := strutil.HideString(str, 3, 7, "*") + result4 := strutil.HideString(str, 7, 11, "*") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 13242658976 + // 132*2658976 + // 132****8976 + // 1324265**** +} +``` + +### ContainsAll + +判断字符串是否包括全部给定的子字符串切片。
+ +函数签名: + +```go +func ContainsAll(str string, substrs []string) bool +``` + +示例:[运行](https://go.dev/play/p/KECtK2Os4zq) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := "hello world" + + result1 := strutil.ContainsAll(str, []string{"hello", "world"}) + result2 := strutil.ContainsAll(str, []string{"hello", "abc"}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### ContainsAny + +判断字符串是否包括给定的子字符串切片中任意一个子字符串。
+ +函数签名: + +```go +func ContainsAny(str string, substrs []string) bool +``` + +示例:[运行](https://go.dev/play/p/dZGSSMB3LXE) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := "hello world" + + result1 := strutil.ContainsAny(str, []string{"hello", "world"}) + result2 := strutil.ContainsAny(str, []string{"hello", "abc"}) + result3 := strutil.ContainsAny(str, []string{"123", "abc"}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### RemoveWhiteSpace + +删除字符串中的空格,当设置repalceAll为true时,删除全部空格,为false时,替换多个空格为1个空格。
+ +函数签名: + +```go +func RemoveWhiteSpace(str string, repalceAll bool) string +``` + +示例:[运行](https://go.dev/play/p/HzLC9vsTwkf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := " hello \r\n \t world" + + result1 := strutil.RemoveWhiteSpace(str, true) + result2 := strutil.RemoveWhiteSpace(str, false) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // helloworld + // hello world +} +``` + +### SubInBetween + +获取字符串中指定的起始字符串start和终止字符串end直接的子字符串。
+ +函数签名: + +```go +func SubInBetween(str string, start string, end string) string +``` + +示例:[运行](https://go.dev/play/p/EDbaRvjeNsv) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := "abcde" + + result1 := strutil.SubInBetween(str, "", "de") + result2 := strutil.SubInBetween(str, "a", "d") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // abc + // bc +} +``` + +### HammingDistance + +计算两个字符串之间的汉明距离。汉明距离是指对应符号不同的位置数。
+ +函数签名: + +```go +func HammingDistance(a, b string) (int, error) +``` + +示例:[运行](https://go.dev/play/p/glNdQEA9HUi) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + + result1, _ := strutil.HammingDistance("de", "de") + result2, _ := strutil.HammingDistance("a", "d") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // 1 +} + +``` +### Concat + +拼接字符串。length是拼接后字符串的长度,如果不确定则传0或负数。
+ +函数签名: + +```go +func Concat(length int, str ...string) string +``` + +示例:[运行](https://go.dev/play/p/gD52SZHr4Kp) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Concat(12, "Hello", " ", "World", "!") + result2 := strutil.Concat(11, "Go", " ", "Language") + result3 := strutil.Concat(0, "An apple a ", "day,", "keeps the", " doctor away") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // Hello World! + // Go Language + // An apple a day,keeps the doctor away +} +``` + +### Ellipsis + +将字符串截断到指定长度,并在末尾添加省略号。
+ +函数签名: + +```go +func Ellipsis(str string, length int) string +``` + +示例:[运行](https://go.dev/play/p/i1vbdQiQVRR) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Ellipsis("hello world", 5) + result2 := strutil.Ellipsis("你好,世界!", 2) + result3 := strutil.Ellipsis("😀😃😄😁😆", 3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // hello... + // 你好... + // 😀😃😄... +} +``` + +### Shuffle + +打乱给定字符串中的字符顺序。
+ +函数签名: + +```go +func Shuffle(str string) string +``` + +示例:[运行](https://go.dev/play/p/iStFwBwyGY7) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result := strutil.Shuffle("hello") + fmt.Println(result) //olelh (random order) +} +``` + +### Rotate + +按指定的字符数旋转字符串。
+ +函数签名: + +```go +func Rotate(str string, shift int) string +``` + +示例:[运行](https://go.dev/play/p/Kf03iOeT5bd) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Rotate("Hello", 0) + result2 := strutil.Rotate("Hello", 1) + result3 := strutil.Rotate("Hello", 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // Hello + // oHell + // loHel +} +``` + +### TemplateReplace + +将模板字符串中的占位符替换为map中的相应值。占位符括在花括号中,例如 {key}。例如,模板字符串为“Hello, {name}!”,map为{"name": "world"},结果将为“Hello, world!”。
+ +函数签名: + +```go +func TemplateReplace(template string, data map[string]string) string +``` + +示例:[运行](https://go.dev/play/p/cXSuFvyZqv9) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + template := `Hello, my name is {name}, I'm {age} years old.` + data := map[string]string{ + "name": "Bob", + "age": "20", + } + + result := strutil.TemplateReplace(template, data) + + fmt.Println(result) + + // Output: + // Hello, my name is Bob, I'm 20 years old. +} +``` + +### RegexMatchAllGroups + +使用正则表达式匹配字符串中的所有子组并返回结果。
+ +函数签名: + +```go +func RegexMatchAllGroups(pattern, str string) [][]string +``` + +示例:[运行](https://go.dev/play/p/JZiu0RXpgN-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + pattern := `(\w+\.+\w+)@(\w+)\.(\w+)` + str := "Emails: john.doe@example.com and jane.doe@example.com" + + result := strutil.RegexMatchAllGroups(pattern, str) + + fmt.Println(result[0]) + fmt.Println(result[1]) + + // Output: + // [john.doe@example.com john.doe example com] + // [jane.doe@example.com jane.doe example com] +} +``` + +### ExtractContent + +提取两个标记之间的内容。
+ +函数签名: + +```go +func ExtractContent(s, start, end string) []string +``` + +示例:[运行](https://go.dev/play/p/Ay9UIk7Rum9) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + html := `content1aacontent2bbcontent1` + + result := strutil.ExtractContent(html, "", "") + + fmt.Println(result) + + // Output: + // [content1 content2 content1] +} +``` + +### FindAllOccurrences + +返回子字符串在字符串中所有出现的位置。
+ +函数签名: + +```go +func FindAllOccurrences(str, substr string) []int +``` + +示例:[运行](https://go.dev/play/p/uvyA6azGLB1) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result := strutil.FindAllOccurrences("ababab", "ab") + + fmt.Println(result) + + // Output: + // [0 2 4] +} +``` \ No newline at end of file diff --git a/docs/api/packages/system.md b/docs/api/packages/system.md new file mode 100644 index 00000000..937a8f0c --- /dev/null +++ b/docs/api/packages/system.md @@ -0,0 +1,444 @@ +# System + +system 包含 os, 运行time, shell command 相关函数。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/system" +) +``` + + + +## 目录 + +- [IsWindows](#IsWindows) +- [IsLinux](#IsLinux) +- [IsMac](#IsMac) +- [GetOsEnv](#GetOsEnv) +- [SetOsEnv](#SetOsEnv) +- [RemoveOsEnv](#RemoveOsEnv) +- [CompareOsEnv](#CompareOsEnv) +- [ExecCommand](#ExecCommand) +- [GetOsBits](#GetOsBits) +- [StartProcess](#StartProcess) +- [StopProcess](#StopProcess) +- [KillProcess](#KillProcess) +- [GetProcessInfo](#GetProcessInfo) + + + + +## 文档 + +### IsWindows + +检查当前操作系统是否是windows
+ +函数签名: + +```go +func IsWindows() bool +``` + +示例:[运行](https://go.dev/play/p/zIflQgZNuxD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + isOsWindows := system.IsWindows() + fmt.Println(isOsWindows) +} +``` + +### IsLinux + +检查当前操作系统是否是linux
+ +函数签名:[运行](https://go.dev/play/p/zIflQgZNuxD) + +```go +func IsLinux() bool +``` + +示例: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + isOsLinux := system.IsLinux() + fmt.Println(isOsLinux) +} +``` + +### IsMac + +检查当前操作系统是否是macos
+ +函数签名: + +```go +func IsMac() bool +``` + +示例:[运行](https://go.dev/play/p/Mg4Hjtyq7Zc) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + isOsMac := system.IsMac() + fmt.Println(isOsMac) +} +``` + +### GetOsEnv + +获取key命名的环境变量的值
+ +函数签名: + +```go +func GetOsEnv(key string) string +``` + +示例:[运行](https://go.dev/play/p/D88OYVCyjO-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + err := system.SetOsEnv("foo", "abc") + result := system.GetOsEnv("foo") + + fmt.Println(err) + fmt.Println(result) + // Output: + //设置由key命名的环境变量的值
+ +函数签名: + +```go +func SetOsEnv(key, value string) error +``` + +示例:[运行](https://go.dev/play/p/D88OYVCyjO-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + err := system.SetOsEnv("foo", "abc") + result := system.GetOsEnv("foo") + + fmt.Println(err) + fmt.Println(result) + // Output: + //删除单个环境变量
+ +函数签名: + +```go +func RemoveOsEnv(key string) error +``` + +示例:[运行](https://go.dev/play/p/fqyq4b3xUFQ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + err1 := system.SetOsEnv("foo", "abc") + result1 := GetOsEnv("foo") + + err2 := system.RemoveOsEnv("foo") + result2 := GetOsEnv("foo") + + fmt.Println(err1) + fmt.Println(err2) + fmt.Println(result1) + fmt.Println(result2) + + // Output: + //获取key命名的环境变量值并与compareEnv进行比较
+ +函数签名: + +```go +func CompareOsEnv(key, comparedEnv string) bool +``` + +示例:[运行](https://go.dev/play/p/BciHrKYOHbp) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + err := system.SetOsEnv("foo", "abc") + if err != nil { + return + } + + result := system.CompareOsEnv("foo", "abc") + + fmt.Println(result) + + // Output: + // true +} +``` + +### ExecCommand + +执行shell命令,返回命令的stdout和stderr字符串,如果出现错误,则返回错误。参数`command`是一个完整的命令字符串,如ls-a(linux),dir(windows),ping 127.0.0.1。在linux中,使用/bin/bash-c执行命令,在windows中,使用powershell.exe执行命令。 +函数的第二个参数是cmd选项控制参数,类型是func(*exec.Cmd),可以通过这个参数设置cmd属性。
+ +函数签名: + +```go +type ( + Option func(*exec.Cmd) +) +func ExecCommand(command string, opts ...Option) (stdout, stderr string, err error) +``` + +示例:[运行](https://go.dev/play/p/n-2fLyZef-4) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + // linux or mac + stdout, stderr, err := system.ExecCommand("ls", func(cmd *exec.Cmd) { + cmd.Dir = "/tmp" + }) + fmt.Println("std out: ", stdout) + fmt.Println("std err: ", stderr) + assert.Equal("", stderr) + + // windows + stdout, stderr, err = system.ExecCommand("dir") + fmt.Println("std out: ", stdout) + fmt.Println("std err: ", stderr) + + // error command + stdout, stderr, err = system.ExecCommand("abc") + fmt.Println("std out: ", stdout) + fmt.Println("std err: ", stderr) + if err != nil { + fmt.Println(err.Error()) + } +} +``` + +### GetOsBits + +获取当前操作系统位数,返回32或64
+ +函数签名: + +```go +func GetOsBits() int +``` + +示例:[运行](https://go.dev/play/p/ml-_XH3gJbW) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + osBit := system.GetOsBits() + fmt.Println(osBit) // 32 or 64 +} +``` + +### StartProcess + +创建进程。
+ +函数签名: + +```go +func StartProcess(command string, args ...string) (int, error) +``` + +示例:[运行](https://go.dev/play/p/5GVol6ryS_X) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + pid, err := system.StartProcess("sleep", "2") + if err != nil { + return + } + + fmt.Println(pid) +} +``` + +### StopProcess + +停止进程。
+ +函数签名: + +```go +func StopProcess(pid int) error +``` + +示例:[运行](https://go.dev/play/p/jJZhRYGGcmD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + pid, err := system.StartProcess("sleep", "10") + if err != nil { + return + } + time.Sleep(1 * time.Second) + + err = system.StopProcess(pid) + + fmt.Println(err) + + // Output: + //杀掉进程。
+ +函数签名: + +```go +func KillProcess(pid int) error +``` + +示例:[运行](https://go.dev/play/p/XKmvV-ExBWa) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + pid, err := system.StartProcess("sleep", "10") + if err != nil { + return + } + time.Sleep(1 * time.Second) + + err = system.KillProcess(pid) + + fmt.Println(err) + + // Output: + //根据进程id获取进程信息。
+ +函数签名: + +```go +func GetProcessInfo(pid int) (*ProcessInfo, error) +``` + +示例:[运行](https://go.dev/play/p/NQDVywEYYx7) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + pid, err := system.StartProcess("ls", "-a") + if err != nil { + return + } + + processInfo, err := system.GetProcessInfo(pid) + if err != nil { + return + } + + fmt.Println(processInfo) +} +``` \ No newline at end of file diff --git a/docs/api/packages/tuple.md b/docs/api/packages/tuple.md new file mode 100644 index 00000000..5c50e614 --- /dev/null +++ b/docs/api/packages/tuple.md @@ -0,0 +1,1198 @@ +# Tuple + +tuple包实现一个元组数据类型。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/tuple/tuple.go](https://github.com/duke-git/lancet/blob/main/tuple/tuple.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/pointer" +) +``` + + + +## 目录 + +- [Tuple2](#Tuple2) +- [Tuple2_Unbox](#Tuple2_Unbox) +- [Zip2](#Zip2) +- [Unzip2](#Unzip2) +- [Tuple3](#Tuple3) +- [Tuple3_Unbox](#Tuple3_Unbox) +- [Zip3](#Zip3) +- [Unzip3](#Unzip3) +- [Tuple4](#Tuple4) +- [Tuple4_Unbox](#Tuple4_Unbox) +- [Zip4](#Zip4) +- [Unzip4](#Unzip4) +- [Tuple5](#Tuple5) +- [Tuple5_Unbox](#Tuple5_Unbox) +- [Zip5](#Zip5) +- [Unzip5](#Unzip5) +- [Tuple6](#Tuple6) +- [Tuple6_Unbox](#Tuple6_Unbox) +- [Zip6](#Zip6) +- [Unzip6](#Unzip6) +- [Tuple7](#Tuple7) +- [Tuple7_Unbox](#Tuple7_Unbox) +- [Zip7](#Zip7) +- [Unzip7](#Unzip7) +- [Tuple8](#TTuple8uple6) +- [Tuple8_Unbox](#Tuple8_Unbox) +- [Zip8](#Zip8) +- [Unzip8](#Unzip8) +- [Tuple9](#Tuple9) +- [Tuple9_Unbox](#Tuple9_Unbox) +- [Zip9](#Zip9) +- [Unzip9](#Unzip9) +- [Tuple10](#Tuple10) +- [Tuple10_Unbox](#Tuple10_Unbox) +- [Zip10](#Zip10) +- [Unzip10](#Unzip10) + + + + +## 文档 + +### Tuple2 + +2元元组
+ +函数签名: + +```go +type Tuple2[A any, B any] struct { + FieldA A + FieldB B +} + +func NewTuple2[A any, B any](a A, b B) Tuple2[A, B] +``` + +示例:[运行](https://go.dev/play/p/3sHVqBQpLYN) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple2(1, 0.1) + fmt.Printf("%v %v", t.FieldA, t.FieldB) + + // Output: 1 0.1 +} +``` + +### Tuple2_Unbox + +返回元组的字段值。
+ +函数签名: + +```go +func (t Tuple2[A, B]) Unbox() (A, B) +``` + +示例:[运行](https://go.dev/play/p/0fD1qfCVwjm) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple2(1, 0.1) + v1, v2 := t.Unbox() + fmt.Printf("%v %v", v1, v2) + + // Output: 1 0.1 +} +``` + +### Zip2 + +创建一个Tuple2元组切片, 其中元组的元素和传入切片元素相对应。
+ +函数签名: + +```go +func Zip2[A any, B any](a []A, b []B) []Tuple2[A, B] +``` + +示例:[运行](https://go.dev/play/p/4ncWJJ77Xio) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip2([]int{1}, []float64{0.1}) + fmt.Println(result) + + // Output: [{1 0.1}] +} +``` + +### Unzip2 + +根据传入的Tuple2切片,创建一组和Tuple2元素相对应的切片。
+ +函数签名: + +```go +func Unzip2[A any, B any](tuples []Tuple2[A, B]) ([]A, []B) +``` + +示例:[运行](https://go.dev/play/p/KBecr60feXb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2 := tuple.Unzip2([]tuple.Tuple2[int, float64]{{FieldA: 1, FieldB: 0.1}}) + + fmt.Printf("%v %v", v1, v2) + + // Output: [1] [0.1] +} +``` + +### Tuple3 + +3元元组。
+ +函数签名: + +```go +type Tuple3[A any, B any, C any] struct { + FieldA A + FieldB B + FieldC C +} + +func NewTuple3[A any, B any, C any](a A, b B c C) Tuple3[A, B, C] +``` + +示例:[运行](https://go.dev/play/p/FtH2sdCLlCf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple3(1, 0.1, "a") + fmt.Printf("%v %v %v", t.FieldA, t.FieldB, t.FieldC) + + // Output: 1 0.1 a +} +``` + +### Tuple3_Unbox + +返回元组的字段值。
+ +函数签名: + +```go +func (t Tuple3[A, B, C]) Unbox() (A, B, C) +``` + +示例:[运行](https://go.dev/play/p/YojLy-id1BS) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple2(1, 0.1, "a") + v1, v2, v3 := t.Unbox() + fmt.Printf("%v %v %v", v1, v2, v3) + + // Output: 1 0.1 a +} +``` + +### Zip3 + +创建一个Tuple3元组切片, 其中元组的元素和传入切片元素相对应。
+ +函数签名: + +```go +func Zip3[A any, B any, C any](a []A, b []B, c []C) []Tuple3[A, B, C] +``` + +示例:[运行](https://go.dev/play/p/97NgmsTILfu) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip3([]int{1}, []float64{0.1}, []string{"a"}) + fmt.Println(result) + + // Output: [{1 0.1 a}] +} +``` + +### Unzip3 + +根据传入的Tuple3切片,创建一组和Tuple3元素相对应的切片。
+ +函数签名: + +```go +func Unzip3[A any, B any, C any](tuples []Tuple3[A, B, C]) ([]A, []B, []C) +``` + +示例:[运行](https://go.dev/play/p/bba4cpAa7KO) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3 := tuple.Unzip3([]tuple.Tuple3[int, float64, string]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a"}, + }) + + fmt.Printf("%v %v %v", v1, v2, v3) + + // Output: [1] [0.1] [a] +} +``` + +### Tuple4 + +4元元组。
+ +函数签名: + +```go +type Tuple4[A any, B any, C any, D any] struct { + FieldA A + FieldB B + FieldC C + FieldD D +} + +func NewTuple4[A any, B any, C any, D any](a A, b B, c C, d D) Tuple4[A, B, C, D] +``` + +示例:[运行](https://go.dev/play/p/D2EqDz096tk) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple4(1, 0.1, "a", true) + fmt.Printf("%v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD) + + // Output: 1 0.1 a true +} +``` + +### Tuple4_Unbox + +返回元组的字段值。
+ +函数签名: + +```go +func (t Tuple4[A, B, C, D]) Unbox() (A, B, C, D) +``` + +示例:[运行](https://go.dev/play/p/ACj9YuACGgW) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple4(1, 0.1, "a", true) + v1, v2, v3, v4 := t.Unbox() + fmt.Printf("%v %v %v %v", v1, v2, v3, v4) + + // Output: 1 0.1 a true +} +``` + +### Zip4 + +创建一个Tuple4元组切片, 其中元组的元素和传入切片元素相对应。
+ +函数签名: + +```go +func Zip4[A any, B any, C any, D any](a []A, b []B, c []C, d []D) []Tuple4[A, B, C, D] +``` + +示例:[运行](https://go.dev/play/p/PEmTYVK5hL4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip4([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}) + fmt.Println(result) + + // Output: [{1 0.1 a true}] +} +``` + +### Unzip4 + +根据传入的Tuple4切片,创建一组和Tuple4元素相对应的切片。
+ +函数签名: + +```go +func Unzip4[A any, B any, C any, D any](tuples []Tuple4[A, B, C, D]) ([]A, []B, []C, []D) +``` + +示例:[运行](https://go.dev/play/p/rb8z4gyYSRN) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4 := tuple.Unzip4([]tuple.Tuple4[int, float64, string, bool]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true}, + }) + + fmt.Printf("%v %v %v %v", v1, v2, v3, v4) + + // Output: [1] [0.1] [a] [true] +} +``` + +### Tuple5 + +5元元组。
+ +函数签名: + +```go +type Tuple5[A any, B any, C any, D any, E any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E +} + +func NewTuple5[A any, B any, C any, D any, E any](a A, b B, c C, d D, e E) Tuple5[A, B, C, D, E] +``` + +示例:[运行](https://go.dev/play/p/2WndmVxPg-r) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple5(1, 0.1, "a", true, 2) + fmt.Printf("%v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE) + + // Output: 1 0.1 a true 2 +} +``` + +### Tuple5_Unbox + +返回元组的字段值。
+ +函数签名: + +```go +func (t Tuple5[A, B, C, D, E]) Unbox() (A, B, C, D, E) +``` + +示例:[运行](https://go.dev/play/p/GyIyZHjCvoS) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple5(1, 0.1, "a", true, 2) + v1, v2, v3, v4, v5 := t.Unbox() + fmt.Printf("%v %v %v %v %v", v1, v2, v3, v4, v5) + + // Output: 1 0.1 a true 2 +} +``` + +### Zip5 + +创建一个Tuple5元组切片, 其中元组的元素和传入切片元素相对应。
+ +函数签名: + +```go +func Zip5[A any, B any, C any, D any, E any](a []A, b []B, c []C, d []D, e []E) []Tuple5[A, B, C, D, E] +``` + +示例:[运行](https://go.dev/play/p/fCAAJLMfBIP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip5([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}, []int{2}) + fmt.Println(result) + + // Output: [{1 0.1 a true 2}] +} +``` + +### Unzip5 + +根据传入的Tuple5切片,创建一组和Tuple5元素相对应的切片。
+ +函数签名: + +```go +func Unzip5[A any, B any, C any, D any, E any](tuples []Tuple5[A, B, C, D, E]) ([]A, []B, []C, []D, []E) +``` + +示例:[运行](https://go.dev/play/p/gyl6vKfhqPb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4, v5 := tuple.Unzip5([]tuple.Tuple5[int, float64, string, bool, int]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2}, + }) + + fmt.Printf("%v %v %v %v %v", v1, v2, v3, v4, v5) + + // Output: [1] [0.1] [a] [true] [2] +} +``` + +### Tuple6 + +6元元组。
+ +函数签名: + +```go +type Tuple6[A any, B any, C any, D any, E any, F any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F +} + +func NewTuple6[A any, B any, C any, D any, E any, F any](a A, b B, c C, d D, e E, f F) Tuple6[A, B, C, D, E, F] +``` + +示例:[运行](https://go.dev/play/p/VjqcCwEJZbs) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple6(1, 0.1, "a", true, 2, 2.2) + fmt.Printf("%v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF) + + // Output: 1 0.1 a true 2 2.2 +} +``` + +### Tuple6_Unbox + +返回元组的字段值。
+ +函数签名: + +```go +func (t Tuple6[A, B, C, D, E, F]) Unbox() (A, B, C, D, E, F) +``` + +示例:[运行](https://go.dev/play/p/FjIHV7lpxmW) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple6(1, 0.1, "a", true, 2, 2.2) + v1, v2, v3, v4, v5, v6 := t.Unbox() + fmt.Printf("%v %v %v %v %v %v", v1, v2, v3, v4, v5, v6) + + // Output: 1 0.1 a true 2 2.2 +} +``` + +### Zip6 + +创建一个Tuple6元组切片, 其中元组的元素和传入切片元素相对应。
+ +函数签名: + +```go +func Zip6[A any, B any, C any, D any, E any, F any](a []A, b []B, c []C, d []D, e []E, f []F) []Tuple6[A, B, C, D, E, F] +``` + +示例:[运行](https://go.dev/play/p/oWPrnUYuFHo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip6([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}, []int{2}, []float32{2.2}) + fmt.Println(result) + + // Output: [{1 0.1 a true 2 2.2}] +} +``` + +### Unzip6 + +根据传入的Tuple6切片,创建一组和Tuple6元素相对应的切片。
+ +函数签名: + +```go +func Unzip6[A any, B any, C any, D any, E any, F any](tuples []Tuple6[A, B, C, D, E, F]) ([]A, []B, []C, []D, []E, []F) +``` + +示例:[运行](https://go.dev/play/p/l41XFqCyh5E) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4, v5, v6 := tuple.Unzip6([]tuple.Tuple6[int, float64, string, bool, int, float32]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2}, + }) + + fmt.Printf("%v %v %v %v %v %v", v1, v2, v3, v4, v5, v6) + + // Output: [1] [0.1] [a] [true] [2] [2.2] +} +``` + +### Tuple7 + +7元元组。
+ +函数签名: + +```go +type Tuple7[A any, B any, C any, D any, E any, F any, G any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F + FieldG G +} + +func NewTuple7[A any, B any, C any, D any, E any, F any, G any](a A, b B, c C, d D, e E, f F, g G) Tuple7[A, B, C, D, E, F, G] +``` + +示例:[运行](https://go.dev/play/p/dzAgv_Ezub9) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple7(1, 0.1, "a", true, 2, 2.2, "b") + fmt.Printf("%v %v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG) + + // Output: 1 0.1 a true 2 2.2 b +} +``` + +### Tuple7_Unbox + +返回元组的字段值。
+ +函数签名: + +```go +func (t Tuple7[A, B, C, D, E, F, G]) Unbox() (A, B, C, D, E, F, G) +``` + +示例:[运行](https://go.dev/play/p/R9I8qeDk0zs) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple7(1, 0.1, "a", true, 2, 2.2, "b") + v1, v2, v3, v4, v5, v6, v7 := t.Unbox() + fmt.Printf("%v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7) + + // Output: 1 0.1 a true 2 2.2 b +} +``` + +### Zip7 + +创建一个Tuple7元组切片, 其中元组的元素和传入切片元素相对应。
+ +函数签名: + +```go +func Zip7[A any, B any, C any, D any, E any, F any, G any](a []A, b []B, c []C, d []D, e []E, f []F, g []G) []Tuple7[A, B, C, D, E, F, G] +``` + +示例:[运行](https://go.dev/play/p/WUJuo897Egf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip7([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}, []int{2}, []float32{2.2}, []string{"b"}) + fmt.Println(result) + + // Output: [{1 0.1 a true 2 2.2 b}] +} +``` + +### Unzip7 + +根据传入的Tuple7切片,创建一组和Tuple7元素相对应的切片。
+ +函数签名: + +```go +func Unzip7[A any, B any, C any, D any, E any, F any, G any](tuples []Tuple7[A, B, C, D, E, F, G]) ([]A, []B, []C, []D, []E, []F, []G) +``` + +示例:[运行](https://go.dev/play/p/hws_P1Fr2j3) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4, v5, v6, v7 := tuple.Unzip7([]tuple.Tuple7[int, float64, string, bool, int, float32, string]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b"}, + }) + + fmt.Printf("%v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7) + + // Output: [1] [0.1] [a] [true] [2] [2.2] [b] +} +``` + +### Tuple8 + +8元元组。
+ +函数签名: + +```go +type Tuple8[A any, B any, C any, D any, E any, F any, G any, H any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F + FieldG G + FieldH H +} + +func NewTuple8[A any, B any, C any, D any, E any, F any, G any, H any](a A, b B, c C, d D, e E, f F, g G, h H) Tuple8[A, B, C, D, E, F, G, H] +``` + +示例:[运行](https://go.dev/play/p/YA9S0rz3dRz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple8(1, 0.1, "a", true, 2, 2.2, "b", "c") + fmt.Printf("%v %v %v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH) + + // Output: 1 0.1 a true 2 2.2 b c +} +``` + +### Tuple8_Unbox + +返回元组的字段值。
+ +函数签名: + +```go +func (t Tuple8[A, B, C, D, E, F, G, H]) Unbox() (A, B, C, D, E, F, G, H) +``` + +示例:[运行](https://go.dev/play/p/PRxLBBb4SMl) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple8(1, 0.1, "a", true, 2, 2.2, "b", "c") + v1, v2, v3, v4, v5, v6, v7, v8 := t.Unbox() + fmt.Printf("%v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8) + + // Output: 1 0.1 a true 2 2.2 b c +} +``` + +### Zip8 + +创建一个Tuple8元组切片, 其中元组的元素和传入切片元素相对应。
+ +函数签名: + +```go +func Zip8[A any, B any, C any, D any, E any, F any, G any, H any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H) []Tuple8[A, B, C, D, E, F, G, H] +``` + +示例:[运行](https://go.dev/play/p/8V9jWkuJfaQ) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip8([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}, []int{2}, []float32{2.2}, []string{"b"}, []string{"c"}) + fmt.Println(result) + + // Output: [{1 0.1 a true 2 2.2 b c}] +} +``` + +### Unzip8 + +根据传入的Tuple8切片,创建一组和Tuple8元素相对应的切片。
+ +函数签名: + +```go +func Unzip8[A any, B any, C any, D any, E any, F any, G any, H any](tuples []Tuple8[A, B, C, D, E, F, G, H]) ([]A, []B, []C, []D, []E, []F, []G, []H) +``` + +示例:[运行](https://go.dev/play/p/1SndOwGsZB4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4, v5, v6, v7, v8 := tuple.Unzip8([]tuple.Tuple8[int, float64, string, bool, int, float32, string, string]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b", FieldH: "c"}, + }) + + fmt.Printf("%v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8) + + // Output: [1] [0.1] [a] [true] [2] [2.2] [b] [c] +} +``` + +### Tuple9 + +9元元组。
+ +函数签名: + +```go + +type Tuple9[A any, B any, C any, D any, E any, F any, G any, H any, I any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F + FieldG G + FieldH H + FieldI I +} + +func NewTuple9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a A, b B, c C, d D, e E, f F, g G, h H, i I) Tuple9[A, B, C, D, E, F, G, H, I] + +``` + +示例:[运行](https://go.dev/play/p/yS2NGGtZpQr) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple9(1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}) + fmt.Printf("%v %v %v %v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH, t.FieldI) + + // Output: 1 0.1 a true 2 2.2 b c map[a:1] +} +``` + +### Tuple9_Unbox + +返回元组的字段值。
+ +函数签名: + +```go +func (t Tuple9[A, B, C, D, E, F, G, H, I]) Unbox() (A, B, C, D, E, F, G, H, I) +``` + +示例:[运行](https://go.dev/play/p/oFJFGTAuOa8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple9(1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}) + v1, v2, v3, v4, v5, v6, v7, v8, v9 := t.Unbox() + fmt.Printf("%v %v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8, v9) + + // Output: 1 0.1 a true 2 2.2 b c map[a:1] +} +``` + +### Zip9 + +创建一个Tuple9元组切片, 其中元组的元素和传入切片元素相对应。
+ +函数签名: + +```go +func Zip9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I) []Tuple9[A, B, C, D, E, F, G, H, I] +``` + +示例:[运行](https://go.dev/play/p/cgsL15QYnfz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip9([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}, []int{2}, []float32{2.2}, []string{"b"}, []string{"c"}, []int64{3}) + fmt.Println(result) + + // Output: [{1 0.1 a true 2 2.2 b c 3}] +} +``` + +### Unzip9 + +根据传入的Tuple9切片,创建一组和Tuple9元素相对应的切片。
+ +函数签名: + +```go +func Unzip9[A any, B any, C any, D any, E any, F any, G any, H any, I any](tuples []Tuple9[A, B, C, D, E, F, G, H, I]) ([]A, []B, []C, []D, []E, []F, []G, []H, []I) +``` + +示例:[运行](https://go.dev/play/p/91-BU_KURSA) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4, v5, v6, v7, v8, v9 := tuple.Unzip9([]tuple.Tuple9[int, float64, string, bool, int, float32, string, string, int64]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b", FieldH: "c", FieldI: 3}, + }) + + fmt.Printf("%v %v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8, v9) + + // Output: [1] [0.1] [a] [true] [2] [2.2] [b] [c] [3] +} +``` + +### Tuple10 + +10元元组。
+ +函数签名: + +```go + +type Tuple10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F + FieldG G + FieldH H + FieldI I + FieldJ J +} + +func NewTuple10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](a A, b B, c C, d D, e E, f F, g G, h H, i I, j J) Tuple10[A, B, C, D, E, F, G, H, I, J] + +``` + +示例:[运行](https://go.dev/play/p/799qqZg0hUv) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + type foo struct { + A string + } + t := tuple.NewTuple10(1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}, foo{A: "a"}) + fmt.Printf("%v %v %v %v %v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH, t.FieldI, t.FieldJ) + + // Output: 1 0.1 a true 2 2.2 b c map[a:1] {a} +} +``` + +### Tuple10_Unbox + +返回元组的字段值。
+ +函数签名: + +```go +func (t Tuple10[A, B, C, D, E, F, G, H, I, J]) Unbox() (A, B, C, D, E, F, G, H, I, J) +``` + +示例:[运行](https://go.dev/play/p/qfyx3x_X0Cu) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + type foo struct { + A string + } + t := tuple.NewTuple10(1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}, foo{A: "a"}) + v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 := t.Unbox() + fmt.Printf("%v %v %v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) + + // Output: 1 0.1 a true 2 2.2 b c map[a:1] {a} +} +``` + +### Zip10 + +创建一个Tuple10元组切片, 其中元组的元素和传入切片元素相对应。
+ +函数签名: + +```go +func Zip10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I, j []J) []Tuple10[A, B, C, D, E, F, G, H, I, J] +``` + +示例:[运行](https://go.dev/play/p/YSR-2cXnrY4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip10([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}, []int{2}, []float32{2.2}, []string{"b"}, []string{"c"}, []int64{3}, []bool{false}) + fmt.Println(result) + + // Output: [{1 0.1 a true 2 2.2 b c 3 false}] +} +``` + +### Unzip10 + +根据传入的Tuple10切片,创建一组和Tuple10元素相对应的切片。
+ +函数签名: + +```go +func Unzip10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](tuples []Tuple10[A, B, C, D, E, F, G, H, I, J]) ([]A, []B, []C, []D, []E, []F, []G, []H, []I, []J) +``` + +示例:[运行](https://go.dev/play/p/-taQB6Wfre_z) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 := tuple.Unzip10([]tuple.Tuple10[int, float64, string, bool, int, float32, string, string, int64, bool]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b", FieldH: "c", FieldI: 3, FieldJ: false}, + }) + + fmt.Printf("%v %v %v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) + + // Output: [1] [0.1] [a] [true] [2] [2.2] [b] [c] [3] [false] +} +``` diff --git a/docs/api/packages/validator.md b/docs/api/packages/validator.md new file mode 100644 index 00000000..b354ce05 --- /dev/null +++ b/docs/api/packages/validator.md @@ -0,0 +1,1569 @@ +# Validator + +validator 验证器包,包含常用字符串格式验证函数。 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/validator/validator.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/validator" +) +``` + + + +## 目录: + +- [ContainChinese](#ContainChinese) +- [ContainLetter](#ContainLetter) +- [ContainLower](#ContainLower) +- [ContainUpper](#ContainUpper) +- [IsAlpha](#IsAlpha) +- [IsAllUpper](#IsAllUpper) +- [IsAllLower](#IsAllLower) +- [IsASCII](#IsASCII) +- [IsBase64](#IsBase64) +- [IsChineseMobile](#IsChineseMobile) +- [IsChineseIdNum](#IsChineseIdNum) +- [IsChinesePhone](#IsChinesePhone) +- [IsCreditCard](#IsCreditCard) +- [IsDns](#IsDns) +- [IsEmail](#IsEmail) +- [IsEmptyString](#IsEmptyString) +- [IsInt](#IsInt) +- [IsFloat](#IsFloat) +- [IsNumber](#IsNumber) +- [IsIntStr](#IsIntStr) +- [IsFloatStr](#IsFloatStr) +- [IsNumberStr](#IsNumberStr) +- [IsJSON](#IsJSON) +- [IsRegexMatch](#IsRegexMatch) +- [IsIp](#IsIp) +- [IsIpV4](#IsIpV4) +- [IsIpV6](#IsIpV6) +- [IsIpPort](#IsIpPort) +- [IsStrongPassword](#IsStrongPassword) +- [IsUrl](#IsUrl) +- [IsWeakPassword](#IsWeakPassword) +- [IsZeroValue](#IsZeroValue) +- [IsGBK](#IsGBK) +- [IsPrintable](#IsPrintable) +- [IsBin](#IsBin) +- [IsHex](#IsHex) +- [IsBase64URL](#IsBase64URL) +- [IsJWT](#IsJWT) +- [IsVisa](#IsVisa) +- [IsMasterCard](#IsMasterCard) +- [IsAmericanExpress](#IsAmericanExpress) +- [IsUnionPay](#IsUnionPay) +- [IsChinaUnionPay](#IsChinaUnionPay) + + + +## 文档 + +### ContainChinese + +验证字符串是否包含中文字符。
+ +函数签名: + +```go +func ContainChinese(s string) bool +``` + +示例:[运行](https://go.dev/play/p/7DpU0uElYeM) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.ContainChinese("你好") + result2 := validator.ContainChinese("你好hello") + result3 := validator.ContainChinese("hello") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### ContainLetter + +验证字符串是否包含至少一个英文字母。
+ +函数签名: + +```go +func ContainLetter(str string) bool +``` + +示例:[运行](https://go.dev/play/p/lqFD04Yyewp) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.ContainLetter("你好") + result2 := validator.ContainLetter("&@#$%^&*") + result3 := validator.ContainLetter("ab1") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // false + // false + // true +} +``` + +### ContainLower + +验证字符串是否包含至少一个英文小写字母。
+ +函数签名: + +```go +func ContainLower(str string) bool +``` + +示例:[运行](https://go.dev/play/p/Srqi1ItvnAA) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.ContainLower("abc") + result2 := validator.ContainLower("aBC") + result3 := validator.ContainLower("ABC") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### ContainUpper + +验证字符串是否包含至少一个英文大写字母。
+ +函数签名: + +```go +func ContainUpper(str string) bool +``` + +示例:[运行](https://go.dev/play/p/CmWeBEk27-z) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.ContainUpper("ABC") + result2 := validator.ContainUpper("abC") + result3 := validator.ContainUpper("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### IsAlpha + +验证字符串是否只包含英文字母。
+ +函数签名: + +```go +func IsAlpha(s string) bool +``` + +示例:[运行](https://go.dev/play/p/7Q5sGOz2izQ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsAlpha("abc") + result2 := validator.IsAlpha("ab1") + result3 := validator.IsAlpha("") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsAllUpper + +验证字符串是否全是大写英文字母。
+ +函数签名: + +```go +func IsAllUpper(str string) bool +``` + +示例:[运行](https://go.dev/play/p/ZHctgeK1n4Z) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsAllUpper("ABC") + result2 := validator.IsAllUpper("ABc") + result3 := validator.IsAllUpper("AB1") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsAllLower + +验证字符串是否全是小写英文字母。
+ +函数签名: + +```go +func IsAllLower(str string) bool +``` + +示例:[运行](https://go.dev/play/p/GjqCnOfV6cM) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsAllLower("abc") + result2 := validator.IsAllLower("abC") + result3 := validator.IsAllLower("ab1") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsASCII + +验证字符串全部为ASCII字符。
+ +函数签名: + +```go +func IsASCII(str string) bool +``` + +示例:[运行](https://go.dev/play/p/hfQNPLX0jNa) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsASCII("ABC") + result2 := validator.IsASCII("123") + result3 := validator.IsASCII("") + result4 := validator.IsASCII("😄") + result5 := validator.IsASCII("你好") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // true + // true + // true + // false + // false +} +``` + +### IsBase64 + +验证字符串是否是base64编码。
+ +函数签名: + +```go +func IsBase64(base64 string) bool +``` + +示例:[运行](https://go.dev/play/p/sWHEySAt6hl) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsBase64("aGVsbG8=") + result2 := validator.IsBase64("123456") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsChineseMobile + +验证字符串是否是中国手机号码。
+ +函数签名: + +```go +func IsChineseMobile(mobileNum string) bool +``` + +示例:[运行](https://go.dev/play/p/GPYUlGTOqe3) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsChineseMobile("13263527980") + result2 := validator.IsChineseMobile("434324324") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsChineseIdNum + +验证字符串是否是中国身份证号码。
+ +函数签名: + +```go +func IsChineseIdNum(id string) bool +``` + +示例:[运行](https://go.dev/play/p/d8EWhl2UGDF) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsChineseIdNum("210911192105130715") + result2 := validator.IsChineseIdNum("123456") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsChinesePhone + +验证字符串是否是中国电话座机号码。
+ +函数签名: + +```go +func IsChinesePhone(phone string) bool +``` + +示例:[运行](https://go.dev/play/p/RUD_-7YZJ3I) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsChinesePhone("010-32116675") + result2 := validator.IsChinesePhone("123-87562") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsCreditCard + +验证字符串是否是信用卡号码。
+ +函数签名: + +```go +func IsCreditCard(creditCart string) bool +``` + +示例:[运行](https://go.dev/play/p/sNwwL6B0-v4) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsCreditCard("4111111111111111") + result2 := validator.IsCreditCard("123456") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsDns + +验证字符串是否是有效dns。
+ +函数签名: + +```go +func IsDns(dns string) bool +``` + +示例:[运行](https://go.dev/play/p/jlYApVLLGTZ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsDns("abc.com") + result2 := validator.IsDns("a.b.com") + result3 := validator.IsDns("http://abc.com") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsEmail + +验证字符串是否是有效电子邮件地址。
+ +函数签名: + +```go +func IsEmail(email string) bool +``` + +示例:[运行](https://go.dev/play/p/Os9VaFlT33G) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsEmail("abc@xyz.com") + result2 := validator.IsEmail("a.b@@com") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsEmptyString + +验证字符串是否是空字符串。
+ +函数签名: + +```go +func IsEmptyString(s string) bool +``` + +示例:[运行](https://go.dev/play/p/dpzgUjFnBCX) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsEmptyString("") + result2 := validator.IsEmptyString(" ") + result3 := validator.IsEmptyString("\t") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsInt + +验证参数是否是整数(int, unit)。
+ +函数签名: + +```go +func IsInt(v any) bool +``` + +示例:[运行](https://go.dev/play/p/eFoIHbgzl-z) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsInt("") + result2 := validator.IsInt("3") + result3 := validator.IsInt(0.1) + result4 := validator.IsInt(0) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // false + // true +} +``` + +### IsFloat + +验证参数是否是浮点数(float32, float34)。
+ +函数签名: + +```go +func IsFloat(v any) bool +``` + +示例:[运行](https://go.dev/play/p/vsyG-sxr99_Z) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsFloat("") + result2 := validator.IsFloat("3") + result3 := validator.IsFloat(0) + result4 := validator.IsFloat(0.1) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // false + // true +} +``` + +### IsNumber + +验证参数是否是数字(integer or float)。
+ +函数签名: + +```go +func IsNumber(v any) bool +``` + +示例:[运行](https://go.dev/play/p/mdJHOAvtsvF) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsNumber("") + result2 := validator.IsNumber("3") + result3 := validator.IsNumber(0.1) + result4 := validator.IsNumber(0) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // true + // true +} +``` + +### IsIntStr + +验证字符串是否是可以转换为整数。
+ +函数签名: + +```go +func IsIntStr(s string) bool +``` + +示例:[运行](https://go.dev/play/p/jQRtFv-a0Rk) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsIntStr("+3") + result2 := validator.IsIntStr("-3") + result3 := validator.IsIntStr("3.") + result4 := validator.IsIntStr("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsFloatStr + +验证字符串是否是可以转换为浮点数。
+ +函数签名: + +```go +func IsFloatStr(s string) bool +``` + +示例:[运行](https://go.dev/play/p/LOYwS_Oyl7U) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsFloatStr("3.") + result2 := validator.IsFloatStr("+3.") + result3 := validator.IsFloatStr("12") + result4 := validator.IsFloatStr("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // true + // false +} +``` + +### IsNumberStr + +验证字符串是否是可以转换为数字。
+ +函数签名: + +```go +func IsNumberStr(s string) bool +``` + +示例:[运行](https://go.dev/play/p/LzaKocSV79u) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsNumberStr("3.") + result2 := validator.IsNumberStr("+3.") + result3 := validator.IsNumberStr("+3e2") + result4 := validator.IsNumberStr("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // true + // false +} +``` + +### IsAlphaNumeric + +验证字符串是字母或数字。
+ +函数签名: + +```go +func IsAlphaNumeric(s string) bool +``` + +示例:[运行](https://go.dev/play/p/RHeESLrLg9c) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsAlphaNumeric("ABC") + result2 := validator.IsAlphaNumeric("123") + result3 := validator.IsAlphaNumeric("abc123") + result4 := validator.IsAlphaNumeric("abc123@#$") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // true + // false +} +``` + +### IsJSON + +验证字符串是否是有效json。
+ +函数签名: + +```go +func IsJSON(str string) bool +``` + +示例:[运行](https://go.dev/play/p/8Kip1Itjiil) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsJSON("{}") + result2 := validator.IsJSON("{\"name\": \"test\"}") + result3 := validator.IsJSON("") + result4 := validator.IsJSON("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsRegexMatch + +验证字符串是否可以匹配正则表达式。
+ +函数签名: + +```go +func IsRegexMatch(s, regex string) bool +``` + +示例:[运行](https://go.dev/play/p/z_XeZo_litG) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsRegexMatch("abc", `^[a-zA-Z]+$`) + result2 := validator.IsRegexMatch("ab1", `^[a-zA-Z]+$`) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsIp + +验证字符串是否是ip地址。
+ +函数签名: + +```go +func IsIp(ipstr string) bool +``` + +示例:[运行](https://go.dev/play/p/FgcplDvmxoD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsIp("127.0.0.1") + result2 := validator.IsIp("::0:0:0:0:0:0:1") + result3 := validator.IsIp("127.0.0") + result4 := validator.IsIp("::0:0:0:0:") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsIpV4 + +验证字符串是否是ipv4地址。
+ +函数签名: + +```go +func IsIpV4(ipstr string) bool +``` + +示例:[运行](https://go.dev/play/p/zBGT99EjaIu) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsIpV4("127.0.0.1") + result2 := validator.IsIpV4("::0:0:0:0:0:0:1") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsIpV6 + +验证字符串是否是ipv6地址。
+ +函数签名: + +```go +func IsIpV6(ipstr string) bool +``` + +示例:[运行](https://go.dev/play/p/AHA0r0AzIdC) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsIpV6("127.0.0.1") + result2 := validator.IsIpV6("::0:0:0:0:0:0:1") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // false + // true +} +``` + +### IsIpPort + +检查字符串是否是ip:port格式。
+ +函数签名: + +```go +func IsIpPort(str string) bool +``` + +示例:[运行](https://go.dev/play/p/xUmls_b9L29) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsIpPort("127.0.0.1:8080") + result2 := validator.IsIpPort("[0:0:0:0:0:0:0:1]:8080") + result3 := validator.IsIpPort(":8080") + result4 := validator.IsIpPort("::0:0:0:0:") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsStrongPassword + +验证字符串是否是强密码:(alpha(lower+upper) + number + special chars(!@#$%^&*()?><))。
+ +函数签名: + +```go +func IsStrongPassword(password string, length int) bool +``` + +示例:[运行](https://go.dev/play/p/QHdVcSQ3uDg) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsStrongPassword("abcABC", 6) + result2 := validator.IsStrongPassword("abcABC123@#$", 10) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // false + // true +} +``` + +### IsUrl + +验证字符串是否是url。
+ +函数签名: + +```go +func IsUrl(str string) bool +``` + +示例:[运行](https://go.dev/play/p/pbJGa7F98Ka) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsUrl("abc.com") + result2 := validator.IsUrl("http://abc.com") + result3 := validator.IsUrl("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### IsWeakPassword + +验证字符串是否是弱密码:(only letter or only number or letter + number) +。
+ +函数签名: + +```go +func IsWeakPassword(password string, length int) bool +``` + +示例:[运行](https://go.dev/play/p/wqakscZH5gH) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsWeakPassword("abcABC") + result2 := validator.IsWeakPassword("abc123@#$") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsZeroValue + +判断传入的参数值是否为零值。
+ +函数签名: + +```go +func IsZeroValue(value any) bool +``` + +示例:[运行](https://go.dev/play/p/UMrwaDCi_t4) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsZeroValue("") + result2 := validator.IsZeroValue(0) + result3 := validator.IsZeroValue("abc") + result4 := validator.IsZeroValue(1) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsGBK + +检查数据编码是否为gbk(汉字内部代码扩展规范)。该函数的实现取决于双字节是否在gbk的编码范围内,而utf-8编码格式的每个字节都在gbk编码范围内。因此,应该首先调用utf8.valid检查它是否是utf-8编码,然后调用IsGBK检查gbk编码。如示例所示。
+ +函数签名: + +```go +func IsGBK(data []byte) bool +``` + +示例:[运行](https://go.dev/play/p/E2nt3unlmzP) + +```go +import ( + "fmt" + "golang.org/x/text/encoding/simplifiedchinese" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + str := "你好" + gbkData, _ := simplifiedchinese.GBK.NewEncoder().Bytes([]byte(str)) + + result := validator.IsGBK(gbkData) + + fmt.Println(result) + + // Output: + // true +} +``` + +### IsPrintable + +检查字符串是否全部为可打印字符。
+ +函数签名: + +```go +func IsPrintable(str string) bool +``` + +示例:[运行](https://go.dev/play/p/Pe1FE2gdtTP) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsPrintable("ABC") + result2 := validator.IsPrintable("{id: 123}") + result3 := validator.IsPrintable("") + result4 := validator.IsPrintable("😄") + result5 := validator.IsPrintable("\u0000") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // true + // true + // true + // true + // false +} +``` + +### IsBin + +检查字符串是否是有效的二进制数。
+ +函数签名: + +```go +func IsBin(v string) bool +``` + +示例:[运行](https://go.dev/play/p/ogPeg2XJH4P) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsBin("0101") + result2 := validator.IsBin("0b1101") + result3 := validator.IsBin("b1101") + result4 := validator.IsBin("1201") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsHex + +检查字符串是否是有效的十六进制数。
+ +函数签名: + +```go +func IsHex(v string) bool +``` + +示例:[运行](https://go.dev/play/p/M2qpHbEwmm7) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsHex("0xabcde") + result2 := validator.IsHex("0XABCDE") + result3 := validator.IsHex("cdfeg") + result4 := validator.IsHex("0xcdfeg") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsBase64URL + +检查字符串是否是有效的base64 url。
+ +函数签名: + +```go +func IsBase64URL(v string) bool +``` + +示例:[运行](https://go.dev/play/p/vhl4mr8GZ6S) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ") + result2 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ==") + result3 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ=") + result4 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ===") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsJWT + +检查字符串是否是有效的JSON Web Token (JWT)。
+ +函数签名: + +```go +func IsJWT(v string) bool +``` + +示例:[运行](https://go.dev/play/p/R6Op7heJbKI) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsJWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibWVzc2FnZSI6IlB1dGluIGlzIGFic29sdXRlIHNoaXQiLCJpYXQiOjE1MTYyMzkwMjJ9.wkLWA5GtCpWdxNOrRse8yHZgORDgf8TpJp73WUQb910") + result2 := validator.IsJWT("abc") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsVisa + +检查字符串是否是有效的visa卡号。
+ +函数签名: + +```go +func IsVisa(v string) bool +``` + +示例:[运行](https://go.dev/play/p/SdS2keOyJsl) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsVisa("4111111111111111") + result2 := validator.IsVisa("123") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsMasterCard + +检查字符串是否是有效的MasterCard卡号。
+ +函数签名: + +```go +func IsMasterCard(v string) bool +``` + +示例:[运行](https://go.dev/play/p/CwWBFRrG27b) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsMasterCard("5425233430109903") + result2 := validator.IsMasterCard("4111111111111111") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsAmericanExpress + +检查字符串是否是有效的American Express卡号。
+ +函数签名: + +```go +func IsAmericanExpress(v string) bool +``` + +示例:[运行](https://go.dev/play/p/HIDFpcOdpkd) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsAmericanExpress("342883359122187") + result2 := validator.IsAmericanExpress("3782822463100007") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsUnionPay + +检查字符串是否是有效的美国银联卡号。
+ +函数签名: + +```go +func IsUnionPay(v string) bool +``` + +示例:[运行](https://go.dev/play/p/CUHPEwEITDf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsUnionPay("6221263430109903") + result2 := validator.IsUnionPay("3782822463100007") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsChinaUnionPay + +检查字符串是否是有效的中国银联卡号。
+ +函数签名: + +```go +func IsChinaUnionPay(v string) bool +``` + +示例:[运行](https://go.dev/play/p/yafpdxLiymu) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsChinaUnionPay("6250941006528599") + result2 := validator.IsChinaUnionPay("3782822463100007") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` diff --git a/docs/api/packages/xerror.md b/docs/api/packages/xerror.md new file mode 100644 index 00000000..d17df7a5 --- /dev/null +++ b/docs/api/packages/xerror.md @@ -0,0 +1,543 @@ +# Xerror + +xerror 错误处理逻辑封装 + + + +## 源码: + +- [https://github.com/duke-git/lancet/blob/main/xerror/xerror.go](https://github.com/duke-git/lancet/blob/main/xerror/xerror.go) + + + +## 用法: + +```go +import ( + "github.com/duke-git/lancet/v2/xerror" +) +``` + + + +## 目录 + +- [New](#New) +- [Wrap](#Wrap) +- [Unwrap](#Unwrap) +- [XError_Wrap](#XError_Wrap) +- [XError_Unwrap](#XError_Unwrap) +- [XError_With](#XError_With) +- [XError_Is](#XError_Is) +- [XError_Id](#XError_Id) +- [XError_Values](#XError_Values) +- [XError_StackTrace](#XError_StackTrace) +- [XError_Info](#XError_Info) +- [XError_Error](#XError_Error) +- [TryUnwrap](#TryUnwrap) +- [TryCatch](#TryCatch) + + + + +## 文档 + +### New + +创建XError对象实例。
+ +函数签名: + +```go +type XError struct { + id string + message string + stack *stack + cause error + values map[string]any +} + +func New(format string, args ...any) *XError +``` + +示例:[运行](https://go.dev/play/p/w4oWZts7q7f) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err := xerror.New("error") + fmt.Println(err.Error()) + + // Output: + // error +} +``` + +### Wrap + +根据error对象创建XError对象实例,可添加message。
+ +函数签名: + +```go +func Wrap(cause error, message ...any) *XError +``` + +示例:[运行](https://go.dev/play/p/5385qT2dCi4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err := xerror.New("wrong password") + wrapErr := xerror.Wrap(err, "error") + + fmt.Println(wrapErr.Error()) + + // Output: + // error: wrong password +} +``` + +### Unwrap + +从error对象中解构出XError。
+ +函数签名: + +```go +func Unwrap(err error) *XError +``` + +示例:[运行](https://go.dev/play/p/LKMLep723tu) + +```go +package main + +import ( + "fmt" + "github.com/pkg/errors" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err1 := xerror.New("error").With("level", "high") + wrapErr := errors.Wrap(err1, "oops") + + err := xerror.Unwrap(wrapErr) + + values := err.Values() + fmt.Println(values["level"]) + + // Output: + // high +} +``` + +### XError_Wrap + +创建新的XError对象并将消息和id复制到新的对象中。
+ +函数签名: + +```go +func (e *XError) Wrap(cause error) *XError +``` + +示例:[运行](https://go.dev/play/p/RpjJ5u5sc97) + +```go +package main + +import ( + "fmt" + "errors" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err1 := xerror.New("error").With("level", "high") + err2 := err1.Wrap(errors.New("invalid username")) + + fmt.Println(err2.Error()) + + // Output: + // error: invalid username +} +``` + +### XError_Unwrap + +解构XEerror为error对象。适配github.com/pkg/errors。
+ +函数签名: + +```go +func (e *XError) Unwrap() error +``` + +示例:[运行](https://go.dev/play/p/VUXJ8BST4c6) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err1 := xerror.New("error").With("level", "high") + err2 := err1.Wrap(errors.New("invalid username")) + + err := err2.Unwrap() + + fmt.Println(err.Error()) + + // Output: + // invalid username +} +``` + +### XError_With + +添加与XError对象的键和值。
+ +函数签名: + +```go +func (e *XError) With(key string, value any) *XError +``` + +示例:[运行](https://go.dev/play/p/ow8UISXX_Dp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err := xerror.New("error").With("level", "high") + + errLevel := err.Values()["level"] + + fmt.Println(errLevel) + + // Output: + // high +} +``` + +### XError_Id + +设置XError对象的id。
+ +函数签名: + +```go +func (e *XError) Id(id string) *XError +``` + +示例:[运行](https://go.dev/play/p/X6HBlsy58U9) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err1 := xerror.New("error").Id("e001") + err2 := xerror.New("error").Id("e001") + err3 := xerror.New("error").Id("e003") + + equal := err1.Is(err2) + notEqual := err1.Is(err3) + + fmt.Println(equal) + fmt.Println(notEqual) + + // Output: + // true + // false +} +``` + +### XError_Is + +检查目标error是否为XError,两个错误中的error.id是否匹配。
+ +函数签名: + +```go +func (e *XError) Is(target error) bool +``` + +示例:[运行](https://go.dev/play/p/X6HBlsy58U9) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err1 := xerror.New("error").Id("e001") + err2 := xerror.New("error").Id("e001") + err3 := xerror.New("error").Id("e003") + + equal := err1.Is(err2) + notEqual := err1.Is(err3) + + fmt.Println(equal) + fmt.Println(notEqual) + + // Output: + // true + // false +} +``` + +### XError_Values + +返回由With设置的键和值的映射。将合并所有XError键和值。
+ +函数签名: + +```go +func (e *XError) Values() map[string]any +``` + +示例:[运行](https://go.dev/play/p/ow8UISXX_Dp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err := xerror.New("error").With("level", "high") + + errLevel := err.Values()["level"] + + fmt.Println(errLevel) + + // Output: + // high +} +``` + + +### XError_StackTrace + +返回与pkg/error兼容的堆栈信息。
+ +函数签名: + +```go +func (e *XError) StackTrace() StackTrace +``` + +示例:[运行](https://go.dev/play/p/6FAvSQpa7pc) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err := xerror.New("error") + + stacks := err.Stacks() + + fmt.Println(stacks[0].Func) + fmt.Println(stacks[0].Line) + + containFile := strings.Contains(stacks[0].File, "xxx.go") + fmt.Println(containFile) +} +``` + + +### XError_Info + +返回可打印的XError对象信息。
+ +函数签名: + +```go +func (e *XError) Info() *errInfo +``` + +示例:[运行](https://go.dev/play/p/1ZX0ME1F-Jb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + cause := errors.New("error") + err := xerror.Wrap(cause, "invalid username").Id("e001").With("level", "high") + + errInfo := err.Info() + + fmt.Println(errInfo.Id) + fmt.Println(errInfo.Cause) + fmt.Println(errInfo.Values["level"]) + fmt.Println(errInfo.Message) + + // Output: + // e001 + // error + // high + // invalid username +} +``` + + +### XError_Error + +实现标准库的error接口。
+ +函数签名: + +```go +func (e *XError) Error() string +``` + +示例:[运行](https://go.dev/play/p/w4oWZts7q7f) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err := xerror.New("error") + fmt.Println(err.Error()) + + // Output: + // error +} +``` + +### TryUnwrap + +检查error, 如果err为nil则展开,则它返回一个有效值,如果err不是nil则TryUnwrap使用err发生panic。
+ +函数签名: + +```go +func TryUnwrap[T any](val T, err error) T +``` + +示例:[运行](https://go.dev/play/p/acyZVkNZEeW) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + result1 := xerror.TryUnwrap(strconv.Atoi("42")) + fmt.Println(result1) + + _, err := strconv.Atoi("4o2") + defer func() { + v := recover() + result2 := reflect.DeepEqual(err.Error(), v.(*strconv.NumError).Error()) + fmt.Println(result2) + }() + + xerror.TryUnwrap(strconv.Atoi("4o2")) + + // Output: + // 42 + // true +} +``` + +### TryCatch + +简单实现的java风格异常处理(try-catch-finally)。try catch不符合go错误处理风格,谨慎使用。
+ +函数签名: + +```go +func NewTryCatch(ctx context.Context) *TryCatch + +func (tc *TryCatch) Try(tryFunc func(ctx context.Context) error) *TryCatch + +func (tc *TryCatch) Catch(catchFunc func(ctx context.Context, err error)) *TryCatch + +func (tc *TryCatch) Finally(finallyFunc func(ctx context.Context)) *TryCatch + +func (tc *TryCatch) Do() +``` + +示例:[运行](https://go.dev/play/p/D5Mdb0mRj0P) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + calledFinally := false + calledCatch := false + + tc := xerror.NewTryCatch(context.Background()) + + tc.Try(func(ctx context.Context) error { + return errors.New("error in try block") + }).Catch(func(ctx context.Context, err error) { + calledCatch = true + }).Finally(func(ctx context.Context) { + calledFinally = true + }).Do() + + fmt.Println(calledCatch) + fmt.Println(calledFinally) + + // Output: + // true + // true +} +``` \ No newline at end of file diff --git a/docs/convertor.md b/docs/convertor.md deleted file mode 100644 index e11f1c16..00000000 --- a/docs/convertor.md +++ /dev/null @@ -1,349 +0,0 @@ -# Convertor -Package convertor contains some functions for data type convertion. - - - -## Source: - -[https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go) - - - -## Usage: -```go -import ( - "github.com/duke-git/lancet/convertor" -) -``` - - - -## Index -- [ColorHexToRGB](#ColorHexToRGB) -- [ColorRGBToHex](#ColorRGBToHex) -- [ToBool](#ToBool) -- [ToBytes](#ToBytes) -- [ToChar](#ToChar) -- [ToInt](#ToInt) -- [ToJson](#ToJson) -- [ToString](#ToString) -- [StructToMap](#StructToMap) - - - -## Documentation - - - -### ColorHexToRGB -Convert color hex to color rgb.
- -Signature: - -```go -func ColorHexToRGB(colorHex string) (red, green, blue int) -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - colorHex := "#003366" - r, g, b := ColorHexToRGB(colorHex) - fmt.Println(r, g, b) //0,51,102 -} -``` - - - -### ColorRGBToHex - -Convert color rgb to color hex.
- -Signature: - -```go -func ColorRGBToHex(red, green, blue int) string -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - r := 0 - g := 51 - b := 102 - colorHex := ColorRGBToHex(r, g, b) - - fmt.Println(colorHex) //#003366 -} -``` - - - -### ToBool - -Convert string to a boolean value. Use strconv.ParseBool
- -Signature: - -```go -func ToBool(s string) (bool, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - v1, _ := convertor.ToBool("1") - fmt.Println(v1) //true - - v2, _ := convertor.ToBool("true") - fmt.Println(v2) //true - - v3, _ := convertor.ToBool("True") - fmt.Println(v3) //true - - v4, _ := convertor.ToBool("123") - fmt.Println(v4) //false -} -``` - - - -### ToBytes - -Convert interface to byte slice.
- -Signature: - -```go -func ToBytes(data interface{}) ([]byte, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - bytesData, err := convertor.ToBytes("0") - if err != nil { - fmt.Println(err) - } - fmt.Println(bytesData) //[]bytes{3, 4, 0, 0} -} -``` - - - -### ToChar - -Convert string to char slice.
- -Signature: - -```go -func ToChar(s string) []string -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - chars := convertor.ToChar("") - fmt.Println(chars) //[]string{""} - - chars = convertor.ToChar("abc") - fmt.Println(chars) //[]string{"a", "b", "c"} - - chars = convertor.ToChar("1 2#3") - fmt.Println(chars) //[]string{"1", " ", "2", "#", "3"} -} -``` - - - -### ToFloat - -Convert interface to a float64 value. If param is a invalid floatable, will return 0 and error.
- -Signature: - -```go -func ToFloat(value interface{}) (float64, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - v, err := convertor.ToFloat("") - if err != nil { - fmt.Println(err) //strconv.ParseFloat: parsing "": invalid syntax - } - fmt.Println(v) //0 - - v, _ = convertor.ToFloat("-.11") - fmt.Println(v) //-0.11 -} -``` - - - -### ToInt - -Convert interface to a int64 value. If param is a invalid intable, will return 0 and error.
- -Signature: - -```go -func ToInt(value interface{}) (int64, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - v, err := convertor.ToInt("") - if err != nil { - fmt.Println(err) //strconv.ParseInt: parsing "": invalid syntax - } - fmt.Println(v) //0 - - v, _ = convertor.ToFloat(1.12) - fmt.Println(v) //1 -} -``` - - - -### ToJson - -Convert interface to json string. If param can't be converted, will return "" and error.
- -Signature: - -```go -func ToJson(value interface{}) (string, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - var aMap = map[string]int{"a": 1, "b": 2, "c": 3} - jsonStr, _ := convertor.ToJson(aMap) - fmt.Printf("%q", jsonStr) //"{\"a\":1,\"b\":2,\"c\":3}" -} -``` - - - -### ToString - -Convert interface to string.
- -Signature: - -```go -func ToString(value interface{}) string -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - fmt.Printf("%q", convertor.ToString(1)) //"1" - fmt.Printf("%q", convertor.ToString(1.1)) //"1.1" - fmt.Printf("%q", convertor.ToString([]int{1, 2, 3})) //"[1,2,3]" -} -``` - - - -### StructToMap - -Convert struct to map, only convert exported field, struct field tag `json` should be set.
- -Signature: - -```go -func StructToMap(value interface{}) (map[string]interface{}, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - type People struct { - Name string `json:"name"` - age int - } - p := People{ - "test", - 100, - } - pm, _ := convertor.StructToMap(p) - - fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test] -} -``` \ No newline at end of file diff --git a/docs/convertor_zh-CN.md b/docs/convertor_zh-CN.md deleted file mode 100644 index f22877d4..00000000 --- a/docs/convertor_zh-CN.md +++ /dev/null @@ -1,351 +0,0 @@ -# Convertor -convertor转换器包支持一些常见的数据类型转换 - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go) - - - -## 用法: - -```go -import ( - "github.com/duke-git/lancet/convertor" -) -``` - - - -## 目录 - -- [ColorHexToRGB](#ColorHexToRGB) -- [ColorRGBToHex](#ColorRGBToHex) -- [ToBool](#ToBool) -- [ToBytes](#ToBytes) -- [ToChar](#ToChar) -- [ToInt](#ToInt) -- [ToJson](#ToJson) -- [ToString](#ToString) -- [StructToMap](#StructToMap) - - - -## 文档 - - - -### ColorHexToRGB -颜色值十六进制转rgb
- -函数签名: - -```go -func ColorHexToRGB(colorHex string) (red, green, blue int) -``` -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - colorHex := "#003366" - r, g, b := ColorHexToRGB(colorHex) - fmt.Println(r, g, b) //0,51,102 -} -``` - - - -### ColorRGBToHex - -颜色值rgb转十六进制
- -函数签名: - -```go -func ColorRGBToHex(red, green, blue int) string -``` -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - r := 0 - g := 51 - b := 102 - colorHex := ColorRGBToHex(r, g, b) - - fmt.Println(colorHex) //#003366 -} -``` - - - -### ToBool - -字符串转布尔类型,使用strconv.ParseBool
- -函数签名: - -```go -func ToBool(s string) (bool, error) -``` -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - v1, _ := convertor.ToBool("1") - fmt.Println(v1) //true - - v2, _ := convertor.ToBool("true") - fmt.Println(v2) //true - - v3, _ := convertor.ToBool("True") - fmt.Println(v3) //true - - v4, _ := convertor.ToBool("123") - fmt.Println(v4) //false -} -``` - - - -### ToBytes - -interface转字节切片.
- -函数签名: - -```go -func ToBytes(data interface{}) ([]byte, error) -``` -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - bytesData, err := convertor.ToBytes("0") - if err != nil { - fmt.Println(err) - } - fmt.Println(bytesData) //[]bytes{3, 4, 0, 0} -} -``` - - - -### ToChar - -字符串转字符切片
- -函数签名: - -```go -func ToChar(s string) []string -``` -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - chars := convertor.ToChar("") - fmt.Println(chars) //[]string{""} - - chars = convertor.ToChar("abc") - fmt.Println(chars) //[]string{"a", "b", "c"} - - chars = convertor.ToChar("1 2#3") - fmt.Println(chars) //[]string{"1", " ", "2", "#", "3"} -} -``` - - - -### ToFloat - -将interface转成float64类型,如果参数无法转换,会返回0和error
- -函数签名: - -```go -func ToFloat(value interface{}) (float64, error) -``` -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - v, err := convertor.ToFloat("") - if err != nil { - fmt.Println(err) //strconv.ParseFloat: parsing "": invalid syntax - } - fmt.Println(v) //0 - - v, _ = convertor.ToFloat("-.11") - fmt.Println(v) //-0.11 -} -``` - - - -### ToInt - -将interface转成intt64类型,如果参数无法转换,会返回0和error
- -函数签名: - -```go -func ToInt(value interface{}) (int64, error) -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - v, err := convertor.ToInt("") - if err != nil { - fmt.Println(err) //strconv.ParseInt: parsing "": invalid syntax - } - fmt.Println(v) //0 - - v, _ = convertor.ToFloat(1.12) - fmt.Println(v) //1 -} -``` - - - -### ToJson - -将interface转成json字符串,如果参数无法转换,会返回""和error
- -函数签名: - -```go -func ToJson(value interface{}) (string, error) -``` -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - var aMap = map[string]int{"a": 1, "b": 2, "c": 3} - jsonStr, _ := convertor.ToJson(aMap) - fmt.Printf("%q", jsonStr) //"{\"a\":1,\"b\":2,\"c\":3}" -} -``` - - - -### ToString - -将interface转成字符串
- -函数签名: - -```go -func ToString(value interface{}) string -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - fmt.Printf("%q", convertor.ToString(1)) //"1" - fmt.Printf("%q", convertor.ToString(1.1)) //"1.1" - fmt.Printf("%q", convertor.ToString([]int{1, 2, 3})) //"[1,2,3]" -} -``` - - - -### StructToMap - -将struct转成map,只会转换struct中可导出的字段。struct中导出字段需要设置json tag标记
- -函数签名: - -```go -func StructToMap(value interface{}) (map[string]interface{}, error) -``` -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/convertor" -) - -func main() { - type People struct { - Name string `json:"name"` - age int - } - p := People{ - "test", - 100, - } - pm, _ := convertor.StructToMap(p) - - fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test] -} -``` \ No newline at end of file diff --git a/docs/cryptor.md b/docs/cryptor.md deleted file mode 100644 index 5b98e726..00000000 --- a/docs/cryptor.md +++ /dev/null @@ -1,1033 +0,0 @@ -# Cryptor -Package cryptor contains some functions for data encryption and decryption. Support base64, md5, hmac, aes, des, rsa. - - - -## Source: - -- [https://github.com/duke-git/lancet/blob/main/cryptor/aes.go](https://github.com/duke-git/lancet/blob/main/cryptor/aes.go) -- [https://github.com/duke-git/lancet/blob/main/cryptor/des.go](https://github.com/duke-git/lancet/blob/main/cryptor/des.go) -- [https://github.com/duke-git/lancet/blob/main/cryptor/basic.go](https://github.com/duke-git/lancet/blob/main/cryptor/basic.go) -- [https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go) - - - -## Usage: -```go -import ( - "github.com/duke-git/lancet/cryptor" -) -``` - - - -## Index - -- [AesEcbEncrypt](#AesEcbEncrypt) -- [AesEcbDecrypt](#AesEcbDecrypt) -- [AesCbcEncrypt](#AesCbcEncrypt) -- [AesCbcDecrypt](#AesCbcDecrypt) -- [AesCtrCrypt](#AesCtrCrypt) -- [AesCfbEncrypt](#AesCfbEncrypt) -- [AesCfbDecrypt](#AesCfbDecrypt) -- [AesOfbEncrypt](#AesOfbEncrypt) -- [AesOfbDecrypt](#AesOfbDecrypt) -- [Base64StdEncode](#Base64StdEncode) -- [Base64StdDecode](#Base64StdDecode) -- [DesEcbEncrypt](#DesEcbEncrypt) -- [DesEcbDecrypt](#DesEcbDecrypt) -- [DesCbcEncrypt](#DesCbcEncrypt) -- [DesCbcDecrypt](#DesCbcDecrypt) -- [DesCtrCrypt](#DesCtrCrypt) -- [DesCfbEncrypt](#DesCfbEncrypt) -- [DesCfbDecrypt](#DesCfbDecrypt) -- [DesOfbEncrypt](#DesOfbEncrypt) -- [DesOfbDecrypt](#DesOfbDecrypt) -- [HmacMd5](#HmacMd5) -- [HmacSha1](#HmacSha1) -- [HmacSha256](#HmacSha256) -- [HmacSha512](#HmacSha512) - -- [Md5String](#Md5String) -- [Md5File](#Md5File) -- [Sha1](#Sha1) -- [Sha256](#Sha256) -- [Sha512](#Sha512) -- [GenerateRsaKey](#GenerateRsaKey) -- [RsaEncrypt](#RsaEncrypt) -- [RsaDecrypt](#RsaDecrypt) - - - - -## Documentation - - - -### AesEcbEncrypt - -Encrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.
- -Signature: - -```go -func AesEcbEncrypt(data, key []byte) []byte -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key)) - - fmt.Println(string(encrypted)) -} -``` - - - -### AesEcbDecrypt - -Decrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.
- -Signature: - -```go -func AesEcbDecrypt(encrypted, key []byte) []byte -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key)) - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### AesCbcEncrypt - -Encrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.
- -Signature: - -```go -func AesCbcEncrypt(data, key []byte) []byte -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key)) - - fmt.Println(string(encrypted)) -} -``` - - - -### AesCbcDecrypt - -Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.
- -Signature: - -```go -func AesCbcDecrypt(encrypted, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key)) - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### AesCtrCrypt - -Encrypt or decrypt data with key use AES CTR algorithm. Length of `key` param should be 16, 24 or 32.
- -Signature: - -```go -func AesCtrCrypt(data, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key)) - decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key)) - - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### AesCfbEncrypt - -Encrypt data with key use AES CFB algorithm. Length of `key` param should be 16, 24 or 32.
- -Signature: - -```go -func AesCfbEncrypt(data, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key)) - fmt.Println(string(encrypted)) -} -``` - - - -### AesCfbDecrypt - -Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.
- -Signature: - -```go -func AesCfbDecrypt(encrypted, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key)) - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### AesOfbEncrypt - -Enecrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.
- -Signature: - -```go -func AesOfbEncrypt(data, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key)) - fmt.Println(string(encrypted)) -} -``` - - - -### AesOfbDecrypt - -Decrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.
- -Signature: - -```go -func AesOfbDecrypt(encrypted, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.AesOfbDecrypt(encrypted, []byte(key)) - - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### Base64StdEncode - -Encode string with base64 encoding.
- -Signature: - -```go -func Base64StdEncode(s string) string -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - base64Str := cryptor.Base64StdEncode("hello world") - fmt.Println(base64Str) //aGVsbG8gd29ybGQ= -} -``` - - - -### Base64StdDecode - -Decode a base64 encoded string.
- -Signature: - -```go -func Base64StdDecode(s string) string -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - str := cryptor.Base64StdDecode("aGVsbG8gd29ybGQ=") - fmt.Println(str) //hello world -} -``` - - - -### DesEcbEncrypt - -Encrypt data with key use DES ECB algorithm. Length of `key` param should be 8.
- -Signature: - -```go -func DesEcbEncrypt(data, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key)) - - fmt.Println(string(encrypted)) -} -``` - - - -### DesEcbDecrypt - -Decrypt data with key use DES ECB algorithm. Length of `key` param should be 8.
- -Signature: - -```go -func DesEcbDecrypt(encrypted, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesEcbEncrypt([]byte(data), []byt(key) - decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key)) - - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### DesCbcEncrypt - -Encrypt data with key use DES CBC algorithm. Length of `key` param should be 8.
- -Signature: - -```go -func DesCbcEncrypt(data, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key) - - fmt.Println(string(encrypted)) -} -``` - - - -### DesCbcDecrypt - -Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.
- -Signature: - -```go -func DesCbcDecrypt(encrypted, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key) - decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key)) - - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### DesCtrCrypt - -Encrypt or decrypt data with key use DES CTR algorithm. Length of `key` param should be 8.
- -Signature: - -```go -func DesCtrCrypt(data, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key)) - decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key)) - - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### DesCfbEncrypt - -Encrypt data with key use DES CFB algorithm. Length of `key` param should be 8.
- -Signature: - -```go -func DesCfbEncrypt(data, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key) - fmt.Println(string(encrypted)) -} -``` - - - -### DesCfbDecrypt - -Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.
- -Signature: - -```go -func DesCfbDecrypt(encrypted, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key) - decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key)) - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### DesOfbEncrypt - -Enecrypt data with key use DES OFB algorithm. Length of `key` param should be 8.
- -Signature: - -```go -func DesOfbEncrypt(data, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key)) - fmt.Println(string(encrypted)) -} -``` - - - -### DesOfbDecrypt - -Decrypt data with key use DES OFB algorithm. Length of `key` param should be 8.
- -Signature: - -```go -func DesOfbDecrypt(encrypted, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key)) - - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### HmacMd5 - -Get the md5 hmac hash of string.
- -Signature: - -```go -func HmacMd5(data, key string) string -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.HmacMd5("hello world", "12345")) - fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d -} -``` - - - -### HmacSha1 - -Get the sha1 hmac hash of string.
- -Signature: - -```go -func HmacSha1(data, key string) string -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.HmacSha1("hello world", "12345")) - fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd -} -``` - - - -### HmacSha256 - -Get the sha256 hmac hash of string
- -Signature: - -```go -func HmacSha256(data, key string) string -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.HmacSha256("hello world", "12345")) - fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8 -} -``` - - - -### HmacSha512 - -Get the sha512 hmac hash of string.
- -Signature: - -```go -func HmacSha512(data, key string) string -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.HmacSha512("hello world", "12345")) - fmt.Println(s) - //5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175 -} -``` - - - -### Md5String - -Get the md5 value of string.
- -Signature: - -```go -func Md5String(s string) string -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.Md5String("hello")) - fmt.Println(s) //5d41402abc4b2a76b9719d911017c592 -} -``` - - - -### Md5File - -Get the md5 value of file.
- -Signature: - -```go -func Md5File(filepath string) (string, error) -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.Md5File("./main.go")) - fmt.Println(s) -} -``` - - - -### Sha1 - -Get the sha1 value of string.
- -Signature: - -```go -func Sha1(data string) string -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.Sha1("hello world")) - fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed -} -``` - - - -### Sha256 - -Get the sha256 value of string.
- -Signature: - -```go -func Sha256(data string) string -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.Sha256("hello world")) - fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 -} -``` - - - -### Sha512 - -Get the sha512 value of string.
- -Signature: - -```go -func Sha512(data string) string -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.Sha512("hello world")) - fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f -} -``` - - - -### GenerateRsaKey - -Create the rsa public and private key file in current directory.
- -Signature: - -```go -func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") - if err != nil { - fmt.Println(err) - } -} -``` - - - -### RsaEncrypt - -Encrypt data with public key file useing ras algorithm.
- -Signature: - -```go -func RsaEncrypt(data []byte, pubKeyFileName string) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") - if err != nil { - fmt.Println(err) - } - - data := []byte("hello world") - encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem") - decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem") - - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### RsaDecrypt - -Decrypt data with private key file useing ras algorithm.
- -Signature: - -```go -func RsaDecrypt(data []byte, privateKeyFileName string) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") - if err != nil { - fmt.Println(err) - } - - data := []byte("hello world") - encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem") - decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem") - - fmt.Println(string(decrypted)) //hello world -} -``` - - - diff --git a/docs/cryptor_zh-CN.md b/docs/cryptor_zh-CN.md deleted file mode 100644 index 6847bcb4..00000000 --- a/docs/cryptor_zh-CN.md +++ /dev/null @@ -1,1028 +0,0 @@ -# Cryptor -cryptor加密包支持数据加密和解密,获取md5,hash值。支持base64, md5, hmac, aes, des, rsa。 - - - -## 源码: - -- [https://github.com/duke-git/lancet/blob/main/cryptor/aes.go](https://github.com/duke-git/lancet/blob/main/cryptor/aes.go) -- [https://github.com/duke-git/lancet/blob/main/cryptor/des.go](https://github.com/duke-git/lancet/blob/main/cryptor/des.go) -- [https://github.com/duke-git/lancet/blob/main/cryptor/basic.go](https://github.com/duke-git/lancet/blob/main/cryptor/basic.go) -- [https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go) - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/cryptor" -) -``` - - - -## 目录 -- [AesEcbEncrypt](#AesEcbEncrypt) -- [AesEcbDecrypt](#AesEcbDecrypt) -- [AesCbcEncrypt](#AesCbcEncrypt) -- [AesCbcDecrypt](#AesCbcDecrypt) -- [AesCtrCrypt](#AesCtrCrypt) -- [AesCfbEncrypt](#AesCfbEncrypt) -- [AesCfbDecrypt](#AesCfbDecrypt) -- [AesOfbEncrypt](#AesOfbEncrypt) -- [AesOfbDecrypt](#AesOfbDecrypt) -- [Base64StdEncode](#Base64StdEncode) -- [Base64StdDecode](#Base64StdDecode) - -- [DesEcbEncrypt](#DesEcbEncrypt) -- [DesEcbDecrypt](#DesEcbDecrypt) -- [DesCbcEncrypt](#DesCbcEncrypt) -- [DesCbcDecrypt](#DesCbcDecrypt) -- [DesCtrCrypt](#DesCtrCrypt) -- [DesCfbEncrypt](#DesCfbEncrypt) -- [DesCfbDecrypt](#DesCfbDecrypt) -- [DesOfbEncrypt](#DesOfbEncrypt) -- [DesOfbDecrypt](#DesOfbDecrypt) - -- [HmacMd5](#HmacMd5) -- [HmacSha1](#HmacSha1) -- [HmacSha256](#HmacSha256) -- [HmacSha512](#HmacSha512) -- [Md5String](#Md5String) -- [Md5File](#Md5File) -- [Sha1](#Sha1) -- [Sha256](#Sha256) -- [Sha512](#Sha512) -- [GenerateRsaKey](#GenerateRsaKey) -- [RsaEncrypt](#RsaEncrypt) -- [RsaDecrypt](#RsaDecrypt) - - - - -## 文档 - - - -### AesEcbEncrypt - -使用AES ECB算法模式加密数据. 参数`key`的长度是16, 24 or 32。
- -函数签名: - -```go -func AesEcbEncrypt(data, key []byte) []byte -``` -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key)) - - fmt.Println(string(encrypted)) -} -``` - - - -### AesEcbDecrypt - -使用AES ECB算法模式解密数据. 参数`key`的长度是16, 24 or 32。 - -函数签名: - -```go -func AesEcbDecrypt(encrypted, key []byte) []byte -``` -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key)) - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### AesCbcEncrypt - -
使用AES CBC算法模式加密数据. 参数`key`的长度是16, 24 or 32。
- -函数签名: - -```go -func AesCbcEncrypt(data, key []byte) []byte -``` -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key)) - - fmt.Println(string(encrypted)) -} -``` - - - -### AesCbcDecrypt - -使用AES CBC算法模式解密数据. 参数`key`的长度是16, 24 or 32。
- -函数签名: - -```go -func AesCbcDecrypt(encrypted, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key)) - - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### AesCtrCrypt - -使用AES CTR算法模式加密/解密数据. 参数`key`的长度是16, 24 or 32。
- -函数签名: - -```go -func AesCtrCrypt(data, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key)) - decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key)) - - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### AesCfbEncrypt - -使用AES CFB算法模式加密数据. 参数`key`的长度是16, 24 or 32。
- -函数签名: - -```go -func AesCfbEncrypt(data, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key)) - fmt.Println(string(encrypted)) -} -``` - - - -### AesCfbDecrypt - -使用AES CFB算法模式解密数据. 参数`key`的长度是16, 24 or 32。
- -函数签名: - -```go -func AesCfbDecrypt(encrypted, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key)) - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### AesOfbEncrypt - -使用AES OFB算法模式加密数据. 参数`key`的长度是16, 24 or 32
- -函数签名: - -```go -func AesOfbEncrypt(data, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key)) - fmt.Println(string(encrypted)) -} -``` - - - -### AesOfbDecrypt - -使用AES OFB算法模式解密数据. 参数`key`的长度是16, 24 or 32
- -函数签名: - -```go -func AesOfbDecrypt(encrypted, key []byte) []byte -``` - -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefghijklmnop" - encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.AesOfbDecrypt(encrypted, []byte(key)) - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### Base64StdEncode - -将字符串base64编码
- -函数签名: - -```go -func Base64StdEncode(s string) string -``` -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - base64Str := cryptor.Base64StdEncode("hello world") - fmt.Println(base64Str) //aGVsbG8gd29ybGQ= -} -``` - - - -### Base64StdDecode - -解码base64字符串
- -函数签名: - -```go -func Base64StdDecode(s string) string -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - str := cryptor.Base64StdDecode("aGVsbG8gd29ybGQ=") - fmt.Println(str) //hello world -} -``` - - - -### DesEcbEncrypt - -使用DES ECB算法模式加密数据. 参数`key`的长度是8
- -函数签名: - -```go -func DesEcbEncrypt(data, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key)) - - fmt.Println(string(encrypted)) -} -``` - - - -### DesEcbDecrypt - -使用DES ECB算法模式解密数据. 参数`key`的长度是8
- -函数签名: - -```go -func DesEcbDecrypt(encrypted, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key)) - - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### DesCbcEncrypt - -使用DES CBC算法模式加密数据. 参数`key`的长度是8
- -函数签名: - -```go -func DesCbcEncrypt(data, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key)) - - fmt.Println(string(encrypted)) -} -``` - - - -### DesCbcDecrypt - -使用DES CBC算法模式解密数据. 参数`key`的长度是8
- -函数签名: - -```go -func DesCbcDecrypt(encrypted, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key)) - - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### DesCtrCrypt - -使用DES CTR算法模式加密/解密数据. 参数`key`的长度是8
- -函数签名: - -```go -func DesCtrCrypt(data, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key)) - decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key)) - - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### DesCfbEncrypt - -使用DES CFB算法模式加密数据. 参数`key`的长度是8
- -函数签名: - -```go -func DesCfbEncrypt(data, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key)) - fmt.Println(string(encrypted)) -} -``` - - - -### DesCfbDecrypt - -使用DES CFB算法模式解密数据. 参数`key`的长度是8
- -函数签名: - -```go -func DesCfbDecrypt(encrypted, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key)) - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### DesOfbEncrypt - -使用DES OFB算法模式加密数据. 参数`key`的长度是8
- -函数签名: - -```go -func DesOfbEncrypt(data, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key)) - fmt.Println(string(encrypted)) -} -``` - - - -### DesOfbDecrypt - -使用DES OFB算法模式解密数据. 参数`key`的长度是8
- -函数签名: - -```go -func DesOfbDecrypt(encrypted, key []byte) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - data := "hello world" - key := "abcdefgh" - encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key)) - decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key)) - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### HmacMd5 - -获取字符串md5 hmac值
- -函数签名: - -```go -func HmacMd5(data, key string) string -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.HmacMd5("hello world", "12345")) - fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d -} -``` - - - -### HmacSha1 - -获取字符串sha1 hmac值
- -函数签名: - -```go -func HmacSha1(data, key string) string -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.HmacSha1("hello world", "12345")) - fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd -} -``` - - - -### HmacSha256 - -获取字符串sha256 hmac值
- -函数签名: - -```go -func HmacSha256(data, key string) string -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.HmacSha256("hello world", "12345")) - fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8 -} -``` - - - -### HmacSha512 - -获取字符串sha512 hmac值
- -函数签名: - -```go -func HmacSha512(data, key string) string -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.HmacSha512("hello world", "12345")) - fmt.Println(s) - //5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175 -} -``` - - - -### Md5String - -获取字符串md5值
- -函数签名: - -```go -func Md5String(s string) string -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.Md5String("hello")) - fmt.Println(s) //5d41402abc4b2a76b9719d911017c592 -} -``` - - - -### Md5File - -获取文件md5值.
- -函数签名: - -```go -func Md5File(filepath string) (string, error) -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.Md5File("./main.go")) - fmt.Println(s) -} -``` - - - -### Sha1 - -获取字符串sha1值
- -函数签名: - -```go -func Sha1(data string) string -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.Sha1("hello world")) - fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed -} -``` - - - -### Sha256 - -获取字符串sha256值
- -函数签名: - -```go -func Sha256(data string) string -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.Sha256("hello world")) - fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 -} -``` - - - -### Sha512 - -获取字符串sha512值
- -函数签名: - -```go -func Sha512(data string) string -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - s := cryptor.Sha512("hello world")) - fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f -} -``` - - - -### GenerateRsaKey - -在当前目录下创建rsa私钥文件和公钥文件
- -函数签名: - -```go -func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") - if err != nil { - fmt.Println(err) - } -} -``` - - - -### RsaEncrypt - -用公钥文件ras加密数据
- -函数签名: - -```go -func RsaEncrypt(data []byte, pubKeyFileName string) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") - if err != nil { - fmt.Println(err) - } - data := []byte("hello world") - encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem") - decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem") - fmt.Println(string(decrypted)) //hello world -} -``` - - - -### RsaDecrypt - -用私钥文件rsa解密数据
- -函数签名: - -```go -func RsaDecrypt(data []byte, privateKeyFileName string) []byte -``` - -列子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/cryptor" -) - -func main() { - err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") - if err != nil { - fmt.Println(err) - } - data := []byte("hello world") - encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem") - decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem") - fmt.Println(string(decrypted)) //hello world -} -``` - - - diff --git a/docs/datetime.md b/docs/datetime.md deleted file mode 100644 index 4ec076ff..00000000 --- a/docs/datetime.md +++ /dev/null @@ -1,669 +0,0 @@ -# Datetime -Package datetime supports date and time format and compare. - - - -## Source: - -[https://github.com/duke-git/lancet/blob/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.go) - - - -## Usage: -```go -import ( - "github.com/duke-git/lancet/datetime" -) -``` - - - -## Index -- [AddDay](#AddDay) -- [AddHour](#AddHour) -- [AddMinute](#AddMinute) -- [BeginOfMinute](#BeginOfMinute) -- [BeginOfHour](#BeginOfHour) -- [BeginOfDay](#BeginOfDay) -- [BeginOfWeek](#BeginOfWeek) -- [BeginOfMonth](#BeginOfMonth) -- [BeginOfYear](#BeginOfYear) - -- [EndOfMinute](#EndOfMinute) -- [EndOfHour](#EndOfHour) -- [EndOfDay](#EndOfDay) -- [EndOfWeek](#EndOfWeek) -- [EndOfMonth](#EndOfMonth) -- [EndOfYear](#EndOfYear) -- [GetNowDate](#GetNowDate) -- [GetNowTime](#GetNowTime) -- [GetNowDateTime](#GetNowDateTime) -- [GetZeroHourTimestamp](#GetZeroHourTimestamp) -- [GetNightTimestamp](#GetNightTimestamp) -- [FormatTimeToStr](#FormatTimeToStr) - -- [FormatStrToTime](#FormatStrToTime) - - - -## Documentation - -## Note: -1. 'format' string param in func FormatTimeToStr and FormatStrToTime function should be one of flows: -- yyyy-mm-dd hh:mm:ss -- yyyy-mm-dd hh:mm -- yyyy-mm-dd hh -- yyyy-mm-dd -- yyyy-mm -- mm-dd -- dd-mm-yy hh:mm:ss -- yyyy/mm/dd hh:mm:ss -- yyyy/mm/dd hh:mm -- yyyy-mm-dd hh -- yyyy/mm/dd -- yyyy/mm -- mm/dd -- dd/mm/yy hh:mm:ss -- yyyy -- mm -- hh:mm:ss -- mm:ss - - -### AddDay -Add or sub days to time.
- -Signature: - -```go -func AddDay(t time.Time, day int64) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - after2Days := datetime.AddDay(now, 2) - before2Days := datetime.AddDay(now, -2) - - fmt.Println(after2Days, before2Days) -} -``` - - -### AddHour -Add or sub hours to time.
- -Signature: - -```go -func AddHour(t time.Time, hour int64) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - after2Hours := datetime.AddHour(now, 2) - before2Hours := datetime.AddHour(now, -2) - - fmt.Println(after2Hours, after2Hours) -} -``` - -### AddMinute -Add or sub minutes to time.
- -Signature: - -```go -func AddMinute(t time.Time, minute int64) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - after2Minute := datetime.AddMinute(now, 2) - before2Minute := datetime.AddMinute(now, -2) - - fmt.Println(after2Minute, before2Minute) -} -``` - -### BeginOfMinute -Return beginning minute time of day.
- -Signature: - -```go -func BeginOfMinute(t time.Time) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.BeginOfMinute(td) - fmt.Println(bm) //2022-02-15 15:48:00 +0800 CST -} -``` - -### BeginOfHour -Return zero time of day.
- -Signature: - -```go -func BeginOfHour(t time.Time) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.BeginOfHour(td) - fmt.Println(bm) //2022-02-15 15:00:00 +0800 CST -} -``` - -### BeginOfDay -Return begin time of day.
- -Signature: - -```go -func BeginOfDay(t time.Time) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.BeginOfDay(td) - fmt.Println(bm) //2022-02-15 00:00:00 +0800 CST -} -``` - - - -### BeginOfWeek -Return beginning time of week, week begin from Sunday.
- -Signature: - -```go -func BeginOfWeek(t time.Time) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.BeginOfWeek(td) - fmt.Println(bm) //2022-02-13 00:00:00 +0800 CST -} -``` - - - -### BeginOfMonth -Return beginning time of month
- -Signature: - -```go -func BeginOfMonth(t time.Time) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.BeginOfMonth(td) - fmt.Println(bm) //2022-02-01 00:00:00 +0800 CST -} -``` - - -### BeginOfYear -Return beginning time of year.
- -Signature: - -```go -func BeginOfYear(t time.Time) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.BeginOfYear(td) - fmt.Println(bm) //2022-01-01 00:00:00 +0800 CST -} -``` - - - -### EndOfMinute -Return end time minute of day.
- -Signature: - -```go -func EndOfMinute(t time.Time) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.EndOfMinute(td) - fmt.Println(bm) //2022-02-15 15:48:59.999999999 +0800 CST -} -``` - -### EndOfHour -Return end time hour of day.
- -Signature: - -```go -func EndOfHour(t time.Time) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.EndOfHour(td) - fmt.Println(bm) //2022-02-15 15:59:59.999999999 +0800 CST -} -``` - -### EndOfDay -Return end time hour of day.
- -Signature: - -```go -func EndOfDay(t time.Time) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.EndOfDay(td) - fmt.Println(bm) //2022-02-15 23:59:59.999999999 +0800 CST -} -``` - - - -### EndOfWeek -Return end time of week, week end with Saturday.
- -Signature: - -```go -func EndOfWeek(t time.Time) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.EndOfWeek(td) - fmt.Println(bm) //2022-02-19 23:59:59.999999999 +0800 CST -} -``` - - - -### EndOfMonth -Return end time of month
- -Signature: - -```go -func EndOfMonth(t time.Time) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.EndOfMonth(td) - fmt.Println(bm) //2022-02-28 23:59:59.999999999 +0800 CST -} -``` - - -### EndOfYear -Return beginning time of year.
- -Signature: - -```go -func EndOfYear(t time.Time) time.Time -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.EndOfYear(td) - fmt.Println(bm) //2022-12-31 23:59:59.999999999 +0800 CST -} -``` - - -### GetNowDate -Get current date string, format is yyyy-mm-dd.
- -Signature: - -```go -func GetNowDate() string -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - currentDate := datetime.GetNowDate() - fmt.Println(currentDate) // 2022-01-28 -} -``` - - -### GetNowTime -Get current time string, format is hh:mm:ss.
- -Signature: - -```go -func GetNowTime() string -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - currentTime := datetime.GetNowTime() - fmt.Println(currentDate) // 15:57:33 -} -``` - - -### GetNowDateTime -Get current date time string, format is yyyy-mm-dd hh:mm:ss.
- -Signature: - -```go -func GetNowDateTime() string -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - current := datetime.GetNowDateTime() - fmt.Println(current) // 2022-01-28 15:59:33 -} -``` - - -### GetZeroHourTimestamp -Return timestamp of zero hour (timestamp of 00:00).
- -Signature: - -```go -func GetZeroHourTimestamp() int64 -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - zeroTime := datetime.GetZeroHourTimestamp() - fmt.Println(zeroTime) // 1643299200 -} -``` - - -### GetNightTimestamp -Return timestamp of zero hour (timestamp of 23:59).
- -Signature: - -```go -func GetNightTimestamp() int64 -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - nightTime := datetime.GetNightTimestamp() - fmt.Println(nightTime) // 1643385599 -} -``` - -### FormatTimeToStr -Format time to string, `format` param specification see note 1.
- -Signature: - -```go -func FormatTimeToStr(t time.Time, format string) string -``` -Example: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - timeStr := datetime.FormatTimeToStr(now, "yyyy/mm/dd hh:mm:ss") - fmt.Println(timeStr) //2022/01/28 16:07:44 -} -``` - - -### FormatStrToTime -Format string to time, `format` param specification see note 1.
- -Signature: - -```go -func FormatStrToTime(str, format string) (time.Time, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/datetime" -) - -func main() { - time := datetime.FormatStrToTime("2006-01-02 15:04:05", "yyyy/mm/dd hh:mm:ss") - fmt.Println(time) -} -``` - - - diff --git a/docs/datetime_zh-CN.md b/docs/datetime_zh-CN.md deleted file mode 100644 index db6c8899..00000000 --- a/docs/datetime_zh-CN.md +++ /dev/null @@ -1,668 +0,0 @@ -# Datetime -datetime日期时间处理包,格式化日期,比较日期。 - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.go) - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/datetime" -) -``` - - - -## 目录 -- [AddDay](#AddDay) -- [AddHour](#AddHour) -- [AddMinute](#AddMinute) -- [BeginOfMinute](#BeginOfMinute) -- [BeginOfHour](#BeginOfHour) -- [BeginOfDay](#BeginOfDay) -- [BeginOfWeek](#BeginOfWeek) -- [BeginOfMonth](#BeginOfMonth) -- [BeginOfYear](#BeginOfYear) - -- [EndOfMinute](#EndOfMinute) -- [EndOfHour](#EndOfHour) -- [EndOfDay](#EndOfDay) -- [EndOfWeek](#EndOfWeek) -- [EndOfMonth](#EndOfMonth) -- [EndOfYear](#EndOfYear) -- [GetNowDate](#GetNowDate) -- [GetNowTime](#GetNowTime) -- [GetNowDateTime](#GetNowDateTime) -- [GetZeroHourTimestamp](#GetZeroHourTimestamp) -- [GetNightTimestamp](#GetNightTimestamp) -- [FormatTimeToStr](#FormatTimeToStr) -- [FormatStrToTime](#FormatStrToTime) - - - -## 文档 - -## 注: -1. 方法FormatTimeToStr和FormatStrToTime中的format参数值需要传以下类型之一: -- yyyy-mm-dd hh:mm:ss -- yyyy-mm-dd hh:mm -- yyyy-mm-dd hh -- yyyy-mm-dd -- yyyy-mm -- mm-dd -- dd-mm-yy hh:mm:ss -- yyyy/mm/dd hh:mm:ss -- yyyy/mm/dd hh:mm -- yyyy-mm-dd hh -- yyyy/mm/dd -- yyyy/mm -- mm/dd -- dd/mm/yy hh:mm:ss -- yyyy -- mm -- hh:mm:ss -- mm:ss - - -### AddDay -将日期加/减天数
- -函数签名: - -```go -func AddDay(t time.Time, day int64) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - after2Days := datetime.AddDay(now, 2) - before2Days := datetime.AddDay(now, -2) - - fmt.Println(after2Days, before2Days) -} -``` - - -### AddHour -将日期加/减小时数
- -函数签名: - -```go -func AddHour(t time.Time, hour int64) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - after2Hours := datetime.AddHour(now, 2) - before2Hours := datetime.AddHour(now, -2) - - fmt.Println(after2Hours, after2Hours) -} -``` - -### AddMinute -将日期加/减分钟数
- -函数签名: - -```go -func AddMinute(t time.Time, minute int64) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - after2Minute := datetime.AddMinute(now, 2) - before2Minute := datetime.AddMinute(now, -2) - - fmt.Println(after2Minute, before2Minute) -} -``` - -### BeginOfMinute -返回指定时间的分钟开始时间
- -函数签名: - -```go -func BeginOfMinute(t time.Time) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.BeginOfMinute(td) - fmt.Println(bm) //2022-02-15 15:48:00 +0800 CST -} -``` - -### BeginOfHour -返回指定时间的小时开始时间
- -函数签名: - -```go -func BeginOfHour(t time.Time) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.BeginOfHour(td) - fmt.Println(bm) //2022-02-15 15:00:00 +0800 CST -} -``` - -### BeginOfDay -返回指定时间的当天开始时间
- -函数签名: - -```go -func BeginOfDay(t time.Time) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.BeginOfDay(td) - fmt.Println(bm) //2022-02-15 00:00:00 +0800 CST -} -``` - - - -### BeginOfWeek -返回指定时间的星期开始时间
- -函数签名: - -```go -func BeginOfWeek(t time.Time) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.BeginOfWeek(td) - fmt.Println(bm) //2022-02-13 00:00:00 +0800 CST -} -``` - - - -### BeginOfMonth -返回指定时间的当月开始时间
- -函数签名: - -```go -func BeginOfMonth(t time.Time) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.BeginOfMonth(td) - fmt.Println(bm) //2022-02-01 00:00:00 +0800 CST -} -``` - - -### BeginOfYear -返回指定时间的当年开始时间
- -函数签名: - -```go -func BeginOfYear(t time.Time) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.BeginOfYear(td) - fmt.Println(bm) //2022-01-01 00:00:00 +0800 CST -} -``` - - - -### EndOfMinute -返回指定时间的分钟结束时间
- -函数签名: - -```go -func EndOfMinute(t time.Time) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.EndOfMinute(td) - fmt.Println(bm) //2022-02-15 15:48:59.999999999 +0800 CST -} -``` - -### EndOfHour -返回指定时间的小时结束时间
- -函数签名: - -```go -func EndOfHour(t time.Time) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.EndOfHour(td) - fmt.Println(bm) //2022-02-15 15:59:59.999999999 +0800 CST -} -``` - -### EndOfDay -返回指定时间的当天结束时间.
- -函数签名: - -```go -func EndOfDay(t time.Time) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.EndOfDay(td) - fmt.Println(bm) //2022-02-15 23:59:59.999999999 +0800 CST -} -``` - - - -### EndOfWeek -返回指定时间的星期结束时间
- -函数签名: - -```go -func EndOfWeek(t time.Time) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.EndOfWeek(td) - fmt.Println(bm) //2022-02-19 23:59:59.999999999 +0800 CST -} -``` - - - -### EndOfMonth -返回指定时间的月份结束时间
- -函数签名: - -```go -func EndOfMonth(t time.Time) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.EndOfMonth(td) - fmt.Println(bm) //2022-02-28 23:59:59.999999999 +0800 CST -} -``` - - -### EndOfYear -返回指定时间的年份结束时间
- -函数签名: - -```go -func EndOfYear(t time.Time) time.Time -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local) - bm := datetime.EndOfYear(td) - fmt.Println(bm) //2022-12-31 23:59:59.999999999 +0800 CST -} -``` - - -### GetNowDate -获取当天日期,返回格式:yyyy-mm-dd
- -函数签名: - -```go -func GetNowDate() string -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - currentDate := datetime.GetNowDate() - fmt.Println(currentDate) // 2022-01-28 -} -``` - - -### GetNowTime -获取当时时间,返回格式:hh:mm:ss
- -函数签名: - -```go -func GetNowTime() string -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - currentTime := datetime.GetNowTime() - fmt.Println(currentDate) // 15:57:33 -} -``` - - -### GetNowDateTime -获取当时日期和时间,返回格式:yyyy-mm-dd hh:mm:ss.
- -函数签名: - -```go -func GetNowDateTime() string -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - current := datetime.GetNowDateTime() - fmt.Println(current) // 2022-01-28 15:59:33 -} -``` - - -### GetZeroHourTimestamp -获取零时时间戳(timestamp of 00:00).
- -函数签名: - -```go -func GetZeroHourTimestamp() int64 -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - zeroTime := datetime.GetZeroHourTimestamp() - fmt.Println(zeroTime) // 1643299200 -} -``` - - -### GetNightTimestamp -获取午夜时间戳(timestamp of 23:59).
- -函数签名: - -```go -func GetNightTimestamp() int64 -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - nightTime := datetime.GetNightTimestamp() - fmt.Println(nightTime) // 1643385599 -} -``` - -### FormatTimeToStr -将日期格式化成字符串,`format` 参数格式参考注1
- -函数签名: - -```go -func FormatTimeToStr(t time.Time, format string) string -``` -例子: - -```go -package main - -import ( - "fmt" - "time" - "github.com/duke-git/lancet/datetime" -) - -func main() { - now := time.Now() - timeStr := datetime.FormatTimeToStr(now, "yyyy/mm/dd hh:mm:ss") - fmt.Println(timeStr) //2022/01/28 16:07:44 -} -``` - - -### FormatStrToTime -将字符串格式化成时间,`format` 参数格式参考注1
- -函数签名: - -```go -func FormatStrToTime(str, format string) (time.Time, error) -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/datetime" -) - -func main() { - time := datetime.FormatStrToTime("2006-01-02 15:04:05", "yyyy/mm/dd hh:mm:ss") - fmt.Println(time) -} -``` - - - diff --git a/docs/en/api/overview.md b/docs/en/api/overview.md new file mode 100644 index 00000000..2d665732 --- /dev/null +++ b/docs/en/api/overview.md @@ -0,0 +1,69 @@ +--- +outline: deep +--- + +# API Overview + +Lancet (Lancet) is a powerful, comprehensive, efficient and reusable go language tool function library. Contains 25 packages, more than 600 utility functions. Functions cover string processing, slice processing, network, concurrency, encryption and decryption, file processing, time/date, stream processing, iterators, and more. + + + +Lancet function module
+Sort slice with bubble sort algorithm. Param comparator should implements constraints.Comparator.
+ +Signature: + +```go +func BubbleSort[T any](slice []T, comparator constraints.Comparator) +``` + +Example: [Run](https://go.dev/play/p/GNdv7Jg2Taj) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + algorithm.BubbleSort(numbers, comparator) + + fmt.Println(numbers) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### InsertionSort + +Sort slice with insertion sort algorithm. Param comparator should implements constraints.Comparator.
+ +Signature: + +```go +func InsertionSort[T any](slice []T, comparator constraints.Comparator) +``` + +Example: [Run](https://go.dev/play/p/G5LJiWgJJW6) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type people struct { + Name string + Age int +} + +// PeopleAageComparator sort people slice by age field +type peopleAgeComparator struct{} + +// Compare implements github.com/duke-git/lancet/constraints/constraints.go/Comparator +func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int { + p1, _ := v1.(people) + p2, _ := v2.(people) + + //ascending order + if p1.Age < p2.Age { + return -1 + } else if p1.Age > p2.Age { + return 1 + } + + return 0 +} + +func main() { + peoples := []people{ + {Name: "a", Age: 20}, + {Name: "b", Age: 10}, + {Name: "c", Age: 17}, + {Name: "d", Age: 8}, + {Name: "e", Age: 28}, + } + + comparator := &peopleAgeComparator{} + + algorithm.InsertionSort(peoples, comparator) + + fmt.Println(peoples) + + // Output: + // [{d 8} {b 10} {c 17} {a 20} {e 28}] +} +``` + +### SelectionSort + +Sort slice with selection sort algorithm. Param comparator should implements constraints.Comparator.
+ +Signature: + +```go +func SelectionSort[T any](slice []T, comparator constraints.Comparator) +``` + +Example: [Run](https://go.dev/play/p/oXovbkekayS) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + algorithm.SelectionSort(numbers, comparator) + + fmt.Println(numbers) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### ShellSort + +Sort slice with shell sort algorithm. Param comparator should implements constraints.Comparator.
+ +Signature: + +```go +func ShellSort[T any](slice []T, comparator constraints.Comparator) +``` + +Example: [Run](https://go.dev/play/p/3ibkszpJEu3) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + algorithm.ShellSort(numbers, comparator) + + fmt.Println(numbers) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### QuickSort + +Sort slice with quick sort algorithm. Param comparator should implements constraints.Comparator.
+ +Signature: + +```go +func QuickSort[T any](slice []T comparator constraints.Comparator) +``` + +Example:[Run](https://go.dev/play/p/7Y7c1Elk3ax) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + algorithm.QuickSort(numbers, comparator) + + fmt.Println(numbers) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### HeapSort + +Sort slice with heap sort algorithm. Param comparator should implements constraints.Comparator.
+ +Signature: + +```go +func HeapSort[T any](slice []T, comparator constraints.Comparator) +``` + +Example: [Run](https://go.dev/play/p/u6Iwa1VZS_f) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + algorithm.HeapSort(numbers, comparator) + + fmt.Println(numbers) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### MergeSort + +Sort slice with merge sort algorithm. Param comparator should implements constraints.Comparator.
+ +Signature: + +```go +func MergeSort[T any](slice []T, comparator constraints.Comparator) +``` + +Example: [Run](https://go.dev/play/p/ydinn9YzUJn) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + algorithm.MergeSort(numbers, comparator) + + fmt.Println(numbers) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### CountSort + +Sort slice with count sort algorithm. Param comparator should implements constraints.Comparator.
+ +Signature: + +```go +func CountSort[T any](slice []T, comparator constraints.Comparator) []T +``` + +Example: [Run](https://go.dev/play/p/tB-Umgm0DrP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{2, 1, 5, 3, 6, 4} + comparator := &intComparator{} + + sortedNums := algorithm.CountSort(numbers, comparator) + + fmt.Println(sortedNums) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### BinarySearch + +BinarySearch search for target within a sorted slice, recursive call itself. If a target is found, the index of the target is returned. Else the function return -1.
+ +Signature: + +```go +func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator constraints.Comparator) int +``` + +Example: [Run](https://go.dev/play/p/t6MeGiUSN47) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{1, 2, 3, 4, 5, 6, 7, 8} + comparator := &intComparator{} + + result1 := algorithm.BinarySearch(numbers, 5, 0, len(numbers)-1, comparator) + result2 := algorithm.BinarySearch(numbers, 9, 0, len(numbers)-1, comparator) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 4 + // -1 +} +``` + +### BinaryIterativeSearch + +BinaryIterativeSearch search for target within a sorted slice, recursive call itself. If a target is found, the index of the target is returned. Else the function return -1.
+ +Signature: + +```go +func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator constraints.Comparator) int +``` + +Example: [Run](https://go.dev/play/p/Anozfr8ZLH3) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1 any, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + numbers := []int{1, 2, 3, 4, 5, 6, 7, 8} + comparator := &intComparator{} + + result1 := algorithm.BinaryIterativeSearch(numbers, 5, 0, len(numbers)-1, comparator) + result2 := algorithm.BinaryIterativeSearch(numbers, 9, 0, len(numbers)-1, comparator) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 4 + // -1 +} +``` + +### LinearSearch + +return the index of target in slice base on equal function.If a target is found, the index of the target is returned. Else the function return -1.
+ +Signature: + +```go +func LinearSearch[T any](slice []T, target T, equal func(a, b T) bool) int +``` + +Example: [Run](https://go.dev/play/p/IsS7rgn5s3x) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +func main() { + numbers := []int{3, 4, 5, 3, 2, 1} + + equalFunc := func(a, b int) bool { + return a == b + } + + result1 := algorithm.LinearSearch(numbers, 3, equalFunc) + result2 := algorithm.LinearSearch(numbers, 6, equalFunc) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // -1 +} +``` + +### LRUCache + +LRUCache implements mem cache with lru.
+ +Signature: + +```go +func NewLRUCache[K comparable, V any](capacity int) *LRUCache[K, V] +func (l *LRUCache[K, V]) Get(key K) (V, bool) +func (l *LRUCache[K, V]) Put(key K, value V) +func (l *LRUCache[K, V]) Delete(key K) bool +func (l *LRUCache[K, V]) Len() int +``` + +Example: [Run](https://go.dev/play/p/IsS7rgn5s3x) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/algorithm" +) + +func main() { + cache := algorithm.NewLRUCache[int, int](2) + + cache.Put(1, 1) + cache.Put(2, 2) + + result1, ok1 := cache.Get(1) + result2, ok2 := cache.Get(2) + result3, ok3 := cache.Get(3) + + fmt.Println(result1, ok1) + fmt.Println(result2, ok2) + fmt.Println(result3, ok3) + + fmt.Println(cache.Len()) + + ok := cache.Delete(2) + fmt.Println(ok) + + + // Output: + // 1 true + // 2 true + // 0 false + // 2 + // true +} +``` diff --git a/docs/en/api/packages/compare.md b/docs/en/api/packages/compare.md new file mode 100644 index 00000000..84f56e64 --- /dev/null +++ b/docs/en/api/packages/compare.md @@ -0,0 +1,374 @@ +# Compare + +Package compare provides a lightweight comparison function on any type. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/compare/compare.go](https://github.com/duke-git/lancet/blob/main/compare/compare.go) + +- [https://github.com/duke-git/lancet/blob/main/compare/compare_internal.go](https://github.com/duke-git/lancet/blob/main/compare/compare_internal.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/condition" +) +``` + + + +## Index + +- [Equal](#Equal) +- [EqualValue](#EqualValue) +- [LessThan](#LessThan) +- [GreaterThan](#GreaterThan) +- [LessOrEqual](#LessOrEqual) +- [GreaterOrEqual](#GreaterOrEqual) +- [InDelta](#InDelta) + + + +## Documentation + +### Equal + +Checks if two values are equal or not. (check both type and value)
+ +Signature: [Run](https://go.dev/play/p/wmVxR-to4lz) + +```go +func Equal(left, right any) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := compare.Equal(1, 1) + result2 := compare.Equal("1", "1") + result3 := compare.Equal([]int{1, 2, 3}, []int{1, 2, 3}) + result4 := compare.Equal(map[int]string{1: "a", 2: "b"}, map[int]string{1: "a", 2: "b"}) + + result5 := compare.Equal(1, "1") + result6 := compare.Equal(1, int64(1)) + result7 := compare.Equal([]int{1, 2}, []int{1, 2, 3}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + + // Output: + // true + // true + // true + // true + // false + // false + // false +} +``` + +### EqualValue + +Checks if two values are equal or not. (check value only)
+ +Signature: [Run](https://go.dev/play/p/fxnna_LLD9u) + +```go +func EqualValue(left, right any) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := compare.EqualValue(1, 1) + result2 := compare.EqualValue(int(1), int64(1)) + result3 := compare.EqualValue(1, "1") + result4 := compare.EqualValue(1, "2") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // true + // false +} +``` + +### LessThan + +Checks if value `left` less than value `right`.
+ +Signature: [Run](https://go.dev/play/p/cYh7FQQj0ne) + +```go +func LessThan(left, right any) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := compare.LessThan(1, 2) + result2 := compare.LessThan(1.1, 2.2) + result3 := compare.LessThan("a", "b") + + time1 := time.Now() + time2 := time1.Add(time.Second) + result4 := compare.LessThan(time1, time2) + + result5 := compare.LessThan(2, 1) + result6 := compare.LessThan(1, int64(2)) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // true + // true + // true + // true + // false + // false +} +``` + +### GreaterThan + +Checks if value `left` greater than value `right`.
+ +Signature: + +```go +func GreaterThan(left, right any) bool +``` + +Example: [Run](https://go.dev/play/p/9-NYDFZmIMp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := compare.GreaterThan(2, 1) + result2 := compare.GreaterThan(2.2, 1.1) + result3 := compare.GreaterThan("b", "a") + + time1 := time.Now() + time2 := time1.Add(time.Second) + result4 := compare.GreaterThan(time2, time1) + + result5 := compare.GreaterThan(1, 2) + result6 := compare.GreaterThan(int64(2), 1) + result7 := compare.GreaterThan("b", "c") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + + // Output: + // true + // true + // true + // true + // false + // false + // false +} +``` + +### LessOrEqual + +Checks if value `left` less than or equal than value `right`.
+ +Signature: + +```go +func LessOrEqual(left, right any) bool +``` + +Example: [Run](https://go.dev/play/p/e4T_scwoQzp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := compare.LessOrEqual(1, 1) + result2 := compare.LessOrEqual(1.1, 2.2) + result3 := compare.LessOrEqual("a", "b") + + time1 := time.Now() + time2 := time1.Add(time.Second) + result4 := compare.LessOrEqual(time1, time2) + + result5 := compare.LessOrEqual(2, 1) + result6 := compare.LessOrEqual(1, int64(2)) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // true + // true + // true + // true + // false + // false +} +``` + +### GreaterOrEqual + +Checks if value `left` less greater or equal than value `right`.
+ +Signature: [Run](https://go.dev/play/p/vx8mP0U8DFk) + +```go +func GreaterOrEqual(left, right any) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := compare.GreaterOrEqual(1, 1) + result2 := compare.GreaterOrEqual(2.2, 1.1) + result3 := compare.GreaterOrEqual("b", "b") + + time1 := time.Now() + time2 := time1.Add(time.Second) + result4 := compare.GreaterOrEqual(time2, time1) + + result5 := compare.GreaterOrEqual(1, 2) + result6 := compare.GreaterOrEqual(int64(2), 1) + result7 := compare.GreaterOrEqual("b", "c") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + + // Output: + // true + // true + // true + // true + // false + // false + // false +} +``` + +### InDelta + +Checks if two values are equal or not within a delta.
+ +Signature: [Run](https://go.dev/play/p/TuDdcNtMkjo) + +```go +func InDelta[T constraints.Integer | constraints.Float](left, right T, delta float64) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/compare" +) + +func main() { + result1 := InDelta(1, 1, 0) + result2 := InDelta(1, 2, 0) + + result3 := InDelta(2.0/3.0, 0.66667, 0.001) + result4 := InDelta(2.0/3.0, 0.0, 0.001) + + result5 := InDelta(float64(74.96)-float64(20.48), 54.48, 0) + result6 := InDelta(float64(74.96)-float64(20.48), 54.48, 1e-14) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // true + // false + // true + // false + // false + // true +} +``` diff --git a/docs/en/api/packages/concurrency.md b/docs/en/api/packages/concurrency.md new file mode 100644 index 00000000..fce2598f --- /dev/null +++ b/docs/en/api/packages/concurrency.md @@ -0,0 +1,854 @@ +# Concurrency + +Package concurrency contain some functions to support concurrent programming. eg, goroutine, channel. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/concurrency/channel.go](https://github.com/duke-git/lancet/blob/main/concurrency/channel.go) +- [https://github.com/duke-git/lancet/blob/main/concurrency/keyed_locker.go](https://github.com/duke-git/lancet/blob/main/concurrency/keyed_locker.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/concurrency" +) +``` + + + +## Index + +### Channel + +- [NewChannel](#NewChannel) +- [Bridge](#Bridge) +- [FanIn](#FanIn) +- [Generate](#Generate) +- [Or](#Or) +- [OrDone](#OrDone) +- [Repeat](#Repeat) +- [RepeatFn](#RepeatFn) +- [Take](#Take) +- [Tee](#Tee) + +### KeyedLocker + +- [NewKeyedLocker](#NewKeyedLocker) +- [Do](#Do) +- [NewRWKeyedLocker](#NewRWKeyedLocker) +- [RLock](#RLock) +- [Lock](#Lock) +- [NewTryKeyedLocker](#NewTryKeyedLocker) +- [TryLock](#TryLock) +- [Unlock](#Unlock) + + + +## Documentation + +## Channel + +### NewChannel + +Create a Channel pointer instance.
+ +Signature: + +```go +type Channel[T any] struct +func NewChannel[T any]() *Channel[T] +``` + +Example: [Run](https://go.dev/play/p/7aB4KyMMp9A) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + c := concurrency.NewChannel[int]() +} +``` + +### Bridge + +Link multiple channels into one channel until cancel the context.
+ +Signature: + +```go +func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-chan T +``` + +Example: [Run](https://go.dev/play/p/qmWSy1NVF-Y) + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c := concurrency.NewChannel[int]() + genVals := func() <-chan <-chan int { + out := make(chan (<-chan int)) + go func() { + defer close(out) + for i := 1; i <= 5; i++ { + stream := make(chan int, 1) + stream <- i + close(stream) + out <- stream + } + }() + return out + } + + for v := range c.Bridge(ctx, genVals()) { + fmt.Println(v) + } + + // Output: + // 1 + // 2 + // 3 + // 4 + // 5 +} +``` + +### FanIn + +Merge multiple channels into one channel until cancel the context.
+ +Signature: + +```go +func (c *Channel[T]) FanIn(ctx context.Context, channels ...<-chan T) <-chan T +``` + +Example: [Run](https://go.dev/play/p/2VYFMexEvTm) + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c := concurrency.NewChannel[int]() + channels := make([]<-chan int, 2) + + for i := 0; i < 2; i++ { + channels[i] = c.Take(ctx, c.Repeat(ctx, i), 2) + } + + chs := c.FanIn(ctx, channels...) + + for v := range chs { + fmt.Println(v) //1 1 0 0 or 0 0 1 1 + } +} +``` + +### Repeat + +Create channel, put values into the channel repeatly until cancel the context.
+ +Signature: [Run](https://go.dev/play/p/k5N_ALVmYjE) + +```go +func (c *Channel[T]) Repeat(ctx context.Context, values ...T) <-chan T +``` + +Example: + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c := concurrency.NewChannel[int]() + intStream := c.Take(ctx, c.Repeat(ctx, 1, 2), 4) + + for v := range intStream { + fmt.Println(v) + } + + // Output: + // 1 + // 2 + // 1 + // 2 +} +``` + +### Generate + +Creates a channel, then put values into the channel.
+ +Signature: + +```go +func (c *Channel[T]) Generate(ctx context.Context, values ...T) <-chan T +``` + +Example: [Run](https://go.dev/play/p/7aB4KyMMp9A) + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c := concurrency.NewChannel[int]() + intStream := c.Generate(ctx, 1, 2, 3) + + fmt.Println(<-intStream) + fmt.Println(<-intStream) + fmt.Println(<-intStream) + + // Output: + // 1 + // 2 + // 3 +} +``` + +### RepeatFn + +Create a channel, excutes fn repeatly, and put the result into the channel, until close context.
+ +Signature: [Run](https://go.dev/play/p/4J1zAWttP85) + +```go +func (c *Channel[T]) RepeatFn(ctx context.Context, fn func() T) <-chan T +``` + +Example: + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + fn := func() string { + return "hello" + } + + c := concurrency.NewChannel[string]() + intStream := c.Take(ctx, c.RepeatFn(ctx, fn), 3) + + for v := range intStream { + fmt.Println(v) + } + + // Output: + // hello + // hello + // hello +} +``` + +### Or + +Read one or more channels into one channel, will close when any readin channel is closed.
+ +Signature: [Run](https://go.dev/play/p/Wqz9rwioPww) + +```go +func (c *Channel[T]) Or(channels ...<-chan T) <-chan T +``` + +Example: + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + sig := func(after time.Duration) <-chan any { + c := make(chan any) + go func() { + defer close(c) + time.Sleep(after) + }() + return c + } + + start := time.Now() + + c := concurrency.NewChannel[any]() + <-c.Or( + sig(1*time.Second), + sig(2*time.Second), + sig(3*time.Second), + ) + + fmt.Println("done after %v", time.Since(start)) //1.003s +} +``` + +### OrDone + +Read a channel into another channel, will close until cancel context.
+ +Signature: [Run](https://go.dev/play/p/lm_GoS6aDjo) + +```go +func (c *Channel[T]) OrDone(ctx context.Context, channel <-chan T) <-chan T +``` + +Example: + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c := concurrency.NewChannel[int]() + intStream := c.Take(ctx, c.Repeat(ctx, 1), 3) + + for v := range c.OrDone(ctx, intStream) { + fmt.Println(v) + } + + // Output: + // 1 + // 1 + // 1 +} +``` + +### Take + +Create a channel whose values are taken from another channel with limit number.
+ +Signature: [Run](https://go.dev/play/p/9Utt-1pDr2J) + +```go +func (c *Channel[T]) Take(ctx context.Context, valueStream <-chan T, number int) <-chan T +``` + +Example: + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + numbers := make(chan int, 5) + numbers <- 1 + numbers <- 2 + numbers <- 3 + numbers <- 4 + numbers <- 5 + defer close(numbers) + + c := concurrency.NewChannel[int]() + intStream := c.Take(ctx, numbers, 3) + + for v := range intStream { + fmt.Println(v) + } + + // Output: + // 1 + // 2 + // 3 +} +``` + +### Tee + +Split one chanel into two channels, until cancel the context.
+ +Signature: [Run](https://go.dev/play/p/3TQPKnCirrP) + +```go +func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T) +``` + +Example: + +```go +package main + +import ( + "context" + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c := concurrency.NewChannel[int]() + intStream := c.Take(ctx, c.Repeat(ctx, 1), 2) + + ch1, ch2 := c.Tee(ctx, intStream) + + for v := range ch1 { + fmt.Println(v) + fmt.Println(<-ch2) + } + + // Output: + // 1 + // 1 + // 1 + // 1 +} +``` + +### KeyedLocker + +### NewKeyedLocker + +KeyedLocker is a simple implementation of a keyed locker that allows for non-blocking lock acquisition.
+ +Signature: + +```go +func NewKeyedLocker[K comparable](ttl time.Duration) *KeyedLocker[K] +``` + +Example:[Run](https://go.dev/play/p/GzeyC33T5rw) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewKeyedLocker[string](2 * time.Second) + + task := func() { + fmt.Println("Executing task...") + time.Sleep(1 * time.Second) + fmt.Println("Task completed.") + } + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + if err := locker.Do(ctx, "mykey", task); err != nil { + log.Fatalf("Error executing task: %v\n", err) + } else { + fmt.Println("Task successfully executed.") + } + + ctx2, cancel2 := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel2() + + if err := locker.Do(ctx2, "mykey", task); err != nil { + log.Fatalf("Error executing task: %v\n", err) + } else { + fmt.Println("Task successfully executed.") + } + + // Output: + // Executing task... + // Task completed. + // Task successfully executed. + // Executing task... + // Task completed. + // Task successfully executed. +} +``` + +### Do + +Acquires a lock for the specified key and executes the provided function.
+ +Signature: + +```go +func (l *KeyedLocker[K]) Do(ctx context.Context, key K, fn func()) error +``` + +Example:[Run](https://go.dev/play/p/GzeyC33T5rw) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewKeyedLocker[string](2 * time.Second) + + task := func() { + fmt.Println("Executing task...") + time.Sleep(1 * time.Second) + fmt.Println("Task completed.") + } + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + if err := locker.Do(ctx, "mykey", task); err != nil { + log.Fatalf("Error executing task: %v\n", err) + } else { + fmt.Println("Task successfully executed.") + } + + ctx2, cancel2 := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel2() + + if err := locker.Do(ctx2, "mykey", task); err != nil { + log.Fatalf("Error executing task: %v\n", err) + } else { + fmt.Println("Task successfully executed.") + } + + // Output: + // Executing task... + // Task completed. + // Task successfully executed. + // Executing task... + // Task completed. + // Task successfully executed. +} +``` + +### NewRWKeyedLocker + +RWKeyedLocker is a read-write version of KeyedLocker.
+ +Signature: + +```go +func NewRWKeyedLocker[K comparable](ttl time.Duration) *RWKeyedLocker[K] +``` + +Example:[Run](https://go.dev/play/p/ZrCr8sMo77T) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewRWKeyedLocker[string](2 * time.Second) + + // Simulate a key + key := "resource_key" + + fn := func() { + fmt.Println("Starting write operation...") + // Simulate write operation, assuming it takes 2 seconds + time.Sleep(200 * time.Millisecond) + fmt.Println("Write operation completed!") + } + + // Acquire the write lock and execute the operation + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + // Execute the lock operation with a 3-second timeout + err := locker.Lock(ctx, key, fn) + if err != nil { + return + } + + //output: + //Starting write operation... + //Write operation completed! +} +``` + +### RLock + +Acquires a read lock for the specified key and executes the provided function.
+ +Signature: + +```go +func (l *RWKeyedLocker[K]) RLock(ctx context.Context, key K, fn func()) error +``` + +Example:[Run](https://go.dev/play/p/ZrCr8sMo77T) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewRWKeyedLocker[string](2 * time.Second) + + // Simulate a key + key := "resource_key" + + fn := func() { + fmt.Println("Starting write operation...") + // Simulate write operation, assuming it takes 2 seconds + time.Sleep(200 * time.Millisecond) + fmt.Println("Write operation completed!") + } + + // Acquire the write lock and execute the operation + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + // Execute the lock operation with a 3-second timeout + err := locker.RLock(ctx, key, fn) + if err != nil { + return + } + + //output: + //Starting write operation... + //Write operation completed! +} +``` + +### Lock + +Acquires a write lock for the specified key and executes the provided function.
+ +Signature: + +```go +func (l *RWKeyedLocker[K]) Lock(ctx context.Context, key K, fn func()) error +``` + +Example:[Run](https://go.dev/play/p/WgAcXbOPKGk) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := NewRWKeyedLocker[string](2 * time.Second) + + // Simulate a key + key := "resource_key" + + fn := func() { + fmt.Println("Starting write operation...") + // Simulate write operation, assuming it takes 2 seconds + time.Sleep(200 * time.Millisecond) + fmt.Println("Write operation completed!") + } + + // Acquire the write lock and execute the operation + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + // Execute the lock operation with a 3-second timeout + err := locker.Lock(ctx, key, fn) + if err != nil { + return + } + + //output: + //Starting write operation... + //Write operation completed! +} +``` + +### NewTryKeyedLocker + +TryKeyedLocker is a non-blocking version of KeyedLocker.
+ +Signature: + +```go +func NewTryKeyedLocker[K comparable]() *TryKeyedLocker[K] +``` + +Example:[Run](https://go.dev/play/p/VG9qLvyetE2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewTryKeyedLocker[string]() + + key := "resource_key" + + if locker.TryLock(key) { + fmt.Println("Lock acquired") + time.Sleep(1 * time.Second) + // Unlock after work is done + locker.Unlock(key) + fmt.Println("Lock released") + } else { + fmt.Println("Lock failed") + } + + //output: + //Lock acquired + //Lock released +} +``` + +### TryLock + +TryLock tries to acquire a lock for the specified key.
+ +Signature: + +```go +func (l *TryKeyedLocker[K]) TryLock(key K) bool +``` + +Example:[Run](https://go.dev/play/p/VG9qLvyetE2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewTryKeyedLocker[string]() + + key := "resource_key" + + if locker.TryLock(key) { + fmt.Println("Lock acquired") + time.Sleep(1 * time.Second) + // Unlock after work is done + locker.Unlock(key) + fmt.Println("Lock released") + } else { + fmt.Println("Lock failed") + } + + //output: + //Lock acquired + //Lock released +} +``` + +### Unlock + +Unlock releases the lock for the specified key.
+ +Signature: + +```go +func (l *TryKeyedLocker[K]) Unlock(key K) +``` + +Example:[Run](https://go.dev/play/p/VG9qLvyetE2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/concurrency" +) + +func main() { + locker := concurrency.NewTryKeyedLocker[string]() + + key := "resource_key" + + if locker.TryLock(key) { + fmt.Println("Lock acquired") + time.Sleep(1 * time.Second) + // Unlock after work is done + locker.Unlock(key) + fmt.Println("Lock released") + } else { + fmt.Println("Lock failed") + } + + //output: + //Lock acquired + //Lock released +} +``` diff --git a/docs/en/api/packages/condition.md b/docs/en/api/packages/condition.md new file mode 100644 index 00000000..1c3af32c --- /dev/null +++ b/docs/en/api/packages/condition.md @@ -0,0 +1,346 @@ +# Condition +Package condition contains some functions for conditional judgment. eg. And, Or, TernaryOperator... The implementation of this package refers to the implementation of carlmjohnson's truthy package, you may find more useful information in [truthy](https://github.com/carlmjohnson/truthy), thanks carlmjohnson. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/condition/condition.go](https://github.com/duke-git/lancet/blob/main/condition/condition.go) + + + +## Usage: +```go +import ( + "github.com/duke-git/lancet/v2/condition" +) +``` + + + +## Index + +- [Bool](#Bool) +- [And](#And) +- [Or](#Or) +- [Xor](#Generate) +- [Nor](#Nor) +- [Xnor](#Xnor) +- [Nand](#Nand) +- [Ternary](#Ternary) +- [TernaryOperatordeprecated](#TernaryOperator) + + + +## Documentation + + +### Bool +Returns the truthy value of anything.
+If the value's type has a Bool() bool method, the method is called and returned.
+If the type has an IsZero() bool method, the opposite value is returned.
+Slices and maps are truthy if they have a length greater than zero.
+All other types are truthy if they are not their zero value.
Returns true if both a and b are truthy.
+ +Signature: + +```go +func And[T, U any](a T, b U) bool +``` +Example:[运行](https://go.dev/play/p/W1SSUmt6pvr) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + fmt.Println(condition.And(0, 1)) // false + fmt.Println(condition.And(0, "")) // false + fmt.Println(condition.And(0, "0")) // false + fmt.Println(condition.And(1, "0")) // true +} +``` + + + +### Or +Returns false if neither a nor b is truthy.
+ +Signature: + +```go +func Or[T, U any](a T, b U) bool +``` +Example:[运行](https://go.dev/play/p/UlQTxHaeEkq) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + fmt.Println(condition.Or(0, "")) // false + fmt.Println(condition.Or(0, 1)) // true + fmt.Println(condition.Or(0, "0")) // true + fmt.Println(condition.Or(1, "0")) // true +} +``` + + + +### Xor +Returns true if a or b but not both is truthy.
+ +Signature: + +```go +func Xor[T, U any](a T, b U) bool +``` +Example:[运行](https://go.dev/play/p/gObZrW7ZbG8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + fmt.Println(condition.Xor(0, 0)) // false + fmt.Println(condition.Xor(0, 1)) // true + fmt.Println(condition.Xor(1, 0)) // true + fmt.Println(condition.Xor(1, 1)) // false +} +``` + + + +### Nor +Returns true if neither a nor b is truthy.
+ +Signature: + +```go +func Nor[T, U any](a T, b U) bool +``` +Example:[运行](https://go.dev/play/p/g2j08F_zZky) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + fmt.Println(condition.Nor(0, 0)) // true + fmt.Println(condition.Nor(0, 1)) // false + fmt.Println(condition.Nor(1, 0)) // false + fmt.Println(condition.Nor(1, 1)) // false +} +``` + + +### Xnor +Returns true if both a and b or neither a nor b are truthy.
+ +Signature: + +```go +func Xnor[T, U any](a T, b U) bool +``` +Example:[运行](https://go.dev/play/p/OuDB9g51643) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + fmt.Println(condition.Xnor(0, 0)) // true + fmt.Println(condition.Xnor(0, 1)) // false + fmt.Println(condition.Xnor(1, 0)) // false + fmt.Println(condition.Xnor(1, 1)) // true +} +``` + + +### Nand +Returns false if both a and b are truthy
+ +Signature: + +```go +func Nand[T, U any](a T, b U) bool +``` +Example:[运行](https://go.dev/play/p/vSRMLxLIbq8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + fmt.Println(condition.Nand(0, 0)) // true + fmt.Println(condition.Nand(0, 1)) // true + fmt.Println(condition.Nand(1, 0)) // true + fmt.Println(condition.Nand(1, 1)) // false +} +``` + + + +### Ternary +Checks the value of param `isTrue`, if true return ifValue else return elseValue
+ +Signature: + +```go +func Ternary[T, U any](isTrue T, ifValue U, elseValue U) U +``` +Example:[运行](https://go.dev/play/p/ElllPZY0guT) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + conditionTrue := 2 > 1 + result1 := condition.Ternary(conditionTrue, 0, 1) + + conditionFalse := 2 > 3 + result2 := condition.Ternary(conditionFalse, 0, 1) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // 1 +} +``` + +### TernaryOperator +Checks the value of param `isTrue`, if true return ifValue else return elseValue
+ +> ⚠️ This function is deprecated. use `Ternary` instead. + +Signature: + +```go +func TernaryOperator[T, U any](isTrue T, ifValue U, elseValue U) U +``` +Example:[运行](https://go.dev/play/p/ElllPZY0guT) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/condition" +) + +func main() { + conditionTrue := 2 > 1 + result1 := condition.TernaryOperator(conditionTrue, 0, 1) + + conditionFalse := 2 > 3 + result2 := condition.TernaryOperator(conditionFalse, 0, 1) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // 1 +} +``` + + + + + diff --git a/docs/en/api/packages/convertor.md b/docs/en/api/packages/convertor.md new file mode 100644 index 00000000..24d1e3d0 --- /dev/null +++ b/docs/en/api/packages/convertor.md @@ -0,0 +1,1150 @@ +# Convertor + +Package convertor contains some functions for data type convertion. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/convertor" +) +``` + + + +## Index + +- [ColorHexToRGB](#ColorHexToRGB) +- [ColorRGBToHex](#ColorRGBToHex) +- [ToBool](#ToBool) +- [ToBytes](#ToBytes) +- [ToChar](#ToChar) +- [ToChannel](#ToChannel) +- [ToFloat](#ToFloat) +- [ToInt](#ToInt) +- [ToJson](#ToJson) +- [ToMap](#ToMap) +- [ToPointer](#ToPointer) +- [ToString](#ToString) +- [StructToMap](#StructToMap) +- [MapToSlice](#MapToSlice) +- [EncodeByte](#EncodeByte) +- [DecodeByte](#DecodeByte) +- [DeepClone](#DeepClone) +- [CopyProperties](#CopyProperties) +- [ToInterface](#ToInterface) +- [Utf8ToGbk](#Utf8ToGbk) +- [GbkToUtf8](#GbkToUtf8) +- [ToStdBase64](#ToStdBase64) +- [ToUrlBase64](#ToUrlBase64) +- [ToRawStdBase64](#ToRawStdBase64) +- [ToRawUrlBase64](#ToRawUrlBase64) +- [ToBigInt](#ToBigInt) + + + +## Documentation + +### ColorHexToRGB + +Convert color hex to color rgb.
+ +Signature: + +```go +func ColorHexToRGB(colorHex string) (red, green, blue int) +``` + +Example:[Run](https://go.dev/play/p/o7_ft-JCJBV) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + colorHex := "#003366" + r, g, b := convertor.ColorHexToRGB(colorHex) + + fmt.Println(r, g, b) + + // Output: + // 0 51 102 +} +``` + +### ColorRGBToHex + +Convert color rgb to color hex.
+ +Signature: + +```go +func ColorRGBToHex(red, green, blue int) string +``` + +Example:[Run](https://go.dev/play/p/nzKS2Ro87J1) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + r := 0 + g := 51 + b := 102 + colorHex := ColorRGBToHex(r, g, b) + + fmt.Println(colorHex) + + // Output: + // #003366 +} +``` + +### ToBool + +Convert string to bool. Use strconv.ParseBool.
+ +Signature: + +```go +func ToBool(s string) (bool, error) +``` + +Example:[Run](https://go.dev/play/p/ARht2WnGdIN) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + cases := []string{"1", "true", "True", "false", "False", "0", "123", "0.0", "abc"} + + for i := 0; i < len(cases); i++ { + result, _ := convertor.ToBool(cases[i]) + fmt.Println(result) + } + + // Output: + // true + // true + // true + // false + // false + // false + // false + // false + // false +} +``` + +### ToBytes + +Convert value to byte slice.
+ +Signature: + +```go +func ToBytes(data any) ([]byte, error) +``` + +Example:[Run](https://go.dev/play/p/fAMXYFDvOvr) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + bytesData, err := convertor.ToBytes("abc") + if err != nil { + fmt.Println(err) + } + + fmt.Println(bytesData) + + // Output: + // [97 98 99] +} +``` + +### ToChar + +Convert string to char slice.
+ +Signature: + +```go +func ToChar(s string) []string +``` + +Example:[Run](https://go.dev/play/p/JJ1SvbFkVdM) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + result1 := convertor.ToChar("") + result2 := convertor.ToChar("abc") + result3 := convertor.ToChar("1 2#3") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // [] + // [a b c] + // [1 2 # 3] +} +``` + +### ToChannel + +Convert a collection of elements to a read-only channel.
+ +Signature: + +```go +func ToChannel[T any](array []T) <-chan T +``` + +Example:[Run](https://go.dev/play/p/hOx_oYZbAnL) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + ch := convertor.ToChannel([]int{1, 2, 3}) + result1 := <-ch + result2 := <-ch + result3 := <-ch + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 1 + // 2 + // 3 +} +``` + +### ToFloat + +Convert value to a float64 value. If param is a invalid floatable, will return 0.0 and error.
+ +Signature: + +```go +func ToFloat(value any) (float64, error) +``` + +Example:[Run](https://go.dev/play/p/4YTmPCibqHJ) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + result1, _ := convertor.ToFloat("") + result2, err := convertor.ToFloat("abc") + result3, _ := convertor.ToFloat("-1") + result4, _ := convertor.ToFloat("-.11") + result5, _ := convertor.ToFloat("1.23e3") + result6, _ := convertor.ToFloat(true) + + fmt.Println(result1) + fmt.Println(result2, err) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // 0 + // 0 strconv.ParseFloat: parsing "": invalid syntax + // -1 + // -0.11 + // 1230 + // 0 +} +``` + +### ToInt + +Convert value to a int64 value. If param is a invalid intable, will return 0 and error.
+ +Signature: + +```go +func ToInt(value any) (int64, error) +``` + +Example:[Run](https://go.dev/play/p/9_h9vIt-QZ_b) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + result1, _ := convertor.ToInt("123") + result2, _ := convertor.ToInt("-123") + result3, _ := convertor.ToInt(float64(12.3)) + result4, err := convertor.ToInt("abc") + result5, _ := convertor.ToInt(true) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4, err) + fmt.Println(result5) + + // Output: + // 123 + // -123 + // 12 + // 0 strconv.ParseInt: parsing "": invalid syntax + // 0 +} +``` + +### ToJson + +Convert interface to json string. If param can't be converted, will return "" and error.
+ +Signature: + +```go +func ToJson(value any) (string, error) +``` + +Example:[Run](https://go.dev/play/p/2rLIkMmXWvR) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + aMap := map[string]int{"a": 1, "b": 2, "c": 3} + result, err := convertor.ToJson(aMap) + + if err != nil { + fmt.Printf("%v", err) + } + + fmt.Println(result) + + // Output: + // {"a":1,"b":2,"c":3} +} +``` + +### ToMap + +Convert a slice of structs to a map based on iteratee function.
+ +Signature: + +```go +func ToMap[T any, K comparable, V any](array []T, iteratee func(T) (K, V)) map[K]V +``` + +Example:[Run](https://go.dev/play/p/tVFy7E-t24l) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + type Message struct { + name string + code int + } + messages := []Message{ + {name: "Hello", code: 100}, + {name: "Hi", code: 101}, + } + + result := convertor.ToMap(messages, func(msg Message) (int, string) { + return msg.code, msg.name + }) + + fmt.Println(result) + + // Output: + // map[100:Hello 101:Hi] +} +``` + +### ToPointer + +Returns a pointer to passed value.
+ +Signature: + +```go +func ToPointer[T any](value T) *T +``` + +Example:[Run](https://go.dev/play/p/ASf_etHNlw1) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + result := convertor.ToPointer(123) + fmt.Println(*result) + + // Output: + // 123 +} +``` + +### ToString + +ToString convert value to string, for number, string, []byte, will convert to string. For other type (slice, map, array, struct) will call json.Marshal
+ +Signature: + +```go +func ToString(value any) string +``` + +Example:[Run](https://go.dev/play/p/nF1zOOslpQq) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + result1 := convertor.ToString("") + result2 := convertor.ToString(nil) + result3 := convertor.ToString(0) + result4 := convertor.ToString(1.23) + result5 := convertor.ToString(true) + result6 := convertor.ToString(false) + result7 := convertor.ToString([]int{1, 2, 3}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + + // Output: + // + // + // 0 + // 1.23 + // true + // false + // [1,2,3] +} +``` + +### StructToMap + +Convert struct to map, only convert exported field, struct field tag `json` should be set.
+ +Signature: + +```go +func StructToMap(value any) (map[string]any, error) +``` + +Example:[Run](https://go.dev/play/p/KYGYJqNUBOI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + type People struct { + Name string `json:"name"` + age int + } + p := People{ + "test", + 100, + } + pm, _ := convertor.StructToMap(p) + + fmt.Println(pm) + + // Output: + // map[name:test] +} +``` + +### MapToSlice + +Convert a map to a slice based on iteratee function.
+ +Signature: + +```go +func MapToSlice[T any, K comparable, V any](aMap map[K]V, iteratee func(K, V) T) []T +``` + +Example:[Run](https://go.dev/play/p/dmX4Ix5V6Wl) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + aMap := map[string]int{"a": 1, "b": 2, "c": 3} + result := MapToSlice(aMap, func(key string, value int) string { + return key + ":" + strconv.Itoa(value) + }) + + fmt.Println(result) //[]string{"a:1", "b:2", "c:3"} +} +``` + + +### EncodeByte + +Encode data to byte slice.
+ +Signature: + +```go +func EncodeByte(data any) ([]byte, error) +``` + +Example:[Run](https://go.dev/play/p/DVmM1G5JfuP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + byteData, _ := convertor.EncodeByte("abc") + fmt.Println(byteData) + + // Output: + // [6 12 0 3 97 98 99] +} +``` + +### DecodeByte + +Decode byte data to target object. target should be a pointer instance.
+ +Signature: + +```go +func DecodeByte(data []byte, target any) error +``` + +Example:[Run](https://go.dev/play/p/zI6xsmuQRbn) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + var result string + byteData := []byte{6, 12, 0, 3, 97, 98, 99} + + err := convertor.DecodeByte(byteData, &result) + if err != nil { + return + } + + fmt.Println(result) + + // Output: + // abc +} +``` + + +### CopyProperties + +Copies each field from the source struct into the destination struct. Use json.Marshal/Unmarshal, so json tag should be set for fields of dst and src struct.
+ +Signature: + +```go +func CopyProperties[T, U any](dst T, src U) (err error) +``` + +Example:[Run](https://go.dev/play/p/oZujoB5Sgg5) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + type Disk struct { + Name string `json:"name"` + Total string `json:"total"` + Used string `json:"used"` + Percent float64 `json:"percent"` + } + + type DiskVO struct { + Name string `json:"name"` + Total string `json:"total"` + Used string `json:"used"` + Percent float64 `json:"percent"` + } + + type Indicator struct { + Id string `json:"id"` + Ip string `json:"ip"` + UpTime string `json:"upTime"` + LoadAvg string `json:"loadAvg"` + Cpu int `json:"cpu"` + Disk []Disk `json:"disk"` + Stop chan bool `json:"-"` + } + + type IndicatorVO struct { + Id string `json:"id"` + Ip string `json:"ip"` + UpTime string `json:"upTime"` + LoadAvg string `json:"loadAvg"` + Cpu int64 `json:"cpu"` + Disk []DiskVO `json:"disk"` + } + + indicator := &Indicator{Id: "001", Ip: "127.0.0.1", Cpu: 1, Disk: []Disk{ + {Name: "disk-001", Total: "100", Used: "1", Percent: 10}, + {Name: "disk-002", Total: "200", Used: "1", Percent: 20}, + {Name: "disk-003", Total: "300", Used: "1", Percent: 30}, + }} + + indicatorVO := IndicatorVO{} + + err := convertor.CopyProperties(&indicatorVO, indicator) + + if err != nil { + return + } + + fmt.Println(indicatorVO.Id) + fmt.Println(indicatorVO.Ip) + fmt.Println(len(indicatorVO.Disk)) + + // Output: + // 001 + // 127.0.0.1 + // 3 +} +``` + +### Utf8ToGbk + +Converts utf8 encoding data to GBK encoding data.
+ +Signature: + +```go +func Utf8ToGbk(bs []byte) ([]byte, error) +``` + +Example:[Run](https://go.dev/play/p/9FlIaFLArIL) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + utf8Data := []byte("hello") + gbkData, _ := convertor.Utf8ToGbk(utf8Data) + + fmt.Println(utf8.Valid(utf8Data)) + fmt.Println(validator.IsGBK(gbkData)) + + // Output: + // true + // true +} +``` + +### GbkToUtf8 + +Converts GBK encoding data to utf8 encoding data.
+ +Signature: + +```go +func GbkToUtf8(bs []byte) ([]byte, error) +``` + +Example:[Run](https://go.dev/play/p/OphmHCN_9u8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + gbkData, _ := convertor.Utf8ToGbk([]byte("hello")) + utf8Data, _ := convertor.GbkToUtf8(gbkData) + + fmt.Println(utf8.Valid(utf8Data)) + fmt.Println(string(utf8Data)) + + // Output: + // true + // hello +} +``` + +### ToStdBase64 + +Convert a value to a string encoded in standard Base64. Error data of type "error" will also be encoded, and complex structures will be converted to a JSON formatted string.
+ +Signature: + +```go +func ToStdBase64(value any) string +``` + +Example:[Run](https://go.dev/play/p/_fLJqJD3NMo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + afterEncode := convertor.ToStdBase64(nil) + fmt.Println(afterEncode) + + afterEncode = convertor.ToStdBase64("") + fmt.Println(afterEncode) + + stringVal := "hello" + afterEncode = convertor.ToStdBase64(stringVal) + fmt.Println(afterEncode) + + byteSliceVal := []byte("hello") + afterEncode = convertor.ToStdBase64(byteSliceVal) + fmt.Println(afterEncode) + + intVal := 123 + afterEncode = convertor.ToStdBase64(intVal) + fmt.Println(afterEncode) + + mapVal := map[string]any{"a": "hi", "b": 2, "c": struct { + A string + B int + }{"hello", 3}} + afterEncode = convertor.ToStdBase64(mapVal) + fmt.Println(afterEncode) + + floatVal := 123.456 + afterEncode = convertor.ToStdBase64(floatVal) + fmt.Println(afterEncode) + + boolVal := true + afterEncode = convertor.ToStdBase64(boolVal) + fmt.Println(afterEncode) + + errVal := errors.New("err") + afterEncode = convertor.ToStdBase64(errVal) + fmt.Println(afterEncode) + + // Output: + // + // + // aGVsbG8= + // aGVsbG8= + // MTIz + // eyJhIjoiaGkiLCJiIjoyLCJjIjp7IkEiOiJoZWxsbyIsIkIiOjN9fQ== + // MTIzLjQ1Ng== + // dHJ1ZQ== + // ZXJy +} + +``` + + + +### ToUrlBase64 + +Convert a value to a string encoded in url Base64. Error data of type "error" will also be encoded, and complex structures will be converted to a JSON formatted string.
+ +Signature: + +```go +func ToUrlBase64(value any) string +``` + +Example:[Run](https://go.dev/play/p/C_d0GlvEeUR) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + afterEncode := convertor.ToUrlBase64(nil) + fmt.Println(afterEncode) + + + stringVal := "hello" + afterEncode = convertor.ToUrlBase64(stringVal) + fmt.Println(afterEncode) + + byteSliceVal := []byte("hello") + afterEncode = convertor.ToUrlBase64(byteSliceVal) + fmt.Println(afterEncode) + + intVal := 123 + afterEncode = convertor.ToUrlBase64(intVal) + fmt.Println(afterEncode) + + mapVal := map[string]any{"a": "hi", "b": 2, "c": struct { + A string + B int + }{"hello", 3}} + afterEncode = convertor.ToUrlBase64(mapVal) + fmt.Println(afterEncode) + + floatVal := 123.456 + afterEncode = convertor.ToUrlBase64(floatVal) + fmt.Println(afterEncode) + + boolVal := true + afterEncode = convertor.ToUrlBase64(boolVal) + fmt.Println(afterEncode) + + errVal := errors.New("err") + afterEncode = convertor.ToUrlBase64(errVal) + fmt.Println(afterEncode) + + // Output: + // + // aGVsbG8= + // aGVsbG8= + // MTIz + // eyJhIjoiaGkiLCJiIjoyLCJjIjp7IkEiOiJoZWxsbyIsIkIiOjN9fQ== + // MTIzLjQ1Ng== + // dHJ1ZQ== + // ZXJy +} + +``` + +### ToRawStdBase64 + +Convert a value to a string encoded in raw standard Base64. Error data of type "error" will also be encoded, and complex structures will be converted to a JSON formatted string.
+ +Signature: + +```go +func ToRawStdBase64(value any) string +``` + +Example:[Run](https://go.dev/play/p/wSAr3sfkDcv) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + + stringVal := "hello" + afterEncode := convertor.ToRawStdBase64(stringVal) + fmt.Println(afterEncode) + + byteSliceVal := []byte("hello") + afterEncode = convertor.ToRawStdBase64(byteSliceVal) + fmt.Println(afterEncode) + + intVal := 123 + afterEncode = convertor.ToRawStdBase64(intVal) + fmt.Println(afterEncode) + + mapVal := map[string]any{"a": "hi", "b": 2, "c": struct { + A string + B int + }{"hello", 3}} + afterEncode = convertor.ToRawStdBase64(mapVal) + fmt.Println(afterEncode) + + floatVal := 123.456 + afterEncode = convertor.ToRawStdBase64(floatVal) + fmt.Println(afterEncode) + + boolVal := true + afterEncode = convertor.ToRawStdBase64(boolVal) + fmt.Println(afterEncode) + + errVal := errors.New("err") + afterEncode = convertor.ToRawStdBase64(errVal) + fmt.Println(afterEncode) + + // Output: + // aGVsbG8 + // aGVsbG8 + // MTIz + // eyJhIjoiaGkiLCJiIjoyLCJjIjp7IkEiOiJoZWxsbyIsIkIiOjN9fQ + // MTIzLjQ1Ng + // dHJ1ZQ + // ZXJy +} +``` + +### ToRawUrlBase64 + +Convert a value to a string encoded in raw url Base64. Error data of type "error" will also be encoded, and complex structures will be converted to a JSON formatted string.
+ +Signature: + +```go +func ToRawUrlBase64(value any) string +``` + +Example:[Run](https://go.dev/play/p/HwdDPFcza1O) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + + stringVal := "hello" + afterEncode := convertor.ToRawUrlBase64(stringVal) + fmt.Println(afterEncode) + + byteSliceVal := []byte("hello") + afterEncode = convertor.ToRawUrlBase64(byteSliceVal) + fmt.Println(afterEncode) + + intVal := 123 + afterEncode = convertor.ToRawUrlBase64(intVal) + fmt.Println(afterEncode) + + mapVal := map[string]any{"a": "hi", "b": 2, "c": struct { + A string + B int + }{"hello", 3}} + afterEncode = convertor.ToRawUrlBase64(mapVal) + fmt.Println(afterEncode) + + floatVal := 123.456 + afterEncode = convertor.ToRawUrlBase64(floatVal) + fmt.Println(afterEncode) + + boolVal := true + afterEncode = convertor.ToRawUrlBase64(boolVal) + fmt.Println(afterEncode) + + errVal := errors.New("err") + afterEncode = convertor.ToRawUrlBase64(errVal) + fmt.Println(afterEncode) + + // Output: + // aGVsbG8 + // aGVsbG8 + // MTIz + // eyJhIjoiaGkiLCJiIjoyLCJjIjp7IkEiOiJoZWxsbyIsIkIiOjN9fQ + // MTIzLjQ1Ng + // dHJ1ZQ + // ZXJy +} +``` + +### DeepClone + +Creates a deep copy of passed item, can't clone unexported field of struct.
+ +Signature: + +```go +func DeepClone[T any](src T) T +``` + +Example:[Run](https://go.dev/play/p/j4DP5dquxnk) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + type Struct struct { + Str string + Int int + Float float64 + Bool bool + Nil interface{} + unexported string + } + + cases := []interface{}{ + true, + 1, + 0.1, + map[string]int{ + "a": 1, + "b": 2, + }, + &Struct{ + Str: "test", + Int: 1, + Float: 0.1, + Bool: true, + Nil: nil, + }, + } + + for _, item := range cases { + cloned := convertor.DeepClone(item) + + isPointerEqual := &cloned == &item + fmt.Println(cloned, isPointerEqual) + } + + // Output: + // true false + // 1 false + // 0.1 false + // map[a:1 b:2] false + // &{test 1 0.1 trueConverts an integer of any supported type (int, int64, uint64, etc.) to *big.Int
+ +Signature:[Run](https://go.dev/play/p/X3itkCxwB_x) + +```go +func ToBigInt[T any](v T) (*big.Int, error) +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + n := 9876543210 + bigInt, _ := convertor.ToBigInt(n) + + fmt.Println(bigInt) + // Output: + // 9876543210 +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/cryptor.md b/docs/en/api/packages/cryptor.md new file mode 100644 index 00000000..cb05faf1 --- /dev/null +++ b/docs/en/api/packages/cryptor.md @@ -0,0 +1,1833 @@ +# Cryptor + +Package cryptor contains some functions for data encryption and decryption. Support base64, md5, hmac, aes, des, rsa. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/cryptor/basic.go](https://github.com/duke-git/lancet/blob/main/cryptor/basic.go) +- [https://github.com/duke-git/lancet/blob/main/cryptor/crypto.go](https://github.com/duke-git/lancet/blob/main/cryptor/crypto.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/cryptor" +) +``` + + + +## Index + +- [AesEcbEncrypt](#AesEcbEncrypt) +- [AesEcbDecrypt](#AesEcbDecrypt) +- [AesCbcEncrypt](#AesCbcEncrypt) +- [AesCbcDecrypt](#AesCbcDecrypt) +- [AesCtrCryptdeprecated](#AesCtrCrypt) +- [AesCtrEncrypt](#AesCtrEncrypt) +- [AesCtrDecrypt](#AesCtrDecrypt) +- [AesCfbEncrypt](#AesCfbEncrypt) +- [AesCfbDecrypt](#AesCfbDecrypt) +- [AesOfbEncrypt](#AesOfbEncrypt) +- [AesOfbDecrypt](#AesOfbDecrypt) +- [AesGcmEncrypt](#AesGcmEncrypt) +- [AesGcmDecrypt](#AesGcmDecrypt) +- [Base64StdEncode](#Base64StdEncode) +- [Base64StdDecode](#Base64StdDecode) +- [DesEcbEncrypt](#DesEcbEncrypt) +- [DesEcbDecrypt](#DesEcbDecrypt) +- [DesCbcEncrypt](#DesCbcEncrypt) +- [DesCbcDecrypt](#DesCbcDecrypt) +- [DesCtrCryptdeprecated](#DesCtrCrypt) +- [DesCfbEncrypt](#DesCfbEncrypt) +- [DesCfbDecrypt](#DesCfbDecrypt) +- [DesCfbEncrypt](#DesCfbEncrypt) +- [DesCfbDecrypt](#DesCfbDecrypt) +- [DesOfbEncrypt](#DesOfbEncrypt) +- [DesOfbDecrypt](#DesOfbDecrypt) +- [HmacMd5](#HmacMd5) +- [HmacMd5WithBase64](#HmacMd5WithBase64) +- [HmacSha1](#HmacSha1) +- [HmacSha1WithBase64](#HmacSha1WithBase64) +- [HmacSha256](#HmacSha256) +- [HmacSha256WithBase64](#HmacSha256WithBase64) +- [HmacSha512](#HmacSha512) +- [HmacSha512WithBase64](#HmacSha512WithBase64) +- [Md5String](#Md5String) +- [Md5StringWithBase64](#Md5StringWithBase64) +- [Md5Byte](#Md5Byte) +- [Md5ByteWithBase64](#Md5ByteWithBase64) +- [Md5File](#Md5File) +- [Sha1](#Sha1) +- [Sha1WithBase64](#Sha1WithBase64) +- [Sha256](#Sha256) +- [Sha256WithBase64](#Sha256WithBase64) +- [Sha512](#Sha512) +- [Sha512WithBase64](#Sha512WithBase64) +- [GenerateRsaKey](#GenerateRsaKey) +- [RsaEncrypt](#RsaEncrypt) +- [RsaDecrypt](#RsaDecrypt) +- [GenerateRsaKeyPair](#GenerateRsaKeyPair) +- [RsaEncryptOAEP](#RsaEncryptOAEP) +- [RsaDecryptOAEP](#RsaDecryptOAEP) +- [RsaSign](#RsaSign) +- [RsaVerifySign](#RsaVerifySign) + + + +## Documentation + +### AesEcbEncrypt + +Encrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.
+ +Signature: + +```go +func AesEcbEncrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/zI6xsmuQRbn) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesEcbDecrypt + +Decrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.
+ +Signature: + +```go +func AesEcbDecrypt(encrypted, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/zI6xsmuQRbn) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCbcEncrypt + +Encrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.
+ +Signature: + +```go +func AesCbcEncrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/IOq_g8_lKZD) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCbcDecrypt + +Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.
+ +Signature: + +```go +func AesCbcDecrypt(encrypted, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/IOq_g8_lKZD) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCtrCrypt + +Encrypt or decrypt data with key use AES CTR algorithm. Length of `key` param should be 16, 24 or 32.
+ +> ⚠️ This function is deprecated. use `AesCtrEncrypt` and `AesCtrDecrypt` instead. + +Signature: + +```go +func AesCtrCrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/SpaZO0-5Nsp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCtrEncrypt + +Encrypt data with key use AES CTR algorithm
+ +Signature: + +```go +func AesCtrEncrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/x6pjPAvThRz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCtrEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCtrDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCtrDecrypt + +Decrypt data with key use AES CTR algorithm
+ +Signature: + +```go +func AesCtrDecrypt(encrypted, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/x6pjPAvThRz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCtrEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCtrDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCfbEncrypt + +Encrypt data with key use AES CFB algorithm. Length of `key` param should be 16, 24 or 32.
+ +Signature: + +```go +func AesCfbEncrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/tfkF10B13kH) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesCfbDecrypt + +Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.
+ +Signature: + +```go +func AesCfbDecrypt(encrypted, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/tfkF10B13kH) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesOfbEncrypt + +Enecrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.
+ +Signature: + +```go +func AesOfbEncrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/VtHxtkUj-3F) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesOfbDecrypt + +Decrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.
+ +Signature: + +```go +func AesOfbDecrypt(encrypted, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/VtHxtkUj-3F) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesGcmEncrypt + +Encrypt data with key use AES GCM algorithm.
+ +Signature: + +```go +func AesGcmEncrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/rUt0-DmsPCs) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesGcmEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesGcmDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### AesGcmDecrypt + +Decrypt data with key use AES GCM algorithm.
+ +Signature: + +```go +func AesGcmDecrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/rUt0-DmsPCs) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefghijklmnop" + + encrypted := cryptor.AesGcmEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.AesGcmDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### Base64StdEncode + +Encode string with base64 encoding.
+ +Signature: + +```go +func Base64StdEncode(s string) string +``` + +Example:[Run](https://go.dev/play/p/VOaUyQUreoK) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + base64Str := cryptor.Base64StdEncode("hello") + fmt.Println(base64Str) + + // Output: + // aGVsbG8= +} +``` + +### Base64StdDecode + +Decode a base64 encoded string.
+ +Signature: + +```go +func Base64StdDecode(s string) string +``` + +Example:[Run](https://go.dev/play/p/RWQylnJVgIe) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := cryptor.Base64StdDecode("aGVsbG8=") + fmt.Println(str) + + // Output: + // hello +} +``` + +### DesEcbEncrypt + +Encrypt data with key use DES ECB algorithm. Length of `key` param should be 8.
+ +Signature: + +```go +func DesEcbEncrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/8qivmPeZy4P) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key)) + + decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesEcbDecrypt + +Decrypt data with key use DES ECB algorithm. Length of `key` param should be 8.
+ +Signature: + +```go +func DesEcbDecrypt(encrypted, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/8qivmPeZy4P) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key)) + + decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCbcEncrypt + +Encrypt data with key use DES CBC algorithm. Length of `key` param should be 8.
+ +Signature: + +```go +func DesCbcEncrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/4cC4QvWfe3_1) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCbcDecrypt + +Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.
+ +Signature: + +```go +func DesCbcDecrypt(encrypted, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/4cC4QvWfe3_1) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCtrCrypt + +Encrypt or decrypt data with key use DES CTR algorithm. Length of `key` param should be 8.
+ +> ⚠️ This function is deprecated. use `DesCtrEncrypt` and `DesCtrDecrypt` instead. + +Signature: + +```go +func DesCtrCrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/9-T6OjKpcdw) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCtrCrypt + +Encrypt data with key use DES CTR algorithm. Length of `key` param should be 8.
+ +Signature: + +```go +func DesCtrEncrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/S6p_WHCgH1d) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCtrEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCtrDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCtrDecrypt + +Decrypt data with key use DES CTR algorithm. Length of `key` param should be 8.
+ +Signature: + +```go +func DesCtrDecrypt(encrypted, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/S6p_WHCgH1d) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCtrEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCtrDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCfbEncrypt + +Encrypt data with key use DES CFB algorithm. Length of `key` param should be 8.
+ +Signature: + +```go +func DesCfbEncrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/y-eNxcFBlxL) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesCfbDecrypt + +Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.
+ +Signature: + +```go +func DesCfbDecrypt(encrypted, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/y-eNxcFBlxL) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesOfbEncrypt + +Enecrypt data with key use DES OFB algorithm. Length of `key` param should be 8.
+ +Signature: + +```go +func DesOfbEncrypt(data, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/74KmNadjN1J) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### DesOfbDecrypt + +Decrypt data with key use DES OFB algorithm. Length of `key` param should be 8.
+ +Signature: + +```go +func DesOfbDecrypt(encrypted, key []byte) []byte +``` + +Example:[Run](https://go.dev/play/p/74KmNadjN1J) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := "hello" + key := "abcdefgh" + + encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key)) + decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key)) + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### HmacMd5 + +Get the md5 hmac hash of string.
+ +Signature: + +```go +func HmacMd5(str, key string) string +``` + +Example:[Run](https://go.dev/play/p/uef0q1fz53I) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacMd5(str, key) + fmt.Println(hms) + + // Output: + // e834306eab892d872525d4918a7a639a +} +``` + +### HmacMd5WithBase64 + +Get the md5 hmac hash of base64 string.
+ +Signature: + +```go +func HmacMd5WithBase64(str, key string) string +``` + +Example:[Run](https://go.dev/play/p/UY0ng2AefFC) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacMd5WithBase64(str, key) + fmt.Println(hms) + + // Output: + // 6DQwbquJLYclJdSRinpjmg== +} +``` + +### HmacSha1 + +Get the sha1 hmac hash of string.
+ +Signature: + +```go +func HmacSha1(str, key string) string +``` + +Example:[Run](https://go.dev/play/p/1UI4oQ4WXKM) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacSha1(str, key) + fmt.Println(hms) + + // Output: + // 5c6a9db0cccb92e36ed0323fd09b7f936de9ace0 +} +``` + +### HmacSha1WithBase64 + +Return the hmac hash of string use sha1 with base64.
+ +Signature: + +```go +func HmacSha1WithBase64(str, key string) string +``` + +Example:[Run](https://go.dev/play/p/47JmmGrnF7B) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacSha1WithBase64(str, key) + fmt.Println(hms) + + // Output: + // XGqdsMzLkuNu0DI/0Jt/k23prOA= +} +``` + +### HmacSha256 + +Get the sha256 hmac hash of string
+ +Signature: + +```go +func HmacSha256(str, key string) string +``` + +Example:[Run](https://go.dev/play/p/HhpwXxFhhC0) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacSha256(str, key) + fmt.Println(hms) + + // Output: + // 315bb93c4e989862ba09cb62e05d73a5f376cb36f0d786edab0c320d059fde75 +} +``` + +### HmacSha256WithBase64 + +Return the hmac hash of string use sha256 with base64.
+ +Signature: + +```go +func HmacSha256WithBase64(str, key string) string +``` + +Example:[Run](https://go.dev/play/p/EKbkUvPTLwO) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacSha256WithBase64(str, key) + fmt.Println(hms) + + // Output: + // MVu5PE6YmGK6Ccti4F1zpfN2yzbw14btqwwyDQWf3nU= +} +``` + +### HmacSha512 + +Get the sha512 hmac hash of string.
+ +Signature: + +```go +func HmacSha512(str, key string) string +``` + +Example:[Run](https://go.dev/play/p/59Od6m4A0Ud) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacSha512(str, key) + fmt.Println(hms) + + // Output: + // dd8f1290a9dd23d354e2526d9a2e9ce8cffffdd37cb320800d1c6c13d2efc363288376a196c5458daf53f8e1aa6b45a6d856303d5c0a2064bff9785861d48cfc +} +``` + +### HmacSha512WithBase64 + +Return the hmac hash of string use sha512 with base64.
+ +Signature: + +```go +func HmacSha512WithBase64(str, key string) string +``` + +Example:[Run](https://go.dev/play/p/c6dSe3E2ydU) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + key := "12345" + + hms := cryptor.HmacSha512WithBase64(str, key) + fmt.Println(hms) + + // Output: + // 3Y8SkKndI9NU4lJtmi6c6M///dN8syCADRxsE9Lvw2Mog3ahlsVFja9T+OGqa0Wm2FYwPVwKIGS/+XhYYdSM/A== +} +``` + +### Md5String + +Get the md5 value of string.
+ +Signature: + +```go +func Md5String(s string) string +``` + +Example:[Run](https://go.dev/play/p/1bLcVetbTOI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + + md5Str := cryptor.Md5String(str) + fmt.Println(md5Str) + + // Output: + // 5d41402abc4b2a76b9719d911017c592 +} +``` + +### Md5StringWithBase64 + +Return the md5 value of string with base64.
+ +Signature: + +```go +func Md5StringWithBase64(s string) string +``` + +Example:[Run](https://go.dev/play/p/Tcb-Z7LN2ax) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + md5Str := cryptor.Md5StringWithBase64("hello") + fmt.Println(md5Str) + + // Output: + // XUFAKrxLKna5cZ2REBfFkg== +} +``` + +### Md5Byte + +Return the md5 string of byte slice.
+ +Signature: + +```go +func Md5Byte(data []byte) string +``` + +Example:[Run](https://go.dev/play/p/suraalH8lyC) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + md5Str := cryptor.Md5Byte([]byte{'a'}) + fmt.Println(md5Str) + + // Output: + // 0cc175b9c0f1b6a831c399e269772661 +} +``` + +### Md5ByteWithBase64 + +Return the md5 string of byte slice with base64.
+ +Signature: + +```go +func Md5ByteWithBase64(data []byte) string +``` + +Example:[Run](https://go.dev/play/p/Lx4gH7Vdr5_y) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + md5Str := cryptor.Md5ByteWithBase64([]byte("hello")) + fmt.Println(md5Str) + + // Output: + // XUFAKrxLKna5cZ2REBfFkg== +} +``` + +### Md5File + +Get the md5 value of file.
+ +Signature: + +```go +func Md5File(filepath string) (string, error) +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + s := cryptor.Md5File("./main.go")) + fmt.Println(s) +} +``` + +### Sha1 + +Get the sha1 value of string.
+ +Signature: + +```go +func Sha1(str string) string +``` + +Example:[Run](https://go.dev/play/p/_m_uoD1deMT) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + + result := cryptor.Sha1(str) + fmt.Println(result) + + // Output: + // aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d +} +``` + +### Sha1WithBase64 + +Return the sha1 value (SHA-1 hash algorithm) of base64 string.
+ +Signature: + +```go +func Sha1WithBase64(str string) string +``` + +Example:[Run](https://go.dev/play/p/fSyx-Gl2l2-) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + result := cryptor.Sha1WithBase64("hello") + fmt.Println(result) + + // Output: + // qvTGHdzF6KLavt4PO0gs2a6pQ00= +} +``` + +### Sha256 + +Get the sha256 value of string.
+ +Signature: + +```go +func Sha256(str string) string +``` + +Example:[Run](https://go.dev/play/p/tU9tfBMIAr1) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + + result := cryptor.Sha256(str) + fmt.Println(result) + + // Output: + // 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 +} +``` + +### Sha256WithBase64 + +Return the sha256 value (SHA256 hash algorithm) of base64 string.
+ +Signature: + +```go +func Sha256WithBase64(str string) string +``` + +Example:[Run](https://go.dev/play/p/85IXJHIal1k) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + result := cryptor.Sha256WithBase64("hello") + fmt.Println(result) + + // Output: + // LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ= +} +``` + +### Sha512 + +Get the sha512 value of string.
+ +Signature: + +```go +func Sha512(str string) string +``` + +Example:[Run](https://go.dev/play/p/3WsvLYZxsHa) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + str := "hello" + + result := cryptor.Sha512(str) + fmt.Println(result) + + // Output: + // 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043 +} +``` + +### Sha512WithBase64 + +Get the sha512 value of string with base64.
+ +Signature: + +```go +func Sha512WithBase64(str string) string +``` + +Example:[Run](https://go.dev/play/p/q_fY2rA-k5I) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + result := cryptor.Sha512WithBase64("hello") + fmt.Println(result) + + // Output: + // m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw== +} +``` + +### GenerateRsaKey + +Create the rsa public and private key file in current directory.
+ +Signature: + +```go +func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error +``` + +Example:[Run](https://go.dev/play/p/zutRHrDqs0X) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") + if err != nil { + fmt.Println(err) + } +} +``` + +### RsaEncrypt + +Encrypt data with public key file useing ras algorithm.
+ +Signature: + +```go +func RsaEncrypt(data []byte, pubKeyFileName string) []byte +``` + +Example:[Run](https://go.dev/play/p/7_zo6mrx-eX) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") + if err != nil { + return + } + + data := []byte("hello") + encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem") + decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem") + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### RsaDecrypt + +Decrypt data with private key file useing ras algorithm.
+ +Signature: + +```go +func RsaDecrypt(data []byte, privateKeyFileName string) []byte +``` + +Example:[Run](https://go.dev/play/p/7_zo6mrx-eX) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") + if err != nil { + return + } + + data := []byte("hello") + encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem") + decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem") + + fmt.Println(string(decrypted)) + + // Output: + // hello +} +``` + +### GenerateRsaKeyPair + +Creates rsa private and public key.
+ +Signature: + +```go +func GenerateRsaKeyPair(keySize int) (*rsa.PrivateKey, *rsa.PublicKey) +``` + +Example:[Run](https://go.dev/play/p/sSVmkfENKMz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + pri, pub := cryptor.GenerateRsaKeyPair(1024) +} +``` + +### RsaEncryptOAEP + +Encrypts the given data with RSA-OAEP.
+ +Signature: + +```go +func RsaEncryptOAEP(data []byte, label []byte, key rsa.PublicKey) ([]byte, error) +``` + +Example:[Run](https://go.dev/play/p/sSVmkfENKMz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + pri, pub := cryptor.GenerateRsaKeyPair(1024) + + data := []byte("hello world") + label := []byte("123456") + + encrypted, err := cryptor.RsaEncryptOAEP(data, label, *pub) + if err != nil { + return + } + + decrypted, err := cryptor.RsaDecryptOAEP([]byte(encrypted), label, *pri) + if err != nil { + return + } + + fmt.Println(string(decrypted)) + + // Output: + // hello world +} +``` + +### RsaDecryptOAEP + +Decrypts the data with RSA-OAEP.
+ +Signature: + +```go +func RsaDecryptOAEP(ciphertext []byte, label []byte, key rsa.PrivateKey) ([]byte, error) +``` + +Example:[Run](https://go.dev/play/p/sSVmkfENKMz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + pri, pub := cryptor.GenerateRsaKeyPair(1024) + + data := []byte("hello world") + label := []byte("123456") + + encrypted, err := cryptor.RsaEncryptOAEP(data, label, *pub) + if err != nil { + return + } + + decrypted, err := cryptor.RsaDecryptOAEP([]byte(encrypted), label, *pri) + if err != nil { + return + } + + fmt.Println(string(decrypted)) + + // Output: + // hello world +} +``` + +### RsaSign + +Signs the data with RSA algorithm.
+ +Signature: + +```go +func RsaSign(hash crypto.Hash, data []byte, privateKeyFileName string) ([]byte, error) +``` + +Example:[Run](https://go.dev/play/p/qhsbf8BJ6Mf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := []byte("This is a test data for RSA signing") + hash := crypto.SHA256 + + privateKey := "./rsa_private.pem" + publicKey := "./rsa_public.pem" + + signature, err := RsaSign(hash, data, privateKey) + if err != nil { + return + } + + err = RsaVerifySign(hash, data, signature, publicKey) + if err != nil { + return + } +} +``` + +### RsaVerifySign + +Verifies the signature of the data with RSA algorithm.
+ +Signature: + +```go +func RsaVerifySign(hash crypto.Hash, data, signature []byte, pubKeyFileName string) error +``` + +Example:[Run](https://go.dev/play/p/qhsbf8BJ6Mf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/cryptor" +) + +func main() { + data := []byte("This is a test data for RSA signing") + hash := crypto.SHA256 + + privateKey := "./rsa_private.pem" + publicKey := "./rsa_public.pem" + + signature, err := RsaSign(hash, data, privateKey) + if err != nil { + return + } + + err = RsaVerifySign(hash, data, signature, publicKey) + if err != nil { + return + } +} +``` diff --git a/docs/en/api/packages/datastructure/copyonwritelist.md b/docs/en/api/packages/datastructure/copyonwritelist.md new file mode 100644 index 00000000..0419fb74 --- /dev/null +++ b/docs/en/api/packages/datastructure/copyonwritelist.md @@ -0,0 +1,525 @@ +# CopyOnWriteList + +CopyOnWriteList is a thread-safe list implementation that uses go slicing as its base. When writing, a new slice is copied and assigned to the original slice when writing is complete. When reading, the original slice is read directly. + +## 源码 + +- [https://github.com/duke-git/lancet/blob/main/datastructure/list/copyonwritelist.go](https://github.com/duke-git/lancet/blob/main /datastructure/list/copyonwritelist.go) + +## 用法 + +```go +import ( + "github.com/duke-git/lancet/datastructure/list" +) + +``` + + + +## 目录 + +- [NewCopyOnWriteList](#NewCopyOnWriteList) +- [Size](#Size) +- [Get](#Get) +- [Set](#Set) +- [Remove](#Remove) +- [IndexOf](#IndexOf) +- [LastIndexOf](#LastIndexOf) +- [IndexOfFunc](#IndexOfFunc) +- [LastIndexOfFunc](#LastIndexOfFunc) +- [IsEmpty](#IsEmpty) +- [Contain](#Contain) +- [ValueOf](#ValueOf) +- [Add](#Add) +- [AddAll](#AddAll) +- [AddByIndex](#AddByIndex) +- [DeleteAt](#DeleteAt) +- [DeleteIf](#DeleteIf) +- [DeleteBy](#DeleteBy) +- [DeleteRange](#DeleteRange) +- [Equal](#Equal) + +## Documentation + +### NewCopyOnWriteList + +Returns a CopyOnWriteList with empty slices. + +```go +type CopyOnWriteList[T any] struct { + data []T + lock sync. +} + +func NewCopyOnWriteList() *CopyOnWriteList + +``` + +#### Example + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l) +} +``` + +### Size + +Returns the length of the CopyOnWriteList. + +```go +func (l *CopyOnWriteList[T]) Size() int +``` + +#### Example + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.Size()) +} + +``` + +### Get + +Returns the element at the specified position in the list + +```go +func (c *CopyOnWriteList[T]) Get(index int) *T +``` + +#### Example + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.Get(2)) +} + +``` + +### Set + +Replaces the element at the specified position in this list with the specified element. + +```go +func (c *CopyOnWriteList[T]) Set(index int, e T) (oldValue *T, ok bool) +``` + +#### Example + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.Set(2, 4)) +} + +``` + +### Remove + +### IndexOf + +Returns the index of the value in the list, or -1 if not found. + +```go +func (c *CopyOnWriteList[T]) IndexOf(e T) int +``` + +#### Example + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.IndexOf(1)) +} + +``` + +### LastIndexOf + +Returns the index of the last occurrence of the specified element in this list, or -1 if this list does not contain that element. + +```go +func (c *CopyOnWriteList[T]) LastIndexOf(e T) int +``` + +#### Example + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3,1}) + fmt.Println(l.LastIndexOf(1)) +} + +``` + + +### IndexOfFunc +IndexOfFunc returns the first index satisfying the functional predicate f(v) bool. if not found return -1.
+ +Signature: + +```go +func (l *CopyOnWriteList[T]) IndexOfFunc(f func(T) bool) int +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1, 2, 3}) + + fmt.Println(l.IndexOfFunc(func(a int) bool { return a == 1 })) //0 + fmt.Println(l.IndexOfFunc(func(a int) bool { return a == 0 })) //-1 +} +``` + +### LastIndexOfFunc +LastIndexOfFunc returns the index of the last occurrence of the value in this list satisfying the functional predicate f(T) bool. if not found return -1.
+ +Signature: + +```go +func (l *CopyOnWriteList[T]) LastIndexOfFunc(f func(T) bool) int +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1, 2, 3, 1}) + + fmt.Println(l.LastIndexOfFunc(func(a int) bool { return a == 1 })) // 3 + fmt.Println(l.LastIndexOfFunc(func(a int) bool { return a == 0 })) //-1 +} +``` + +### IsEmpty + +Returns true if this list does not contain any elements. + +```go +func (c *CopyOnWriteList[T]) IsEmpty() bool +``` + +#### Example + +```go +package main + +import ( +"fmt" +"github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{}) + fmt.Println(l.IsEmpty()) +} +``` + +### Contain + +Determines if a CopyOnWriteList contains an element. + +```go +func (c *CopyOnWriteList[T]) Contain(e T) bool +``` + +#### Example + +```go +package main + +import ( +"fmt" +"github.com/duke-git/lancet/datastructure/list" +) + +func main() { +l := list.NewCopyOnWriteList([]int{1,2,3}) +fmt.Println(l.Contain(1)) +} +``` + +### ValueOf + +Returns a pointer to the value at the index in the list + +```go +func (c *CopyOnWriteList[T]) ValueOf(index int) []T +``` + +#### Example + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.ValueOf(2)) +} + +``` + +### Add + +Appends the specified element to the end of the list. + +```go +func (c *CopyOnWriteList[T]) Add(e T) bool +``` + +#### Example + +```go + +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + l.Add(4) + fmt.Println(l.getList()) +} + +``` + +### AddAll + +Appends all the elements of the specified collection to the end of this list + +```go +func (c *CopyOnWriteList[T]) AddAll(e []T) bool +``` + +#### Example + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + l.AddAll([]int{4,5,6}) + fmt.Println(l.getList()) +} + +``` + +### AddByIndex + +Inserts the specified element into the list at the specified position. + +```go +func (c *CopyOnWriteList[T]) AddByIndex(index int, e T) bool +``` + +#### Example + +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.AddByIndex(2, 6) + fmt.Println(l.getList()) +} + +``` + +### DeleteAt + +Removes the element at the specified position in this list. + +```go +func (c *CopyOnWriteList[T]) DeleteAt(index int) (oldValue *T, ok bool) +``` + +#### Example + +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.DeleteAt(2) + fmt.Println(l.getList()) +} +``` + +### DeleteIf + +Removes the first occurrence of the specified element from this list (if it exists). + +```go +func (c *CopyOnWriteList[T]) DeleteIf(func(T) bool) (oldValue *T, ok bool) +``` + +#### Example + +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.DeleteIf(func(i int) bool { + return i == 2 + }) + fmt.Println(l.getList()) +} +``` + +### DeleteBy + +Deletes the first occurrence of the specified element from this list (if it exists). + +```go +func (c *CopyOnWriteList[T]) DeleteBy(e T) (*T bool) +``` + +#### Example + +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.DeleteBy(2) + fmt.Println(l.getList()) +} +``` + +### DeleteRange + +Deletes all elements from this list with indexes between fromIndex (included) and toIndex (not included). +(leftCloseRightOpen) + +```go +func (c *CopyOnWriteList[T]) DeleteRange(start int, end int) +``` + +#### Example + +```go +package main +import ( +"fmt" +"github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3,4,5,6,7,8,9}) + list.DeleteRange(2, 5) + fmt.Println(l.getList()) +} +``` + +### Equal + +Returns true if the specified object is equal to this list + +```go +func (c *CopyOnWriteList[T]) Equal(e []T) bool +``` + +#### Example + +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3,4,5,6,7,8,9}) + fmt.Println(l.Equal([]int{1,2,3,4,5,6,7,8,9})) +} +``` diff --git a/docs/en/api/packages/datastructure/hashmap.md b/docs/en/api/packages/datastructure/hashmap.md new file mode 100644 index 00000000..59d0a4ac --- /dev/null +++ b/docs/en/api/packages/datastructure/hashmap.md @@ -0,0 +1,388 @@ +# HashMap + +HashMap is a key value map data structure. + + + +## Source + +- [https://github.com/duke-git/lancet/blob/main/datastructure/hashmap/hashmap.go](https://github.com/duke-git/lancet/blob/main/datastructure/hashmap/hashmap.go) + + + +## Usage + +```go +import ( + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) +``` + + + + +## Index + +- [NewHashMap](#NewHashMap) +- [NewHashMapWithCapacity](#NewHashMapWithCapacity) +- [Get](#Get) +- [Put](#Put) +- [Delete](#Delete) +- [Contains](#Contains) +- [Iterate](#Iterate) +- [Keys](#Keys) +- [Values](#Values) +- [FilterByValue](#FilterByValue) + + + +## Documentation + +### NewHashMap + +Make a HashMap instance with default capacity is 1 << 10.
+ +Signature: + +```go +func NewHashMap() *HashMap +``` + +Example: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + fmt.Println(hm) +} +``` + +### NewHashMap + +Make a HashMap instance with given size and capacity.
+ +Signature: + +```go +func NewHashMapWithCapacity(size, capacity uint64) *HashMap +``` + +Example: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMapWithCapacity(uint64(100), uint64(1000)) + fmt.Println(hm) +} +``` + +### Get + +Get the value of given key in hashmap
+ +Signature: + +```go +func (hm *HashMap) Get(key any) any +``` + +Example: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + val := hm.Get("a") + + fmt.Println(val) //nil +} +``` + +### Put + +Put new key value in hashmap, then return value
+ +Signature: + +```go +func (hm *HashMap) Put(key any, value any) any +``` + +Example: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + hm.Put("a", 1) + + val := hm.Get("a") + fmt.Println(val) //1 +} +``` + + + +### Delete + +Delete key-value item by given key in hashmap.
+ +Signature: + +```go +func (hm *HashMap) Delete(key any) +``` + +Example: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + hm.Put("a", 1) + val := hm.Get("a") + fmt.Println(val) //1 + + hm.Delete("a") + val = hm.Get("a") + fmt.Println(val) //nil +} +``` + + + +### Contains + +Checks if given key is in hashmap or not.
+ +Signature: + +```go +func (hm *HashMap) Contains(key any) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + hm.Put("a", 1) + + fmt.Println(hm.Contains("a")) //true + fmt.Println(hm.Contains("b")) //false +} +``` + + + +### Iterate + +Executes iteratee funcation for every key and value pair of hashmap.
+ +Signature: + +```go +func (hm *HashMap) Iterate(iteratee func(key, value any)) +``` + +Example: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + hm.Put("a", 1) + hm.Put("b", 2) + hm.Put("c", 3) + + hm.Iterate(func(key, value any) { + fmt.Println(key) + fmt.Println(value) + }) +} +``` + + + +### Keys + +Return a slice of the hashmap's keys (random order).
+ +Signature: + +```go +func (hm *HashMap) Keys() []any +``` + +Example: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + hm.Put("a", 1) + hm.Put("b", 2) + hm.Put("c", 3) + + keys := hm.Keys() + fmt.Println(keys) //[]interface{"a", "b", "c"} +} +``` + + +### Values + +Return a slice of the hashmap's values (random order).
+ +Signature: + +```go +func (hm *HashMap) Values() []any +``` + +Example: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := heap.NewHashMap() + hm.Put("a", 1) + hm.Put("b", 2) + hm.Put("c", 3) + + values := hm.Values() + fmt.Println(values) //[]interface{2, 1, 3} +} +``` + +### FilterByValue + +Returns a filtered HashMap.
+ +Signature: + +```go +func (hm *HashMap) FilterByValue(perdicate func(value any) bool) *HashMap +``` + +Example: + +```go +package main + +import ( + "fmt" + hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap" +) + +func main() { + hm := hashmap.NewHashMap() + + hm.Put("a", 1) + hm.Put("b", 2) + hm.Put("c", 3) + hm.Put("d", 4) + hm.Put("e", 5) + hm.Put("f", 6) + + filteredHM := hm.FilterByValue(func(value any) bool { + return value.(int) == 1 || value.(int) == 3 + }) + + fmt.Println(filteredHM.Size()) //2 +} +``` + + + +### ToInterface + +Converts reflect value to its interface type.
+ +Signature: + +```go +func ToInterface(v reflect.Value) (value interface{}, ok bool) +``` + +Example:[Run](https://go.dev/play/p/syqw0-WG7Xd) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/convertor" +) + +func main() { + val := reflect.ValueOf("abc") + iVal, ok := convertor.ToInterface(val) + + fmt.Printf("%T\n", iVal) + fmt.Printf("%v\n", iVal) + fmt.Println(ok) + + // Output: + // string + // abc + // true +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/datastructure/heap.md b/docs/en/api/packages/datastructure/heap.md new file mode 100644 index 00000000..863bfc33 --- /dev/null +++ b/docs/en/api/packages/datastructure/heap.md @@ -0,0 +1,364 @@ +# Heap +Heap is a binary heap tree implemented by slice. + + + +## Source + +- [https://github.com/duke-git/lancet/blob/main/datastructure/heap/maxheap.go](https://github.com/duke-git/lancet/blob/main/datastructure/heap/maxheap.go) + + + + +## Usage +```go +import ( + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) +``` + + + +## Index + +- [MaxHeap](#MaxHeap) +- [Push](#Push) +- [Pop](#Pop) +- [Peek](#Peek) +- [Data](#Data) +- [Size](#Size) + + + + +## Documentation + +### 1. MaxHeap +MaxHeap is a binary heap tree implemented by slice, The key of the root node is both greater than or equal to the key value of the left subtree and greater than or equal to the key value of the right subtree. + +### NewMaxHeap +Return a NewMaxHeap pointer instance.
+ +Signature: + +```go +type MaxHeap[T any] struct { + data []T + comparator constraints.Comparator +} +func NewMaxHeap[T any](comparator constraints.Comparator) *MaxHeap[T] +``` +Example: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + fmt.Println(maxHeap) +} +``` + + + + +### Push +Push value into the heap
+ +Signature: + +```go +func (h *MaxHeap[T]) Push(value T) +``` +Example: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + values := []int{6, 5, 2, 4, 7, 10, 12, 1, 3, 8, 9, 11} + + for _, v := range values { + maxHeap.Push(v) + } + + fmt.Println(maxHeap.Data()) //[]int{12, 9, 11, 4, 8, 10, 7, 1, 3, 5, 6, 2} +} +``` + + + + +### Pop +Pop return the largest value, and remove it from the heap if heap is empty, return zero value and fasle
+ +Signature: + +```go +func (h *MaxHeap[T]) Pop() (T, bool) +``` +Example: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + values := []int{6, 5, 2, 4, 7, 10, 12, 1, 3, 8, 9, 11} + + for _, v := range values { + maxHeap.Push(v) + } + val, ok := maxHeap.Pop() + + fmt.Println(val) //12 + fmt.Println(ok) //true +} +``` + + + +### Peek +Return the largest element from the heap without removing it, if heap is empty, it returns zero value and false.
+ +Signature: + +```go +func (h *MaxHeap[T]) Peek() (T, bool) +``` +Example: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + values := []int{6, 5, 2, 4, 7, 10, 12, 1, 3, 8, 9, 11} + + for _, v := range values { + maxHeap.Push(v) + } + val, ok := maxHeap.Peek() + + fmt.Println(val) //12 + fmt.Println(maxHeap.Size()) //12 +} +``` + + + +### Data +Return all element of the heap
+ +Signature: + +```go +func (h *MaxHeap[T]) Data() []T +``` +Example: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + values := []int{6, 5, 2, 4, 7, 10, 12, 1, 3, 8, 9, 11} + + for _, v := range values { + maxHeap.Push(v) + } + + fmt.Println(maxHeap.Data()) //[]int{12, 9, 11, 4, 8, 10, 7, 1, 3, 5, 6, 2} +} +``` + + +### Size +Return the number of elements in the heap
+ +Signature: + +```go +func (h *MaxHeap[T]) Size() int +``` +Example: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + values := []int{6, 5, 2} + + for _, v := range values { + maxHeap.Push(v) + } + + fmt.Println(maxHeap.Size()) //3 +} +``` + + + +### PrintStructure +Print the tree structure of the heap
+ +Signature: + +```go +func (h *MaxHeap[T]) PrintStructure() +``` +Example: + +```go +package main + +import ( + "fmt" + heap "github.com/duke-git/lancet/v2/datastructure/heap" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + maxHeap := heap.NewMaxHeap[int](&intComparator{}) + values := []int{6, 5, 2, 4, 7, 10, 12, 1, 3, 8, 9, 11} + + for _, v := range values { + maxHeap.Push(v) + } + + fmt.Println(maxHeap.PrintStructure()) +// 12 +// 9 11 +// 4 8 10 7 +// 1 3 5 6 2 +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/datastructure/link.md b/docs/en/api/packages/datastructure/link.md new file mode 100644 index 00000000..174ccff9 --- /dev/null +++ b/docs/en/api/packages/datastructure/link.md @@ -0,0 +1,1018 @@ +# Linklist +Linklist a linked list, whose node has a value and a pointer points to next node of the link. + + + +## Source + +- [https://github.com/duke-git/lancet/blob/main/datastructure/link/singlylink.go](https://github.com/duke-git/lancet/blob/main/datastructure/link/singlylink.go) +- [https://github.com/duke-git/lancet/blob/main/datastructure/link/doublylink.go](https://github.com/duke-git/lancet/blob/main/datastructure/link/doublylink.go) + + + + +## Usage +```go +import ( + link "github.com/duke-git/lancet/v2/datastructure/link" +) +``` + + + +## Index + +### 1. SinglyLink + +- [NewSinglyLink](#NewSinglyLink) +- [Values](#SinglyLink_Values) +- [InsertAt](#SinglyLink_InsertAt) +- [InsertAtHead](#SinglyLink_InsertAtHead) +- [InsertAtTail](#SinglyLink_InsertAtTail) +- [DeleteAt](#SinglyLink_DeleteAt) +- [DeleteAtHead](#SinglyLink_DeleteAtHead) +- [DeleteAtTail](#SinglyLink_DeleteAtTail) +- [DeleteValue](#SinglyLink_DeleteValue) +- [Reverse](#SinglyLink_Reverse) +- [GetMiddleNode](#SinglyLink_GetMiddleNode) +- [Size](#SinglyLink_Size) +- [IsEmpty](#SinglyLink_IsEmpty) +- [Clear](#SinglyLink_Clear) +- [Print](#SinglyLink_Print) + +### 2. DoublyLink + +- [NewDoublyLink](#NewDoublyLink) +- [Values](#DoublyLink_Values) +- [InsertAt](#DoublyLink_InsertAt) +- [InsertAtHead](#DoublyLink_InsertAtHead) +- [InsertAtTail](#DoublyLink_InsertAtTail) +- [DeleteAt](#DoublyLink_DeleteAt) +- [DeleteAtHead](#DoublyLink_DeleteAtHead) +- [DeleteAtTail](#DoublyLink_DeleteAtTail) +- [Reverse](#DoublyLink_Reverse) +- [GetMiddleNode](#DoublyLink_GetMiddleNode) +- [Size](#DoublyLink_Size) +- [IsEmpty](#DoublyLink_IsEmpty) +- [Clear](#DoublyLink_Clear) +- [Print](#DoublyLink_Print) + + + + +## Documentation + +### 1. SinglyLink +SinglyLink a linked list, whose node has a value and a pointer points to next node of the link. + +### NewSinglyLink +Return a singly link(SinglyLink) instance
+ +Signature: + +```go +type LinkNode[T any] struct { + Value T + Next *LinkNode[T] +} +type SinglyLink[T any] struct { + Head *datastructure.LinkNode[T] + length int +} +func NewSinglyLink[T any]() *SinglyLink[T] +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + fmt.Println(lk) +} +``` + + + +### Values +Return a slice of all node value in singly linklist
+ +Signature: + +```go +func (link *SinglyLink[T]) Values() []T +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.Values()) //[]int{1, 2, 3} +} +``` + + + + +### InsertAt +Insert value into singly linklist at index, param `index` should between [0, len(SinglyLink)], if index do not meet the conditions, do nothing
+ +Signature: + +```go +func (link *SinglyLink[T]) InsertAt(index int, value T) +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAt(1, 1) //do nothing + + lk.InsertAt(0, 1) + lk.InsertAt(1, 2) + lk.InsertAt(2, 3) + lk.InsertAt(2, 4) + + fmt.Println(lk.Values()) //[]int{1, 2, 4, 3} +} +``` + + + + +### InsertAtHead +Insert value into singly linklist at head(first) index
+ +Signature: + +```go +func (link *SinglyLink[T]) InsertAtHead(value T) +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtHead(1) + lk.InsertAtHead(2) + lk.InsertAtHead(3) + + fmt.Println(lk.Values()) //[]int{3, 2, 1} +} +``` + + + + +### InsertAtTail +Insert value into singly linklist at tail(last) index
+ +Signature: + +```go +func (link *SinglyLink[T]) InsertAtTail(value T) +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.Values()) //[]int{1, 2, 3} +} +``` + + + +### DeleteAt +Delete value at specific index, param `index` should be [0, len(SinglyLink)-1]
+ +Signature: + +```go +func (link *SinglyLink[T]) DeleteAt(index int) +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + lk.InsertAtTail(4) + + lk.DeleteAt(3) + + fmt.Println(lk.Values()) //[]int{1, 2, 3} +} +``` + + + +### DeleteAtHead +Delete value in singly linklist at first index
+ +Signature: + +```go +func (link *SinglyLink[T]) DeleteAtHead() +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + lk.InsertAtTail(4) + + lk.DeleteAtHead() + + fmt.Println(lk.Values()) //[]int{2, 3, 4} +} +``` + + + + +### DeleteAtTail +Delete value in singly linklist at last index
+ +Signature: + +```go +func (link *SinglyLink[T]) DeleteAtTail() +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.DeleteAtTail() + + fmt.Println(lk.Values()) //[]int{1, 2} +} +``` + + + +### DeleteValue +Delete all `value` in singly linklist
+ +Signature: + +```go +func (link *SinglyLink[T]) DeleteValue(value T) +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.DeleteValue(2) + fmt.Println(lk.Values()) //[]int{1, 3} +} +``` + + + + +### Reverse +Reverse all nodes order in linkist
+ +Signature: + +```go +func (link *SinglyLink[T]) Reverse() +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.Reverse() + fmt.Println(lk.Values()) //[]int{3, 2, 1} +} +``` + + + +### GetMiddleNode +Get the node at middle index of linkist
+ +Signature: + +```go +func (link *SinglyLink[T]) GetMiddleNode() *datastructure.LinkNode[T] +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + midNode := lk.GetMiddleNode() + fmt.Println(midNode.Value) //2 +} +``` + + + +### Size +Get the number of nodes in linklist
+ +Signature: + +```go +func (link *SinglyLink[T]) Size() int +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.Size()) //3 +} +``` + + + +### IsEmpty +Checks if linklist is empty or not
+ +Signature: + +```go +func (link *SinglyLink[T]) IsEmpty() bool +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + fmt.Println(lk.IsEmpty()) //true + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.IsEmpty()) //false +} +``` + + + +### Clear +Clear all nodes in the linklist, make it empty
+ +Signature: + +```go +func (link *SinglyLink[T]) Clear() +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.Clear() + + fmt.Println(lk.Values()) // +} +``` + + + +### Print +Print all nodes info of linklist
+ +Signature: + +```go +func (link *SinglyLink[T]) Clear() +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewSinglyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.Print() //[ &{Value:1 Pre:Return a doubly link instance
+ +Signature: + +```go +type LinkNode[T any] struct { + Value T + Pre *LinkNode[T] + Next *LinkNode[T] +} +type DoublyLink[T any] struct { + Head *datastructure.LinkNode[T] + length int +} +func NewDoublyLink[T any]() *DoublyLink[T] +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + fmt.Println(lk) +} +``` + + + +### Values +Return a slice of all node value in doubly linklist
+ +Signature: + +```go +func (link *DoublyLink[T]) Values() []T +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.Values()) //[]int{1, 2, 3} +} +``` + + + + +### InsertAt +Insert value into doubly linklist at index, param `index` should between [0, len(DoublyLink)], if index do not meet the conditions, do nothing
+ +Signature: + +```go +func (link *DoublyLink[T]) InsertAt(index int, value T) +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAt(1, 1) //do nothing + + lk.InsertAt(0, 1) + lk.InsertAt(1, 2) + lk.InsertAt(2, 3) + lk.InsertAt(2, 4) + + fmt.Println(lk.Values()) //[]int{1, 2, 4, 3} +} +``` + + + + +### InsertAtHead +Insert value into doubly linklist at head(first) index
+ +Signature: + +```go +func (link *DoublyLink[T]) InsertAtHead(value T) +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtHead(1) + lk.InsertAtHead(2) + lk.InsertAtHead(3) + + fmt.Println(lk.Values()) //[]int{3, 2, 1} +} +``` + + + + +### InsertAtTail +Insert value into doubly linklist at tail(last) index
+ +Signature: + +```go +func (link *DoublyLink[T]) InsertAtTail(value T) +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.Values()) //[]int{1, 2, 3} +} +``` + + + +### DeleteAt +Delete value at specific index, param `index` should be [0, len(DoublyLink)-1]
+ +Signature: + +```go +func (link *DoublyLink[T]) DeleteAt(index int) +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + lk.InsertAtTail(4) + + lk.DeleteAt(3) + + fmt.Println(lk.Values()) //[]int{1, 2, 3} +} +``` + + + +### DeleteAtHead +Delete value in doubly linklist at first index
+ +Signature: + +```go +func (link *DoublyLink[T]) DeleteAtHead() +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + lk.InsertAtTail(4) + + lk.DeleteAtHead() + + fmt.Println(lk.Values()) //[]int{2, 3, 4} +} +``` + + + + +### DeleteAtTail +Delete value in doubly linklist at last index
+ +Signature: + +```go +func (link *DoublyLink[T]) DeleteAtTail() error +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + err := lk.DeleteAtTail() + + fmt.Println(err) //nil + fmt.Println(lk.Values()) //[]int{1, 2} +} +``` + + + + +### Reverse +Reverse all nodes order in linkist
+ +Signature: + +```go +func (link *DoublyLink[T]) Reverse() +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.Reverse() + fmt.Println(lk.Values()) //[]int{3, 2, 1} +} +``` + + + +### GetMiddleNode +Get the node at middle index of linkist
+ +Signature: + +```go +func (link *DoublyLink[T]) GetMiddleNode() *datastructure.LinkNode[T] +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + midNode := lk.GetMiddleNode() + fmt.Println(midNode.Value) //2 +} +``` + + + +### Size +Get the number of nodes in linklist
+ +Signature: + +```go +func (link *DoublyLink[T]) Size() int +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.Size()) //3 +} +``` + + + +### IsEmpty +Checks if linklist is empty or not
+ +Signature: + +```go +func (link *DoublyLink[T]) IsEmpty() bool +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + fmt.Println(lk.IsEmpty()) //true + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + fmt.Println(lk.IsEmpty()) //false +} +``` + + + +### Clear +Clear all nodes in the linklist, make it empty
+ +Signature: + +```go +func (link *DoublyLink[T]) Clear() +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.Clear() + + fmt.Println(lk.Values()) // +} +``` + + + +### Print +Print all nodes info of linklist
+ +Signature: + +```go +func (link *DoublyLink[T]) Clear() +``` +Example: + +```go +package main + +import ( + "fmt" + link "github.com/duke-git/lancet/v2/datastructure/link" +) + +func main() { + lk := link.NewDoublyLink[int]() + + lk.InsertAtTail(1) + lk.InsertAtTail(2) + lk.InsertAtTail(3) + + lk.Print() // +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/datastructure/list.md b/docs/en/api/packages/datastructure/list.md new file mode 100644 index 00000000..6f6d9b8f --- /dev/null +++ b/docs/en/api/packages/datastructure/list.md @@ -0,0 +1,1118 @@ +# List +List is a linear table, implemented with slice. + + + +## Source + +- [https://github.com/duke-git/lancet/blob/main/datastructure/list/list.go](https://github.com/duke-git/lancet/blob/main/datastructure/list/list.go) + + + + +## Usage +```go +import ( + list "github.com/duke-git/lancet/v2/datastructure/list" +) +``` + + + +## Index + +- [NewList](#NewList) +- [Contain](#Contain) +- [Data](#Data) +- [ValueOf](#ValueOf) +- [IndexOf](#IndexOf) +- [LastIndexOf](#LastIndexOf) +- [IndexOfFunc](#IndexOfFunc) +- [LastIndexOfFunc](#LastIndexOfFunc) +- [Push](#Push) +- [PopFirst](#PopFirst) +- [PopLast](#PopLast) +- [DeleteAt](#DeleteAt) +- [InsertAt](#InsertAt) +- [UpdateAt](#UpdateAt) +- [Equal](#Equal) +- [IsEmpty](#IsEmpty) +- [Clear](#Clear) +- [Clone](#Clone) +- [Merge](#Merge) +- [Size](#Size) +- [Cap](#Cap) +- [Swap](#Swap) +- [Reverse](#Reverse) +- [Unique](#Unique) +- [Union](#Union) +- [Intersection](#Intersection) +- [Difference](#Difference) +- [SymmetricDifference](#SymmetricDifference) +- [RetainAll](#RetainAll) +- [DeleteAll](#DeleteAll) +- [ForEach](#ForEach) +- [Iterator](#Iterator) +- [ListToMap](#ListToMap) +- [SubList](#SubList) +- [DeleteIf](#DeleteIf) + + + +## Documentation + +### NewList +List is a linear table, implemented with slice. +NewList function return a list pointer
+ +Signature: + +```go +type List[T any] struct { + data []T +} +func NewList[T any](data []T) *List[T] +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + fmt.Println(li) +} +``` + + + +### Contain +Check if the value in the list or not
+ +Signature: + +```go +func (l *List[T]) Contain(value T) bool +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + + fmt.Println(li.Contain(1)) //true + fmt.Println(li.Contain(0)) //false +} +``` + + + + +### Data +Return slice of list data
+ +Signature: + +```go +func (l *List[T]) Data() []T +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + data := li.Data() + + fmt.Println(data) //[]int{1, 2, 3} +} +``` + + + + +### ValueOf +Return the value pointer at index in list
+ +Signature: + +```go +func (l *List[T]) ValueOf(index int) (*T, bool) +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + v, ok := li.ValueOf(0) + + fmt.Println(*v) //1 + fmt.Println(ok) //true +} +``` + + + + +### IndexOf +Returns the index of value in the list. if not found return -1
+ +Signature: + +```go +func (l *List[T]) IndexOf(value T) int +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + + fmt.Println(li.IndexOf(1)) //0 + fmt.Println(li.IndexOf(0)) //-1 +} +``` + +### LastIndexOf +Returns the index of the last occurrence of the value in this list if not found return -1
+ +Signature: + +```go +func (l *List[T]) LastIndexOf(value T) int +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3, 1}) + + fmt.Println(li.LastIndexOf(1)) // 3 + fmt.Println(li.LastIndexOf(0)) //-1 +} +``` + +### IndexOfFunc +IndexOfFunc returns the first index satisfying f(v). if not found return -1
+ +Signature: + +```go +func (l *List[T]) IndexOfFunc(f func(T) bool) int +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + + fmt.Println(li.IndexOfFunc(func(a int) bool { return a == 1 })) //0 + fmt.Println(li.IndexOfFunc(func(a int) bool { return a == 0 })) //-1 +} +``` + +### LastIndexOfFunc +LastIndexOfFunc returns the index of the last occurrence of the value in this list satisfying f(data[i]). if not found return -1
+ +Signature: + +```go +func (l *List[T]) LastIndexOfFunc(f func(T) bool) int +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3, 1}) + + fmt.Println(li.LastIndexOfFunc(func(a int) bool { return a == 1 })) // 3 + fmt.Println(li.LastIndexOfFunc(func(a int) bool { return a == 0 })) //-1 +} +``` + + + +### Push +Append value to the list
+ +Signature: + +```go +func (l *List[T]) Push(value T) +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + li.Push(4) + + fmt.Println(li.Data()) //[]int{1, 2, 3, 4} +} +``` + + + + +### PopFirst +Delete the first value of list and return it
+ +Signature: + +```go +func (l *List[T]) PopFirst() (*T, bool) +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + v, ok := li.PopFirst() + + fmt.Println(*v) //1 + fmt.Println(ok) //true + fmt.Println(li.Data()) //2, 3 +} +``` + + + + + +### PopFirst +Delete the last value of list and return it
+ +Signature: + +```go +func (l *List[T]) PopLast() (*T, bool) +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + v, ok := li.PopLast() + + fmt.Println(*v) //3 + fmt.Println(ok) //true + fmt.Println(li.Data()) //1, 2 +} +``` + + + + +### DeleteAt +Delete the value of list at index, if index is not between 0 and length of list data, do nothing
+ +Signature: + +```go +func (l *List[T]) DeleteAt(index int) +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3, 4}) + + li.DeleteAt(-1) + fmt.Println(li.Data()) //1,2,3,4 + + li.DeleteAt(4) + fmt.Println(li.Data()) //1,2,3,4 + + li.DeleteAt(0) + fmt.Println(li.Data()) //2,3,4 + + li.DeleteAt(2) + fmt.Println(li.Data()) //2,3 +} +``` + + + + +### InsertAt +Insert value into list at index, if index is not between 0 and length of list data, do nothing
+ +Signature: + +```go +func (l *List[T]) InsertAt(index int, value T) +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + + li.InsertAt(-1, 0) + fmt.Println(li.Data()) //1,2,3 + + li.InsertAt(4, 0) + fmt.Println(li.Data()) //1,2,3 + + li.InsertAt(3, 4) + fmt.Println(li.Data()) //1,2,3,4 + + // li.InsertAt(2, 4) + // fmt.Println(li.Data()) //1,2,4,3 +} +``` + + + +### UpdateAt +Update value of list at index, index shoud between 0 and list size - 1
+ +Signature: + +```go +func (l *List[T]) UpdateAt(index int, value T) +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + + li.UpdateAt(-1, 0) + fmt.Println(li.Data()) //1,2,3 + + li.UpdateAt(2, 4) + fmt.Println(li.Data()) //1,2,4 + + li.UpdateAt(3, 5) + fmt.Println(li.Data()) //1,2,4 +} +``` + + +### Equal +Compare a list to another list, use reflect.DeepEqual on every element
+ +Signature: + +```go +func (l *List[T]) Equal(other *List[T]) bool +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li1 := list.NewList([]int{1, 2, 3, 4}) + li2 := list.NewList([]int{1, 2, 3, 4}) + li3 := list.NewList([]int{1, 2, 3}) + + fmt.Println(li1.Equal(li2)) //true + fmt.Println(li1.Equal(li3)) //false +} +``` + + + +### IsEmpty +Check if a list is empty or not
+ +Signature: + +```go +func (l *List[T]) IsEmpty() bool +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li1 := list.NewList([]int{1, 2, 3}) + li2 := list.NewList([]int{}) + + fmt.Println(li1.IsEmpty()) //false + fmt.Println(li2.IsEmpty()) //true +} +``` + + + + +### Clear +Clear the data of list
+ +Signature: + +```go +func (l *List[T]) Clear() +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + li.Clear() + + fmt.Println(li.Data()) // empty +} +``` + + + +### Clone +Return a copy of list
+ +Signature: + +```go +func (l *List[T]) Clone() *List[T] +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3}) + cloneList := li.Clone() + + fmt.Println(cloneList.Data()) // 1,2,3 +} +``` + + + + +### Merge +Merge two list, return new list, don't change original list
+ +Signature: + +```go +func (l *List[T]) Merge(other *List[T]) *List[T] +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li1 := list.NewList([]int{1, 2, 3, 4}) + li2 := list.NewList([]int{4, 5, 6}) + li3 := li1.Merge(li2) + + fmt.Println(li3.Data()) //1, 2, 3, 4, 4, 5, 6 +} +``` + + + +### Size +Return number of list data items
+ +Signature: + +```go +func (l *List[T]) Size() int +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3, 4}) + + fmt.Println(li.Size()) //4 +} +``` + + + + +### Cap +Cap return cap of the inner data
+ +Signature: + +```go +func (l *List[T]) Cap() int +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + data := make([]int, 0, 100) + + li := list.NewList(data) + + fmt.Println(li.Cap()) // 100 +} +``` + + + + +### Swap +Swap the value at two index in list
+ +Signature: + +```go +func (l *List[T]) Swap(i, j int) +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3, 4}) + li.Swap(0, 3) + + fmt.Println(li.Data()) //4, 2, 3, 1 +} +``` + + + + +### Reverse +Reverse the data item order of list
+ +Signature: + +```go +func (l *List[T]) Reverse() +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 3, 4}) + li.Reverse() + + fmt.Println(li.Data()) //4, 3, 2, 1 +} +``` + + + + +### Unique +Remove duplicate items in list
+ +Signature: + +```go +func (l *List[T]) Unique() +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li := list.NewList([]int{1, 2, 2, 3, 4}) + li.Unique() + + fmt.Println(li.Data()) //1,2,3,4 +} +``` + + + + +### Union +Creates a new list contain all elements in list l and other, remove duplicate element
+ +Signature: + +```go +func (l *List[T]) Union(other *List[T]) *List[T] +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li1 := list.NewList([]int{1, 2, 3, 4}) + li2 := list.NewList([]int{4, 5, 6}) + li3 := li1.Union(li2) + + fmt.Println(li3.Data()) //1,2,3,4,5,6 +} +``` + + + + +### Intersection +Creates a new list whose element both be contained in list l and other
+ +Signature: + +```go +func (l *List[T]) Intersection(other *List[T]) *List[T] +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + li1 := list.NewList([]int{1, 2, 3, 4}) + li2 := list.NewList([]int{4, 5, 6}) + li3 := li1.Intersection(li2) + + fmt.Println(li3.Data()) //4 +} +``` + + + +### Difference +Return a list whose element in the original list, not in the given list.
+ +Signature: + +```go +func (l *List[T]) Difference(other *List[T]) *List[T] +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list1 := NewList([]int{1, 2, 3}) + list2 := NewList([]int{1, 2, 4}) + + list3 := list1.Intersection(list2) + + fmt.Println(list3.Data()) //3 +} +``` + + +### SymmetricDifference +Oppoiste operation of intersection function.
+ +Signature: + +```go +func (l *List[T]) SymmetricDifference(other *List[T]) *List[T] +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list1 := NewList([]int{1, 2, 3}) + list2 := NewList([]int{1, 2, 4}) + + list3 := list1.Intersection(list2) + + fmt.Println(list3.Data()) //3, 4 +} +``` + + +### RetainAll +Retains only the elements in this list that are contained in the given list.
+ +Signature: + +```go +func (l *List[T]) RetainAll(list *List[T]) bool +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list := NewList([]int{1, 2, 3, 4}) + list1 := NewList([]int{1, 2, 3, 4}) + list2 := NewList([]int{1, 2, 3, 4}) + + retain := NewList([]int{1, 2}) + retain1 := NewList([]int{2, 3}) + retain2 := NewList([]int{1, 2, 5}) + + list.RetainAll(retain) + list1.RetainAll(retain1) + list2.RetainAll(retain2) + + fmt.Println(list.Data()) //1, 2 + fmt.Println(list1.Data()) //2, 3 + fmt.Println(list2.Data()) //1, 2 +} +``` + + +### DeleteAll +Removes from this list all of its elements that are contained in the given list.
+ +Signature: + +```go +func (l *List[T]) DeleteAll(list *List[T]) bool +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list := NewList([]int{1, 2, 3, 4}) + list1 := NewList([]int{1, 2, 3, 4}) + list2 := NewList([]int{1, 2, 3, 4}) + + del := NewList([]int{1}) + del1 := NewList([]int{2, 3}) + del2 := NewList([]int{1, 2, 5}) + + list.DeleteAll(del) + list1.DeleteAll(del1) + list2.DeleteAll(del2) + + fmt.Println(list.Data()) //2,3,4 + fmt.Println(list1.Data()) //1,4 + fmt.Println(list2.Data()) //3,4 +} +``` + + +### ForEach +Performs the given action for each element of the list.
+ +Signature: + +```go +func (l *List[T]) ForEach(consumer func(T)) +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list := NewList([]int{1, 2, 3, 4}) + + result := make([]int, 0) + list.ForEach(func(i int) { + result = append(result, i) + }) + + fmt.Println(result.Data()) //1,2,3,4 +} +``` + + +### Iterator +Returns an iterator over the elements in this list in proper sequence.
+ +Signature: + +```go +func (l *List[T]) Iterator() iterator.Iterator[T] +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list := NewList([]int{1, 2, 3, 4}) + + iterator := list.Iterator() + + result := make([]int, 0) + for iterator.HasNext() { + item, _ := iterator.Next() + result = append(result, item) + } + + fmt.Println(result.Data()) //1,2,3,4 +} +``` + + +### ListToMap +Converts a list to a map based on iteratee function.
+ +Signature: + +```go +func ListToMap[T any, K comparable, V any](list *List[T], iteratee func(T) (K, V)) map[K]V +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + list := NewList([]int{1, 2, 3, 4}) + + result := ListToMap(list, func(n int) (int, bool) { + return n, n > 1 + }) + + fmt.Println(result) //map[int]bool{1: false, 2: true, 3: true, 4: true} +} +``` + +### SubList +SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.
+ +Signature: + +```go +func (l *List[T]) SubList(fromIndex, toIndex int) *List[T] +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + l := list.NewList([]int{1, 2, 3, 4, 5, 6}) + + fmt.Println(l.SubList(2, 5)) // []int{3, 4, 5} +} +``` + + + + +### DeleteIf +DeleteIf delete all satisfying f(data[i]), returns count of removed elements
+ +Signature: + +```go +func (l *List[T]) DeleteIf(f func(T) bool) int +``` +Example: + +```go +package main + +import ( + "fmt" + list "github.com/duke-git/lancet/v2/datastructure/list" +) + +func main() { + l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1}) + + fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12 + fmt.Println(l.Data()) // []int{2, 3, 4} +} +``` diff --git a/docs/en/api/packages/datastructure/optional.md b/docs/en/api/packages/datastructure/optional.md new file mode 100644 index 00000000..0b91700f --- /dev/null +++ b/docs/en/api/packages/datastructure/optional.md @@ -0,0 +1,416 @@ +# Optional +Optional is a type that may or may not contain a non-nil value. + + + +## Source + +- [https://github.com/duke-git/lancet/blob/main/datastructure/optional/optional.go](https://github.com/duke-git/lancet/blob/main/datastructure/optional/optional.go) + + + + +## Usage +```go +import ( + "github.com/duke-git/lancet/v2/datastructure/optional" +) +``` + + + +## Index + +- [Of](#Of) +- [FromNillable](#FromNillable) +- [Default](#Default) +- [IsNotNil](#IsNotNil) +- [IsNil](#IsNil) +- [IsNotNil](#IsNotNil) +- [IfNotNilOrElse](#IfNotNilOrElse) +- [Umwarp](#Umwarp) +- [OrElse](#OrElse) +- [OrElseGet](#OrElseGet) +- [OrElseTrigger](#OrElseTrigger) + + + + + +## Documentation + +### Of +Returns an Optional with a non-nil value.
+ +Signature: + +```go +func Of[T any](value T) Optional[T] +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + value := 42 + opt := optional.Of(value) + + fmt.Println(opt.Get()) + + // Output: + // 42 +} +``` + +### FromNillable +Returns an Optional for a given value, which may be nil.
+ +Signature: + +```go +func FromNillable[T any](value *T) Optional[T] +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + var value *int = nil + opt := optional.FromNillable(value) + + fmt.Println(opt.IsNotNil()) + + value = new(int) + *value = 42 + opt = optional.FromNillable(value) + + fmt.Println(opt.IsNotNil()) + + + // Output: + // false + // true +} +``` + + +### Default +Returns an default Optional instance.
+ +Signature: + +```go +func Default[T any]() Optional[T] +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + optDefault := optional.Default[int]() + fmt.Println(optDefault.IsNil()) + + // Output: + // true +} +``` + + +### IsNil +Checks if the Optional is nil.
+ +Signature: + +```go +func (o Optional[T]) IsNil() bool +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + optDefault := optional.Default[int]() + fmt.Println(optDefault.IsNil()) + + // Output: + // true +} +``` + + +### IsNotNil +Checks if there is a value not nil.
+ +Signature: + +```go +func (o Optional[T]) IsNotNil() bool +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + var value *int = nil + opt := optional.FromNillable(value) + + fmt.Println(opt.IsNotNil()) + + value = new(int) + *value = 42 + opt = optional.FromNillable(value) + + fmt.Println(opt.IsNotNil()) + + + // Output: + // false + // true +} +``` + + +### IfNotNil +Performs the given action with the value if a value is present.
+ +Signature: + +```go +func (o Optional[T]) IfNotNil(action func(value T)) +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + called := false + action := func(value int) { called = true } + + optDefault := optional.Default[int]() + optDefault.IfNotNil(action) + + fmt.Println(called) + + called = false // Reset for next test + optWithValue := optional.Of(42) + optWithValue.IfNotNil(action) + + fmt.Println(optWithValue.IsNotNil()) + + // Output: + // false + // true +} +``` + + +### IfNotNilOrElse +Performs the action with the value if not nil, otherwise performs the fallback action.
+ +Signature: + +```go +func (o Optional[T]) IfNotNilOrElse(action func(value T), fallbackAction func()) +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + calledWithValue := false + valueAction := func(value int) { calledWithValue = true } + emptyAction := func() { t.Errorf("Empty action should not be called when value is present") } + + optWithValue := optional.Of(42) + optWithValue.IfNotNilOrElse(valueAction, emptyAction) + + fmt.Println(calledWithValue) + + calledWithEmpty := false + valueAction = func(value int) { t.Errorf("Value action should not be called when value is not present") } + emptyAction = func() { calledWithEmpty = true } + + optDefault := optional.Default[int]() + optDefault.IfNotNilOrElse(valueAction, emptyAction) + + fmt.Println(calledWithEmpty) + + // Output: + // true + // true +} +``` + +### Unwrap +Returns the value if not nil, otherwise panics.
+ +Signature: + +```go +func (o Optional[T]) Unwrap() T +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + value := 42 + opt := optional.Of(value) + + fmt.Println(opt.Unwrap()) + + // Output: + // 42 +} +``` + + +### OrElse +Returns the value if not nill, otherwise returns other.
+ +Signature: + +```go +func (o Optional[T]) OrElse(other T) T +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + optDefault := optional.Default[int]() + val := optDefault.OrElse(100) + fmt.Println(val) + + optWithValue := optional.Of(42) + val = optWithValue.OrElse(100) + fmt.Println(val) + + // Output: + // 100 + // 42 +} +``` + + +### OrElseGet +Returns the value if not nil, otherwise invokes action and returns the result.
+ +Signature: + +```go +func (o Optional[T]) OrElseGet(action func() T) T +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + optDefault := optional.Default[int]() + action := func() int { return 100 } + + val := optDefault.OrElseGet(action) + fmt.Println(val) + + // Output: + // 100 +} +``` + + +### OrElseTrigger +Returns the value if present, otherwise returns an error.
+ +Signature: + +```go + OrElseTrigger(errorHandler func() error) (T, error) +``` +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datastructure/optional" +) + +func main() { + optDefault := optional.Default[int]() + _, err := optDefault.OrElseTrigger(func() error { return errors.New("no value") }) + + fmt.Println(err.Error()) + + optWithValue := optional.Of(42) + val, err := optWithValue.OrElseTrigger(func() error { return errors.New("no value") }) + + fmt.Println(val) + fmt.Println(err) + + // Output: + // no value + // 42 + // nil +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/datastructure/queue.md b/docs/en/api/packages/datastructure/queue.md new file mode 100644 index 00000000..623adc48 --- /dev/null +++ b/docs/en/api/packages/datastructure/queue.md @@ -0,0 +1,1387 @@ +# Queue +A queue is a kind of linear table. It only allows delete operations at the front of the table and insert operations at the rear of the table. This package includes ArrayQueue, LinkedQueue, CircularQueue, and PriorityQueue. + + + +## Source + +- [https://github.com/duke-git/lancet/blob/main/datastructure/queue/arrayqueue.go](https://github.com/duke-git/lancet/blob/main/datastructure/queue/arrayqueue.go) +- [https://github.com/duke-git/lancet/blob/main/datastructure/queue/linkedqueue.go](https://github.com/duke-git/lancet/blob/main/datastructure/queue/linkedqueue.go) +- [https://github.com/duke-git/lancet/blob/main/datastructure/queue/circularqueue.go](https://github.com/duke-git/lancet/blob/main/datastructure/queue/circularqueue.go) +- [https://github.com/duke-git/lancet/blob/main/datastructure/queue/priorityqueue.go](https://github.com/duke-git/lancet/blob/main/datastructure/queue/priorityqueue.go) + + + +## Usage +```go +import ( + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) +``` + + + +## Index + +### 1. ArrayQueue +- [NewArrayQueue](#NewArrayQueue) +- [Data](#ArrayQueue_Data) +- [Enqueue](#ArrayQueue_Enqueue) +- [Dequeue](#ArrayQueue_Dequeue) +- [Front](#ArrayQueue_Front) +- [Back](#ArrayQueue_Back) +- [Size](#ArrayQueue_Size) +- [IsEmpty](#ArrayQueue_IsEmpty) +- [IsFull](#ArrayQueue_IsFull) +- [Clear](#ArrayQueue_Clear) +- [Contain](#ArrayQueue_Contain) + + + +### 2. LinkedQueue +- [NewLinkedQueue](#NewLinkedQueue) +- [Data](#LinkedQueue_Data) +- [Enqueue](#LinkedQueue_Enqueue) +- [Dequeue](#LinkedQueue_Dequeue) +- [Front](#LinkedQueue_Front) +- [Back](#LinkedQueue_Back) +- [Size](#LinkedQueue_Size) +- [IsEmpty](#LinkedQueue_IsEmpty) +- [Clear](#LinkedQueue_Clear) +- [Contain](#LinkedQueue_Contain) + + +### 3. CircularQueue +- [NewCircularQueue](#NewCircularQueue) +- [Data](#CircularQueue_Data) +- [Enqueue](#CircularQueue_Enqueue) +- [Dequeue](#CircularQueue_Dequeue) +- [Front](#CircularQueue_Front) +- [Back](#CircularQueue_Back) +- [Size](#CircularQueue_Size) +- [IsEmpty](#CircularQueue_IsEmpty) +- [IsFull](#CircularQueue_IsFull) +- [Clear](#CircularQueue_Clear) +- [Contain](#CircularQueue_Contain) + + + +### 4. PriorityQueue +- [NewPriorityQueue](#NewPriorityQueue) +- [Data](#PriorityQueue_Data) +- [Enqueue](#PriorityQueue_Enqueue) +- [Dequeue](#PriorityQueue_Dequeue) +- [IsEmpty](#PriorityQueue_IsEmpty) +- [IsFull](#PriorityQueue_IsFull) +- [Size](#PriorityQueue_Size) + + + + +## Documentation + +### 1. ArrayQueue +Common queue implemented by slice. + +### NewArrayQueue +Return a ArrayQueue pointer with specific capacity
+ +Signature: + +```go +func NewArrayQueue[T any](capacity int) *ArrayQueue[T] + +type ArrayQueue[T any] struct { + items []T + head int + tail int + capacity int + size int +} +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + fmt.Println(q.Data()) // [] +} +``` + + + +### Data +Get all queue data
+ +Signature: + +```go +func (q *ArrayQueue[T]) Data() []T +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + fmt.Println(q.Data()) // [] +} +``` + + + + +### Enqueue +Put element into queue, if queue is full, return false
+ +Signature: + +```go +func (q *ArrayQueue[T]) Enqueue(item T) bool +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + + +### Dequeue +Remove head element of queue and return it
+ +Signature: + +```go +func (q *ArrayQueue[T]) Dequeue() (T, bool) +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Dequeue()) // 1 + fmt.Println(q.Data()) // 2,3 +} +``` + + + + +### Front +Just get the head element of queue
+ +Signature: + +```go +func (q *ArrayQueue[T]) Front() T +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Front()) // 1 + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + + +### Back +Just get the tail element of queue
+ +Signature: + +```go +func (q *ArrayQueue[T]) Back() T +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Back()) // 3 + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + +### Size +Get the number of elements in queue
+ +Signature: + +```go +func (q *ArrayQueue[T]) Size() int +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Size()) // 3 +} +``` + + + +### IsEmpty +Check if queue is empty or not
+ +Signature: + +```go +func (q *ArrayQueue[T]) IsEmpty() bool +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + fmt.Println(q.IsEmpty()) // true + + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.IsEmpty()) // false +} +``` + + + + +### IsFull +Check if queue is full or not
+ +Signature: + +```go +func (q *ArrayQueue[T]) IsFull() bool +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](3) + fmt.Println(q.IsFull()) // false + + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.IsFull()) // true +} +``` + + + +### Clear +Clean all data in queue
+ +Signature: + +```go +func (q *ArrayQueue[T]) Clear() +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + q.Clear() + + fmt.Println(q.IsEmpty()) // true +} +``` + + + +### Contain +Check if the value is in queue or not
+ +Signature: + +```go +func (q *ArrayQueue[T]) Contain(value T) bool +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewArrayQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Contain(1)) // true + fmt.Println(q.Contain(4)) // false +} +``` + + + +### 2. LinkedQueue +Common queue implemented by link. + +### NewLinkedQueue +Return a LinkedQueue pointer
+ +Signature: + +```go +func NewLinkedQueue[T any]() *LinkedQueue[T] + +type LinkedQueue[T any] struct { + head *datastructure.QueueNode[T] + tail *datastructure.QueueNode[T] + length int +} +type QueueNode[T any] struct { + Value T + Next *QueueNode[T] +} +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int]() + fmt.Println(q.Data()) // [] +} +``` + + + +### Data +Get all queue data
+ +Signature: + +```go +func (q *LinkedQueue[T]) Data() []T +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int]() + fmt.Println(q.Data()) // [] +} +``` + + + + +### Enqueue +Put element into queue
+ +Signature: + +```go +func (q *LinkedQueue[T]) Enqueue(value T) +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + + +### Dequeue +Remove head element of queue and return it
+ +Signature: + +```go +func (q *LinkedQueue[T]) Dequeue() (T, error) +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Dequeue()) // 1 + fmt.Println(q.Data()) // 2,3 +} +``` + + + + +### Front +Just get the head element of queue
+ +Signature: + +```go +func (q *LinkedQueue[T]) Front() (*T, error) +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Front()) // 1 + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + + +### Back +Just get the tail element of queue
+ +Signature: + +```go +func (q *LinkedQueue[T]) Back() (*T, error) +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Back()) // 3 + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + +### Size +Get the number of elements in queue
+ +Signature: + +```go +func (q *LinkedQueue[T]) Size() int +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Size()) // 3 +} +``` + + + +### IsEmpty +Check if queue is empty or not
+ +Signature: + +```go +func (q *LinkedQueue[T]) IsEmpty() bool +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + fmt.Println(q.IsEmpty()) // true + + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.IsEmpty()) // false +} +``` + + + + +### Clear +Clean all data in queue
+ +Signature: + +```go +func (q *LinkedQueue[T]) Clear() +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + q.Clear() + + fmt.Println(q.IsEmpty()) // true +} +``` + + + +### Contain +Check if the value is in queue or not
+ +Signature: + +```go +func (q *LinkedQueue[T]) Contain(value T) bool +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewLinkedQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Contain(1)) // true + fmt.Println(q.Contain(4)) // false +} +``` + + + + +### 3. CircularQueue +Circular queue implemented by slice. + +### NewCircularQueue +Return a CircularQueue pointer with specific capacity
+ +Signature: + +```go +func NewCircularQueue[T any](capacity int) *CircularQueue[T] + +type CircularQueue[T any] struct { + data []T + front int + rear int + capacity int +} +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + fmt.Println(q.Data()) // [] +} +``` + + + +### Data +Get all queue data
+ +Signature: + +```go +func (q *CircularQueue[T]) Data() []T +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + fmt.Println(q.Data()) // [] +} +``` + + + + +### Enqueue +Put element into queue, if queue is full, return error
+ +Signature: + +```go +func (q *CircularQueue[T]) Enqueue(value T) error +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + + +### Dequeue +Remove head element of queue and return it
+ +Signature: + +```go +func (q *CircularQueue[T]) Dequeue() (*T, bool) +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + val := q.Dequeue() + fmt.Println(*val) // 1 + fmt.Println(q.Data()) // 2,3 +} +``` + + + + +### Front +Just get head element of queue
+ +Signature: + +```go +func (q *CircularQueue[T]) Front() T +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Front()) // 1 + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + + +### Back +Just get tail element of queue
+ +Signature: + +```go +func (q *CircularQueue[T]) Back() T +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Back()) // 3 + fmt.Println(q.Data()) // 1,2,3 +} +``` + + + +### Size +Get the number of elements in queue
+ +Signature: + +```go +func (q *CircularQueue[T]) Size() int +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Size()) // 3 +} +``` + + + +### IsEmpty +Check if queue is empty or not
+ +Signature: + +```go +func (q *CircularQueue[T]) IsEmpty() bool +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + fmt.Println(q.IsEmpty()) // true + + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.IsEmpty()) // false +} +``` + + + + +### IsFull +Check if queue is full or not
+ +Signature: + +```go +func (q *CircularQueue[T]) IsFull() bool +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](3) + fmt.Println(q.IsFull()) // false + + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.IsFull()) // true +} +``` + + + +### Clear +Clean all data in queue
+ +Signature: + +```go +func (q *CircularQueue[T]) Clear() +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + q.Clear() + + fmt.Println(q.IsEmpty()) // true +} +``` + + + +### Contain +Check if the value is in queue or not
+ +Signature: + +```go +func (q *CircularQueue[T]) Contain(value T) bool +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewCircularQueue[int](5) + q.Enqueue(1) + q.Enqueue(2) + q.Enqueue(3) + + fmt.Println(q.Contain(1)) // true + fmt.Println(q.Contain(4)) // false +} +``` + + +### 4. PriorityQueue +Common queue implemented by slice. + +### NewPriorityQueue +Return a PriorityQueue pointer with specific capacity, param `comparator` is used to compare values of type T in the queue.
+ +Signature: + +```go +func NewPriorityQueue[T any](capacity int, comparator constraints.Comparator) *PriorityQueue[T] + +type PriorityQueue[T any] struct { + items []T + size int + comparator constraints.Comparator +} +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewPriorityQueue[int](3) + fmt.Println(q.Data()) // [] +} +``` + + + +### Data +Get all queue data
+ +Signature: + +```go +func (q *PriorityQueue[T]) Data() []T +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +func main() { + q := queue.NewPriorityQueue[int](3) + fmt.Println(q.Data()) // [] +} +``` + + + + +### Enqueue +Put element into queue, if queue is full, return false
+ +Signature: + +```go +func (q *PriorityQueue[T]) Enqueue(item T) bool +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + comparator := &intComparator{} + q := queue.NewPriorityQueue[int](10, comparator) + for i := 1; i < 11; i++ { + q.Enqueue(i) + } + + fmt.Println(q.Data()) // 10, 9, 6, 7, 8, 2, 5, 1, 4, 3 +} +``` + + + + +### Dequeue +Remove head element of queue and return it
+ +Signature: + +```go +func (q *PriorityQueue[T]) Dequeue() (T, bool) +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + comparator := &intComparator{} + q := queue.NewPriorityQueue[int](10, comparator) + for i := 1; i < 11; i++ { + q.Enqueue(i) + } + val, ok := pq.Dequeue() + fmt.Println(val) // 10 + fmt.Println(q.Data()) // 9, 8, 6, 7, 3, 2, 5, 1, 4 +} +``` + + + +### IsEmpty +Check if queue is empty or not
+ +Signature: + +```go +func (q *PriorityQueue[T]) IsEmpty() bool +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + comparator := &intComparator{} + q := queue.NewPriorityQueue[int](10, comparator) + fmt.Println(q.IsEmpty()) // true + + for i := 1; i < 11; i++ { + q.Enqueue(i) + } + fmt.Println(q.IsEmpty()) // false +} +``` + + + + +### IsFull +Check if queue is full or not
+ +Signature: + +```go +func (q *PriorityQueue[T]) IsFull() bool +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + comparator := &intComparator{} + q := queue.NewPriorityQueue[int](10, comparator) + fmt.Println(q.IsFull()) // false + + for i := 1; i < 11; i++ { + q.Enqueue(i) + } + fmt.Println(q.IsFull()) // true +} +``` + + + + +### Size +Get nubmers of elements in queue
+ +Signature: + +```go +func (q *PriorityQueue[T]) Size() int +``` +Example: + +```go +package main + +import ( + "fmt" + queue "github.com/duke-git/lancet/v2/datastructure/queue" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + comparator := &intComparator{} + q := queue.NewPriorityQueue[int](10, comparator) + fmt.Println(q.IsFull()) // false + + for i := 1; i < 5; i++ { + q.Enqueue(i) + } + fmt.Println(q.Size()) // 4 +} +``` + + diff --git a/docs/en/api/packages/datastructure/set.md b/docs/en/api/packages/datastructure/set.md new file mode 100644 index 00000000..e6115faf --- /dev/null +++ b/docs/en/api/packages/datastructure/set.md @@ -0,0 +1,710 @@ +# Set + +Set is a data container, like list, but elements of set is not duplicate. + + + +## Source + +- [https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go](https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go) + + + +## Usage + +```go +import ( + set "github.com/duke-git/lancet/v2/datastructure/set" +) +``` + + + +## Index + +- [New](#New) +- [FromSlice](#FromSlice) +- [Valuesdeprecated](#Values) +- [Add](#Add) +- [AddIfNotExist](#AddIfNotExist) +- [AddIfNotExistBy](#AddIfNotExistBy) +- [Delete](#Delete) +- [Contain](#Contain) +- [ContainAll](#ContainAll) +- [Clone](#Clone) +- [Size](#Size) +- [Equal](#Equal) +- [Iterate](#Iterate) +- [EachWithBreak](#EachWithBreak) +- [IsEmpty](#IsEmpty) +- [Union](#Union) +- [Intersection](#Intersection) +- [SymmetricDifference](#SymmetricDifference) +- [Minus](#Minus) +- [Pop](#Pop) +- [ToSlice](#ToSlice) +- [ToSortedSlice](#ToSortedSlice) + + + +## Documentation + +### New + +Create a set instance
+ +Signature: + +```go +type Set[T comparable] map[T]struct{} +func New[T comparable](items ...T) Set[T] +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int](1,2,2,3) + fmt.Println(st.Values()) //1,2,3 +} +``` + +### FromSlice + +Create a set from slice
+ +Signature: + +```go +func FromSlice[T comparable](items []T) Set[T] +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.FromSlice([]int{1, 2, 2, 3}) + fmt.Println(st.Values()) //1,2,3 +} +``` + +### Values + +Return slice of all set data.
+ +> ⚠️ This function is deprecated. use `ToSlice` instead. + +Signature: + +```go +func (s Set[T]) Values() []T +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int](1,2,2,3) + fmt.Println(st.Values()) //1,2,3 +} +``` + +### Add + +Add items to set
+ +Signature: + +```go +func (s Set[T]) Add(items ...T) +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int]() + st.Add(1, 2, 3) + + fmt.Println(st.Values()) //1,2,3 +} +``` + +### AddIfNotExist + +AddIfNotExist checks if item exists in the set, it adds the item to set and returns true if it does not exist in the set, or else it does nothing and returns false.
+ +Signature: + +```go +func (s Set[T]) AddIfNotExist(item T) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int]() + st.Add(1, 2, 3) + + r1 := st.AddIfNotExist(1) + r2 := st.AddIfNotExist(4) + + fmt.Println(r1) // false + fmt.Println(r2) // true + fmt.Println(st.Values()) // 1,2,3,4 +} +``` + +### AddIfNotExistBy + +AddIfNotExistBy checks if item exists in the set and pass the `checker` function it adds the item to set and returns true if it does not exists in the set and function `checker` returns true, or else it does nothing and returns false.
+ +Signature: + +```go +func (s Set[T]) AddIfNotExistBy(item T, checker func(element T) bool) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int]() + st.Add(1, 2) + + ok := st.AddIfNotExistBy(3, func(val int) bool { + return val%2 != 0 + }) + fmt.Println(ok) // true + + + notOk := st.AddIfNotExistBy(4, func(val int) bool { + return val%2 != 0 + }) + fmt.Println(notOk) // false + + fmt.Println(st.Values()) // 1, 2, 3 +} +``` + +### Delete + +Delete item in set
+ +Signature: + +```go +func (s Set[T]) Delete(items ...T) +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int]() + st.Add(1, 2, 3) + + set.Delete(3) + fmt.Println(st.Values()) //1,2 +} +``` + +### Contain + +Check if item is in set or not
+ +Signature: + +```go +func (s Set[T]) Contain(item T) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + st := set.New[int]() + st.Add(1, 2, 3) + + fmt.Println(st.Contain(1)) //true + fmt.Println(st.Contain(4)) //false +} +``` + +### ContainAll + +Checks if set contains another set
+ +Signature: + +```go +func (s Set[T]) ContainAll(other Set[T]) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New(1, 2) + set3 := set.New(1, 2, 3, 4) + + fmt.Println(set1.ContainAll(set2)) //true + fmt.Println(set1.ContainAll(set3)) //false +} +``` + +### Size + +Get the number of elements in set
+ +Signature: + +```go +func (s Set[T]) Size() int +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + + fmt.Println(set1.Size()) //3 +} +``` + +### Clone + +Make a copy of set
+ +Signature: + +```go +func (s Set[T]) Clone() Set[T] +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set1.Clone() + + fmt.Println(set1.Size() == set2.Size()) //true + fmt.Println(set1.ContainAll(set2)) //true +} +``` + +### Equal + +Check if two sets has same elements or not
+ +Signature: + +```go +func (s Set[T]) Equal(other Set[T]) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New(1, 2, 3) + set3 := set.New(1, 2, 3, 4) + + fmt.Println(set1.Equal(set2)) //true + fmt.Println(set1.Equal(set3)) //false +} +``` + +### Iterate + +Call function by every element of set
+ +Signature: + +```go +func (s Set[T]) Iterate(fn func(item T)) +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + arr := []int{} + set.Iterate(func(item int) { + arr = append(arr, item) + }) + + fmt.Println(arr) //1,2,3 +} +``` + +### EachWithBreak + +Iterates over elements of a set and invokes function for each element, when iteratee return false, will break the for each loop.
+ +Signature: + +```go +func (s Set[T]) EachWithBreak(iteratee func(item T) bool) +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + s := set.New(1, 2, 3, 4, 5) + + var sum int + + s.EachWithBreak(func(n int) bool { + if n > 3 { + return false + } + sum += n + return true + }) + + fmt.Println(sum) //6 +} +``` + +### IsEmpty + +Check if the set is empty or not
+ +Signature: + +```go +func (s Set[T]) IsEmpty() bool +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New() + + fmt.Println(set1.IsEmpty()) //false + fmt.Println(set2.IsEmpty()) //true +} +``` + +### Union + +Create a new set contain all element of set s and other
+ +Signature: + +```go +func (s Set[T]) Union(other Set[T]) Set[T] +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New(2, 3, 4, 5) + set3 := set1.Union(set2) + + fmt.Println(set3.Values()) //1,2,3,4,5 +} +``` + +### Intersection + +Create a new set whose element both be contained in set s and other
+ +Signature: + +```go +func (s Set[T]) Intersection(other Set[T]) Set[T] +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New(2, 3, 4, 5) + set3 := set1.Intersection(set2) + + fmt.Println(set3.Values()) //2,3 +} +``` + +### SymmetricDifference + +Create a new set whose element is in set1 or set2, but not in both set1 and set2
+ +Signature: + +```go +func (s Set[T]) SymmetricDifference(other Set[T]) Set[T] +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New(2, 3, 4, 5) + set3 := set1.SymmetricDifference(set2) + + fmt.Println(set3.Values()) //1,4,5 +} +``` + +### Minus + +Create an set of whose element in origin set but not in compared set
+ +Signature: + +```go +func (s Set[T]) Minus(comparedSet Set[T]) Set[T] +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + set1 := set.New(1, 2, 3) + set2 := set.New(2, 3, 4, 5) + set3 := set.New(2, 3) + + res1 := set1.Minus(set2) + fmt.Println(res1.Values()) //1 + + res2 := set2.Minus(set3) + fmt.Println(res2.Values()) //4,5 +} +``` + +### Pop + +Delete the top element of set then return it, if set is empty, return nil-value of T and false.
+ +Signature: + +```go +func (s Set[T]) Pop() (v T, ok bool) +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + s := set.New[int]() + s.Add(1) + s.Add(2) + s.Add(3) + + val, ok = s.Pop() + + fmt.Println(val) // 3 + fmt.Println(ok) // true +} +``` + +### ToSlice + +returns a slice containing all values of the set.
+ +Signature: + +```go +func (s Set[T]) ToSlice() (v T, ok bool) +``` + +Example: + +```go +func main() { + s := set.New(1, 2, 3, 4, 5) + + val := s.ToSlice() + fmt.Println(val) // [2 3 4 5 1] +} +``` + +### ToSortedSlice + +returns a sorted slice containing all values of the set
+ +Signature: + +```go +func (s Set[T]) ToSortedSlice() (v T, ok bool) +``` + +Example: + +```go +func main() { + s1 := set.New(1, 2, 3, 4, 5) + type Person struct { + Name string + Age int + } + s2 := FromSlice([]Person{{"Tom", 20}, {"Jerry", 18}, {"Spike", 25}}) + + res1 := s1.ToSortedSlice(func(v1, v2 int) bool { + return v1 < v2 + }) + + res2 := s2.ToSortedSlice(func(v1, v2 Person) bool { + return v1.Age < v2.Age + }) + + fmt.Println(res1) // [1 2 3 4 5] + fmt.Println(res2) // [{Jerry 18} {Tom 20} {Spike 25}] +} +``` diff --git a/docs/en/api/packages/datastructure/stack.md b/docs/en/api/packages/datastructure/stack.md new file mode 100644 index 00000000..d0455784 --- /dev/null +++ b/docs/en/api/packages/datastructure/stack.md @@ -0,0 +1,611 @@ +# Stack +Stack is an abstract data type that serves as a collection of elements. Elements follow the LIFO principle. FIFO is last-in, first-out, meaning that the most recently produced items are recorded as sold first. + + + +## Source + +- [https://github.com/duke-git/lancet/blob/main/datastructure/stack/arraystack.go](https://github.com/duke-git/lancet/blob/main/datastructure/stack/arraystack.go) +- [https://github.com/duke-git/lancet/blob/main/datastructure/stack/linkedstack.go](https://github.com/duke-git/lancet/blob/main/datastructure/stack/linkedstack.go) + + + + +## Usage +```go +import ( + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) +``` + + + +## Index + +### 1. ArrayStack + +- [NewArrayStack](#NewArrayStack) +- [Push](#ArrayStack_Push) +- [Pop](#ArrayStack_Pop) +- [Peak](#ArrayStack_Peak) +- [Data](#ArrayStack_Data) +- [Size](#ArrayStack_Size) +- [IsEmpty](#ArrayStack_IsEmpty) +- [Clear](#ArrayStack_Clear) + +### 2. LinkedStack + +- [NewLinkedStack](#NewLinkedStack) +- [Push](#LinkedStack_Push) +- [Pop](#LinkedStack_Pop) +- [Peak](#LinkedStack_Peak) +- [Data](#LinkedStack_Data) +- [Size](#LinkedStack_Size) +- [IsEmpty](#LinkedStack_IsEmpty) +- [Clear](#LinkedStack_Clear) +- [Print](#LinkedStack_Print) + + + +## Documentation + +### 1. ArrayStack +ArrayStack is a stack implemented by slice. + +### NewArrayStack +Return a empty ArrayStack pointer
+ +Signature: + +```go +type ArrayStack[T any] struct { + data []T + length int +} +func NewArrayStack[T any]() *ArrayStack[T] +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + fmt.Println(sk) +} +``` + + + + +### Push +Push element into array stack
+ +Signature: + +```go +func (s *ArrayStack[T]) Push(value T) +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.Data()) //[]int{3, 2, 1} +} +``` + + + + +### Pop +Delete the top element of stack then return it, if stack is empty, return nil and error
+ +Signature: + +```go +func (s *ArrayStack[T]) Pop() (*T, error) +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + val, err := sk.Pop() + fmt.Println(err) //nil + fmt.Println(*val) //3 + + fmt.Println(sk.Data()) //[]int{2, 1} +} +``` + + + + +### Peak +Return the top element of array stack
+ +Signature: + +```go +func (s *ArrayStack[T]) Peak() (*T, error) +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + val, err := sk.Peak() + fmt.Println(err) //nil + fmt.Println(*val) //3 + + fmt.Println(sk.Data()) //[]int{3, 2, 1} +} +``` + + + + +### Data +Return a slice of all data in array stack
+ +Signature: + +```go +func (s *ArrayStack[T]) Data() []T +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.Data()) //[]int{3, 2, 1} +} +``` + + + + +### Size +Return number of elements in array stack
+ +Signature: + +```go +func (s *ArrayStack[T]) Size() int +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.Size()) //3 +} +``` + + + + +### IsEmpty +Check if array stack is empty or not
+ +Signature: + +```go +func (s *ArrayStack[T]) IsEmpty() bool +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + fmt.Println(sk.IsEmpty()) //true + + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.IsEmpty()) //false +} +``` + + + + +### Clear +Clear all elments in array stack
+ +Signature: + +```go +func (s *ArrayStack[T]) Clear() +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewArrayStack[int]() + + sk.Push(1) + sk.Push(2) + sk.Push(3) + + sk.Clear() + + fmt.Println(sk.Data()) //[]int{} +} +``` + + + +### 2. LinkedStack +LinkedStack is a stack implemented by linked list. + +### NewLinkedStack +Return a empty LinkedStack pointer
+ +Signature: + +```go +type StackNode[T any] struct { + Value T + Next *StackNode[T] +} +type LinkedStack[T any] struct { + top *datastructure.StackNode[T] + length int +} +func NewLinkedStack[T any]() *LinkedStack[T] +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + fmt.Println(sk) +} +``` + + + + +### Push +Push element into linked stack
+ +Signature: + +```go +func (s *LinkedStack[T]) Push(value T) +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.Data()) //[]int{3, 2, 1} +} +``` + + + + +### Pop +Delete the top element of stack then return it, if stack is empty, return nil and error
+ +Signature: + +```go +func (s *LinkedStack[T]) Pop() (*T, error) +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + val, err := sk.Pop() + fmt.Println(err) //nil + fmt.Println(*val) //3 + + fmt.Println(sk.Data()) //[]int{2, 1} +} +``` + + + + +### Peak +Return the top element of linked stack
+ +Signature: + +```go +func (s *LinkedStack[T]) Peak() (*T, error) +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + val, err := sk.Peak() + fmt.Println(err) //nil + fmt.Println(*val) //3 + + fmt.Println(sk.Data()) //[]int{3, 2, 1} +} +``` + + + + +### Data +Return a slice of all data in linked stack
+ +Signature: + +```go +func (s *LinkedStack[T]) Data() []T +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.Data()) //[]int{3, 2, 1} +} +``` + + + + +### Size +Return number of elements in linked stack
+ +Signature: + +```go +func (s *LinkedStack[T]) Size() int +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.Size()) //3 +} +``` + + + + +### IsEmpty +Check if linked stack is empty or not
+ +Signature: + +```go +func (s *LinkedStack[T]) IsEmpty() bool +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + fmt.Println(sk.IsEmpty()) //true + + sk.Push(1) + sk.Push(2) + sk.Push(3) + + fmt.Println(sk.IsEmpty()) //false +} +``` + + + + +### Clear +Clear all elments in linked stack
+ +Signature: + +```go +func (s *LinkedStack[T]) Clear() +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + + sk.Push(1) + sk.Push(2) + sk.Push(3) + + sk.Clear() + + fmt.Println(sk.Data()) //[]int{} +} +``` + + + + +### Print +Print the structure of a linked stack
+ +Signature: + +```go +func (s *LinkedStack[T]) Print() +``` +Example: + +```go +package main + +import ( + "fmt" + stack "github.com/duke-git/lancet/v2/datastructure/stack" +) + +func main() { + sk := stack.NewLinkedStack[int]() + + sk.Push(1) + sk.Push(2) + sk.Push(3) + + + sk.Print() //[ &{Value:3 Next:0xc000010260}, &{Value:2 Next:0xc000010250}, &{Value:1 Next:Make a BSTree pointer instance
+ +Signature: + +```go +func NewBSTree[T any](rootData T, comparator constraints.Comparator) *BSTree[T] + +type BSTree[T any] struct { + root *datastructure.TreeNode[T] + comparator constraints.Comparator +} + +type TreeNode[T any] struct { + Value T + Left *TreeNode[T] + Right *TreeNode[T] +} +``` +Example: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + fmt.Println(bstree) // +} +``` + + + + +### Insert +Insert value into binary search tree
+ +Signature: + +```go +func (t *BSTree[T]) Insert(data T) +``` +Example: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.PreOrderTraverse()) //6, 5, 2, 4, 7 +} +``` + + + + +### Delete +Delete value of binary search tree
+ +Signature: + +```go +func (t *BSTree[T]) Delete(data T) +``` +Example: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + bstree.Delete(4) + + fmt.Println(bstree.PreOrderTraverse()) //2, 5, 6, 7 +} +``` + + + + +### PreOrderTraverse +Traverse tree nodes in pre order
+ +Signature: + +```go +func (t *BSTree[T]) PreOrderTraverse() []T +``` +Example: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.PreOrderTraverse()) //6, 5, 2, 4, 7 +} +``` + + + + +### InOrderTraverse +Traverse tree nodes in middle order
+ +Signature: + +```go +func (t *BSTree[T]) InOrderTraverse() []T +``` +Example: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.InOrderTraverse()) //2, 4, 5, 6, 7 +} +``` + + + + +### PostOrderTraverse +Traverse tree nodes in post order
+ +Signature: + +```go +func (t *BSTree[T]) PostOrderTraverse() []T +``` +Example: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.PostOrderTraverse()) //5, 2, 4, 7, 6 +} +``` + + + + +### LevelOrderTraverse +Traverse tree nodes in node level order
+ +Signature: + +```go +func (t *BSTree[T]) LevelOrderTraverse() []T +``` +Example: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.LevelOrderTraverse()) //6, 5, 7, 2, 4 +} +``` + + + + +### Depth +Get the depth of a binary saerch tree
+ +Signature: + +```go +func (t *BSTree[T]) Depth() int +``` +Example: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.Depth()) //4 +} +``` + + + + +### HasSubTree +Check if the given tree is sub tree of origin tree or not
+ +Signature: + +```go +func (t *BSTree[T]) HasSubTree(subTree *BSTree[T]) bool +``` +Example: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + superTree := tree.NewBSTree(8, &intComparator{}) + superTree.Insert(4) + superTree.Insert(5) + superTree.Insert(6) + superTree.Insert(9) + superTree.Insert(4) + + subTree := tree.NewBSTree(5, &intComparator{}) + subTree.Insert(4) + subTree.Insert(6) + + fmt.Println(superTree.HasSubTree(subTree)) //true + fmt.Println(subTree.HasSubTree(superTree)) //false +} +``` + + + + +### Print +Print the structure of binary saerch tree
+ +Signature: + +```go +func (t *BSTree[T]) Print() +``` +Example: + +```go +package main + +import ( + "fmt" + tree "github.com/duke-git/lancet/v2/datastructure/tree" +) + +type intComparator struct{} + +func (c *intComparator) Compare(v1, v2 any) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +func main() { + bstree := tree.NewBSTree(6, &intComparator{}) + bstree.Insert(7) + bstree.Insert(5) + bstree.Insert(2) + bstree.Insert(4) + + fmt.Println(bstree.Print()) +// 6 +// / \ +// / \ +// / \ +// / \ +// 5 7 +// / +// / +// 2 +// \ +// 4 +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/datetime.md b/docs/en/api/packages/datetime.md new file mode 100644 index 00000000..e5fc707b --- /dev/null +++ b/docs/en/api/packages/datetime.md @@ -0,0 +1,1855 @@ +# Datetime + +Package datetime supports date and time format and compare. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.go) +- [https://github.com/duke-git/lancet/blob/main/datetime/conversion.go](https://github.com/duke-git/lancet/blob/main/datetime/conversion.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/datetime" +) +``` + + + +## Index + +- [AddDay](#AddDay) +- [AddWeek](#AddWeek) +- [AddMonth](#AddMonth) +- [AddHour](#AddHour) +- [AddMinute](#AddMinute) +- [AddYear](#AddYear) +- [AddDaySafe](#AddDaySafe) +- [AddMonthSafe](#AddMonthSafe) +- [AddYearSafe](#AddYearSafe) +- [BeginOfMinute](#BeginOfMinute) +- [BeginOfHour](#BeginOfHour) +- [BeginOfDay](#BeginOfDay) +- [BeginOfWeek](#BeginOfWeek) +- [BeginOfMonth](#BeginOfMonth) +- [BeginOfYear](#BeginOfYear) +- [EndOfMinute](#EndOfMinute) +- [EndOfHour](#EndOfHour) +- [EndOfDay](#EndOfDay) +- [EndOfWeek](#EndOfWeek) +- [EndOfMonth](#EndOfMonth) +- [EndOfYear](#EndOfYear) +- [GetNowDate](#GetNowDate) +- [GetNowTime](#GetNowTime) +- [GetNowDateTime](#GetNowDateTime) +- [GetTodayStartTime](#GetTodayStartTime) +- [GetTodayEndTime](#GetTodayEndTime) +- [GetZeroHourTimestamp](#GetZeroHourTimestamp) +- [GetNightTimestamp](#GetNightTimestamp) +- [FormatTimeToStr](#FormatTimeToStr) +- [FormatStrToTime](#FormatStrToTime) +- [NewUnixNow](#NewUnixNow) +- [NewUnix](#NewUnix) +- [NewFormat](#NewFormat) +- [NewISO8601](#NewISO8601) +- [ToUnix](#ToUnix) +- [ToFormat](#ToFormat) +- [ToFormatForTpl](#ToFormatForTpl) +- [ToIso8601](#ToIso8601) +- [IsLeapYear](#IsLeapYear) +- [BetweenSeconds](#BetweenSeconds) +- [DayOfYear](#DayOfYear) +- [IsWeekenddeprecated](#IsWeekend) +- [NowDateOrTime](#NowDateOrTime) +- [Timestamp](#Timestamp) +- [TimestampMilli](#TimestampMilli) +- [TimestampMicro](#TimestampMicro) +- [TimestampNano](#TimestampNano) +- [TrackFuncTime](#TrackFuncTime) +- [DaysBetween](#DaysBetween) +- [GenerateDatetimesBetween](#GenerateDatetimesBetween) +- [Min](#Min) +- [Max](#Max) +- [MaxMin](#MaxMin) + + + + +## Documentation + +## Note: + +1. In below functions, the `format` string param should be one of flows value (case no sensitive): + +- yyyy-mm-dd hh:mm:ss +- yyyy-mm-dd hh:mm +- yyyy-mm-dd hh +- yyyy-mm-dd +- yyyy-mm +- mm-dd +- dd-mm-yy hh:mm:ss +- yyyy/mm/dd hh:mm:ss +- yyyy/mm/dd hh:mm +- yyyy/mm/dd hh +- yyyy/mm/dd +- yyyy/mm +- mm/dd +- dd/mm/yy hh:mm:ss +- yyyymmdd +- mmddyy +- yyyy +- yy +- mm +- hh:mm:ss +- hh:mm +- mm:ss + +### AddDay + +Add or sub days to time.
+ +Signature: + +```go +func AddDay(t time.Time, days int64) time.Time +``` + +Example:[Run](https://go.dev/play/p/dIGbs_uTdFa) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00") + + after1Day := datetime.AddDay(date, 1) + before1Day := datetime.AddDay(date, -1) + + fmt.Println(after1Day.Format("2006-01-02 15:04:05")) + fmt.Println(before1Day.Format("2006-01-02 15:04:05")) + + // Output: + // 2021-01-02 00:00:00 + // 2020-12-31 00:00:00 +} +``` + +### AddWeek + +Add or sub weeks to time.
+ +Signature: + +```go +func AddWeek(t time.Time, weeks int64) time.Time +``` + +Example:[Run](https://go.dev/play/p/M9TqdMiaA2p) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02", "2021-01-01") + + after2Weeks := datetime.AddWeek(date, 2) + before2Weeks := datetime.AddWeek(date, -2) + + fmt.Println(after2Weeks.Format("2006-01-02")) + fmt.Println(before2Weeks.Format("2006-01-02")) + + // Output: + // 2021-01-15 + // 2020-12-18 +} +``` + +### AddMonth + +Add or sub months to time.
+ +Signature: + +```go +func AddMonth(t time.Time, months int64) time.Time +``` + +Example:[Run](https://go.dev/play/p/DLoiOnpLvsN) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02", "2021-01-01") + + after2Months := datetime.AddMonth(date, 2) + before2Months := datetime.AddMonth(date, -2) + + fmt.Println(after2Months.Format("2006-01-02")) + fmt.Println(before2Months.Format("2006-01-02")) + + // Output: + // 2021-03-01 + // 2020-11-01 +} +``` + +### AddHour + +Add or sub hours to time.
+ +Signature: + +```go +func AddHour(t time.Time, hour int64) time.Time +``` + +Example:[Run](https://go.dev/play/p/rcMjd7OCsi5) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00") + + after2Hours := datetime.AddHour(date, 2) + before2Hours := datetime.AddHour(date, -2) + + fmt.Println(after2Hours.Format("2006-01-02 15:04:05")) + fmt.Println(before2Hours.Format("2006-01-02 15:04:05")) + + // Output: + // 2021-01-01 02:00:00 + // 2020-12-31 22:00:00 +} +``` + +### AddMinute + +Add or sub minutes to time.
+ +Signature: + +```go +func AddMinute(t time.Time, minute int64) time.Time +``` + +Example:[Run](https://go.dev/play/p/nT1heB1KUUK) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00") + + after2Minutes := datetime.AddMinute(date, 2) + before2Minutes := datetime.AddMinute(date, -2) + + fmt.Println(after2Minutes.Format("2006-01-02 15:04:05")) + fmt.Println(before2Minutes.Format("2006-01-02 15:04:05")) + + // Output: + // 2021-01-01 00:02:00 + // 2020-12-31 23:58:00 +} +``` + +### AddYear + +Add or sub year to the time.
+ +Signature: + +```go +func AddYear(t time.Time, year int64) time.Time +``` + +Example:[Run](https://go.dev/play/p/MqW2ujnBx10) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02", "2021-01-01") + + after2Years := AddYear(date, 2) + before2Years := AddYear(date, -2) + + fmt.Println(after2Years.Format("2006-01-02")) + fmt.Println(before2Years.Format("2006-01-02")) + + // Output: + // 2023-01-01 + // 2019-01-01 +} +``` + +### AddDaySafe + +Add or sub days to the time and ensure that the returned date does not exceed the valid date of the target year and month.
+ +Signature: + +```go +func AddDaySafe(t time.Time, days int) time.Time +``` + +Example:[Run](https://go.dev/play/p/JTohZFpoDJ3) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + leapYearDate1, _ := time.Parse("2006-01-02", "2024-02-29") + result1 := datetime.AddDaySafe(leapYearDate1, 1) + + leapYearDate2, _ := time.Parse("2006-01-02", "2024-03-01") + result2 := datetime.AddDaySafe(leapYearDate2, -1) + + nonLeapYearDate1, _ := time.Parse("2006-01-02", "2025-02-28") + result3 := datetime.AddDaySafe(nonLeapYearDate1, 1) + + nonLeaYearDate2, _ := time.Parse("2006-01-02", "2025-03-01") + result4 := datetime.AddDaySafe(nonLeaYearDate2, -1) + + fmt.Println(result1.Format("2006-01-02")) + fmt.Println(result2.Format("2006-01-02")) + fmt.Println(result3.Format("2006-01-02")) + fmt.Println(result4.Format("2006-01-02")) + + // Output: + // 2024-03-01 + // 2024-02-29 + // 2025-03-01 + // 2025-02-28 +} +``` + +### AddMonthSafe + +Add or sub months to the time and ensure that the returned date does not exceed the valid date of the target year and month.
+ +Signature: + +```go +func AddMonthSafe(t time.Time, months int) time.Time +``` + +Example:[Run](https://go.dev/play/p/KLw0lo6mbVW) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date1, _ := time.Parse("2006-01-02", "2025-01-31") + result1 := datetime.AddMonthSafe(date1, 1) + + date2, _ := time.Parse("2006-01-02", "2024-02-29") + result2 := datetime.AddMonthSafe(date2, -1) + + fmt.Println(result1.Format("2006-01-02")) + fmt.Println(result2.Format("2006-01-02")) + + // Output: + // 2025-02-28 + // 2024-01-29 +} +``` + +### AddYearSafe + +Add or sub years to the time and ensure that the returned date does not exceed the valid date of the target year and month.
+ +Signature: + +```go +func AddYearSafe(t time.Time, years int) time.Time +``` + +Example:[Run](https://go.dev/play/p/KVGXWZZ54ZH) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date, _ := time.Parse("2006-01-02", "2020-02-29") + + result1 := datetime.AddYearSafe(date, 1) + result2 := datetime.AddYearSafe(date, -1) + + fmt.Println(result1.Format("2006-01-02")) + fmt.Println(result2.Format("2006-01-02")) + + // Output: + // 2021-02-28 + // 2019-02-28 +} +``` + +### BeginOfMinute + +Return beginning minute time of day.
+ +Signature: + +```go +func BeginOfMinute(t time.Time) time.Time +``` + +Example:[Run](https://go.dev/play/p/ieOLVJ9CiFT) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.BeginOfMinute(input) + + fmt.Println(result) + + // Output: + // 2023-01-08 18:50:00 +0000 UTC +} +``` + +### BeginOfHour + +Return zero time of day.
+ +Signature: + +```go +func BeginOfHour(t time.Time) time.Time +``` + +Example:[Run](https://go.dev/play/p/GhdGFnDWpYs) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.BeginOfHour(input) + + fmt.Println(result) + + // Output: + // 2023-01-08 18:00:00 +0000 UTC +} +``` + +### BeginOfDay + +Return begin time of day.
+ +Signature: + +```go +func BeginOfDay(t time.Time) time.Time +``` + +Example:[Run](https://go.dev/play/p/94m_UT6cWs9) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.BeginOfDay(input) + + fmt.Println(result) + + // Output: + // 2023-01-08 00:00:00 +0000 UTC +} +``` + +### BeginOfWeek + +Return beginning time of week, week begin from Sunday.
+ +Signature: + +```go +func BeginOfWeek(t time.Time, beginFrom ...time.Weekday) time.Time +``` + +Example:[Run](https://go.dev/play/p/DCHdcL6gnfV) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + + result := datetime.BeginOfWeek(input, time.Monday) + + fmt.Println(result) + + // Output: + // 2023-01-02 00:00:00 +0000 UTC +} +``` + +### BeginOfMonth + +Return beginning time of month
+ +Signature: + +```go +func BeginOfMonth(t time.Time) time.Time +``` + +Example:[Run](https://go.dev/play/p/bWXVFsmmzwL) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.BeginOfMonth(input) + + fmt.Println(result) + + // Output: + // 2023-01-01 00:00:00 +0000 UTC +} +``` + +### BeginOfYear + +Return beginning time of year.
+ +Signature: + +```go +func BeginOfYear(t time.Time) time.Time +``` + +Example:[Run](https://go.dev/play/p/i326DSwLnV8) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.BeginOfYear(input) + + fmt.Println(result) + + // Output: + // 2023-01-01 00:00:00 +0000 UTC +} +``` + +### EndOfMinute + +Return end time minute of day.
+ +Signature: + +```go +func EndOfMinute(t time.Time) time.Time +``` + +Example:[Run](https://go.dev/play/p/yrL5wGzPj4z) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.EndOfMinute(input) + + fmt.Println(result) + + // Output: + // 2023-01-08 18:50:59.999999999 +0000 UTC +} +``` + +### EndOfHour + +Return end time hour of day.
+ +Signature: + +```go +func EndOfHour(t time.Time) time.Time +``` + +Example:[Run](https://go.dev/play/p/6ce3j_6cVqN) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.EndOfHour(input) + + fmt.Println(result) + + // Output: + // 2023-01-08 18:59:59.999999999 +0000 UTC +} +``` + +### EndOfDay + +Return end time hour of day.
+ +Signature: + +```go +func EndOfDay(t time.Time) time.Time +``` + +Example:[Run](https://go.dev/play/p/eMBOvmq5Ih1) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.EndOfDay(input) + + fmt.Println(result) + + // Output: + // 2023-01-08 23:59:59.999999999 +0000 UTC +} +``` + +### EndOfWeek + +Return end time of week, week end with Saturday.
+ +Signature: + +```go +func EndOfWeek(t time.Time, endWith ...time.Weekday) time.Time +``` + +Example:[Run](https://go.dev/play/p/mGSA162YgX9) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.EndOfWeek(input, time.Sunday) + + fmt.Println(result) + + // Output: + // 2023-01-08 23:59:59.999999999 +0000 UTC +} +``` + +### EndOfMonth + +Return end time of month
+ +Signature: + +```go +func EndOfMonth(t time.Time) time.Time +``` + +Example:[Run](https://go.dev/play/p/_GWh10B3Nqi) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.EndOfMonth(input) + + fmt.Println(result) + + // Output: + // 2023-01-31 23:59:59.999999999 +0000 UTC +} +``` + +### EndOfYear + +Return beginning time of year.
+ +Signature: + +```go +func EndOfYear(t time.Time) time.Time +``` + +Example:[Run](https://go.dev/play/p/G01cKlMCvNm) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC) + result := datetime.EndOfYear(input) + + fmt.Println(result) + + // Output: + // 2023-12-31 23:59:59.999999999 +0000 UTC +} +``` + +### GetNowDate + +Get current date string, format is yyyy-mm-dd.
+ +Signature: + +```go +func GetNowDate() string +``` + +Example:[Run](https://go.dev/play/p/PvfkPpcpBBf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + currentDate := datetime.GetNowDate() + fmt.Println(currentDate) + + // Output: + // 2022-01-28 +} +``` + +### GetNowTime + +Get current time string, format is hh:mm:ss.
+ +Signature: + +```go +func GetNowTime() string +``` + +Example:[Run](https://go.dev/play/p/l7BNxCkTmJS) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + currentTime := datetime.GetNowTime() + fmt.Println(currentTime) // 15:57:33 + + // Output: + // 15:57:33 +} +``` + +### GetNowDateTime + +Get current date time string, format is yyyy-mm-dd hh:mm:ss.
+ +Signature: + +```go +func GetNowDateTime() string +``` + +Example:[Run](https://go.dev/play/p/pI4AqngD0al) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + current := datetime.GetNowDateTime() + fmt.Println(current) + + // Output: + // 2022-01-28 15:59:33 +} +``` + +### GetTodayStartTime + +Return the start time of today, format: yyyy-mm-dd 00:00:00.
+ +Signature: + +```go +func GetTodayStartTime() string +``` + +Example:[Run](https://go.dev/play/p/84siyYF7t99) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + startTime := datetime.GetTodayStartTime() + fmt.Println(startTime) + + // Output: + // 2023-06-29 00:00:00 +} +``` + +### GetTodayEndTime + +Return the end time of today, format: yyyy-mm-dd 23:59:59.
+ +Signature: + +```go +func GetTodayEndTime() string +``` + +Example:[Run](https://go.dev/play/p/jjrLnfoqgn3) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + endTime := datetime.GetTodayEndTime() + fmt.Println(endTime) + + // Output: + // 2023-06-29 23:59:59 +} +``` + +### GetZeroHourTimestamp + +Return timestamp of zero hour (timestamp of 00:00).
+ +Signature: + +```go +func GetZeroHourTimestamp() int64 +``` + +Example:[Run](https://go.dev/play/p/QmL2oIaGE3q) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + zeroTime := datetime.GetZeroHourTimestamp() + fmt.Println(zeroTime) + + // Output: + // 1643299200 +} +``` + +### GetNightTimestamp + +Return timestamp of zero hour (timestamp of 23:59).
+ +Signature: + +```go +func GetNightTimestamp() int64 +``` + +Example:[Run](https://go.dev/play/p/UolysR3MYP1) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + nightTime := datetime.GetNightTimestamp() + fmt.Println(nightTime) + + // Output: + // 1643385599 +} +``` + +### FormatTimeToStr + +Format time to string, `format` param specification see note 1.
+ +Signature: + +```go +func FormatTimeToStr(t time.Time, format string, timezone ...string) string +``` + +Example:[Run](https://go.dev/play/p/_Ia7M8H_OvE) + +```go +package main + +import ( + "fmt" + "time" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + t, _ := time.Parse("2006-01-02 15:04:05", "2021-01-02 16:04:08") + + result1 := datetime.FormatTimeToStr(t, "yyyy-mm-dd hh:mm:ss") + result2 := datetime.FormatTimeToStr(t, "yyyy-mm-dd") + result3 := datetime.FormatTimeToStr(t, "dd-mm-yy hh:mm:ss") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 2021-01-02 16:04:08 + // 2021-01-02 + // 02-01-21 16:04:08 +} +``` + +### FormatStrToTime + +Format string to time, `format` param specification see note 1.
+ +Signature: + +```go +func FormatStrToTime(str, format string, timezone ...string) (time.Time, error) +``` + +Example:[Run](https://go.dev/play/p/1h9FwdU8ql4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + result1, _ := datetime.FormatStrToTime("2021-01-02 16:04:08", "yyyy-mm-dd hh:mm:ss") + result2, _ := datetime.FormatStrToTime("2021-01-02", "yyyy-mm-dd") + result3, _ := datetime.FormatStrToTime("02-01-21 16:04:08", "dd-mm-yy hh:mm:ss") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 2021-01-02 16:04:08 +0000 UTC + // 2021-01-02 00:00:00 +0000 UTC + // 2021-01-02 16:04:08 +0000 UTC +} +``` + +### NewUnixNow + +Return unix timestamp of current time
+ +Signature: + +```go +type theTime struct { + unix int64 +} +func NewUnixNow() *theTime +``` + +Example:[Run](https://go.dev/play/p/U4PPx-9D0oz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm := datetime.NewUnixNow() + fmt.Println(tm) + + // Output: + // &{1647597438} +} +``` + +### NewUnix + +Return unix timestamp of specified int64 value.
+ +Signature: + +```go +type theTime struct { + unix int64 +} +func NewUnix(unix int64) *theTime +``` + +Example:[Run](https://go.dev/play/p/psoSuh_kLRt) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm := datetime.NewUnix(1647597438) + fmt.Println(tm) + + // Output: + // &{1647597438} +} +``` + +### NewFormat + +Return unix timestamp of specified time string, t should be "yyyy-mm-dd hh:mm:ss".
+ +Signature: + +```go +type theTime struct { + unix int64 +} +func NewFormat(t string) (*theTime, error) +``` + +Example:[Run](https://go.dev/play/p/VkW08ZOaXPZ) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm, err := datetime.NewFormat("2022-03-18 17:04:05") + fmt.Println(tm) + + // Output: + // &{1647594245} +} +``` + +### NewISO8601 + +Return unix timestamp of specified iso8601 time string.
+ +Signature: + +```go +type theTime struct { + unix int64 +} +func NewISO8601(iso8601 string) (*theTime, error) +``` + +Example:[Run](https://go.dev/play/p/mkhOHQkdeA2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm, err := datetime.NewISO8601("2006-01-02T15:04:05.999Z") + fmt.Println(tm) + + // Output: + // &{1136214245} +} +``` + +### ToUnix + +Return unix timestamp.
+ +Signature: + +```go +func (t *theTime) ToUnix() int64 +``` + +Example:[Run](https://go.dev/play/p/_LUiwAdocjy) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm := datetime.NewUnixNow() + fmt.Println(tm.ToUnix()) + + // Output: + // 1647597438 +} +``` + +### ToFormat + +Return time string 'yyyy-mm-dd hh:mm:ss'.
+ +Signature: + +```go +func (t *theTime) ToFormat() string +``` + +Example:[Run](https://go.dev/play/p/VkW08ZOaXPZ) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm, _ := datetime.NewFormat("2022-03-18 17:04:05") + fmt.Println(tm.ToFormat()) + + // Output: + // 2022-03-18 17:04:05 +} +``` + +### ToFormatForTpl + +Return the time string which format is specified tpl.
+ +Signature: + +```go +func (t *theTime) ToFormatForTpl(tpl string) string +``` + +Example:[Run](https://go.dev/play/p/nyXxXcQJ8L5) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm, _ := datetime.NewFormat("2022-03-18 17:04:05") + ts := tm.ToFormatForTpl("2006/01/02 15:04:05") + fmt.Println(ts) + + // Output: + // 2022/03/18 17:04:05 +} +``` + +### ToIso8601 + +Return iso8601 time string.
+ +Signature: + +```go +func (t *theTime) ToIso8601() string +``` + +Example:[Run](https://go.dev/play/p/mkhOHQkdeA2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + tm, _ := datetime.NewISO8601("2006-01-02T15:04:05.999Z") + ts := tm.ToIso8601() + fmt.Println(ts) + + // Output: + // 2006-01-02T23:04:05+08:00 +} +``` + +### IsLeapYear + +check if param `year` is leap year or not.
+ +Signature: + +```go +func IsLeapYear(year int) bool +``` + +Example:[Run](https://go.dev/play/p/xS1eS2ejGew) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + result1 := datetime.IsLeapYear(2000) + result2 := datetime.IsLeapYear(2001) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### BetweenSeconds + +Return the number of seconds between two times.
+ +Signature: + +```go +func BetweenSeconds(t1 time.Time, t2 time.Time) int64 +``` + +Example:[Run](https://go.dev/play/p/n3YDRyfyXJu) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + today := time.Now() + tomorrow := datetime.AddDay(today, 1) + yesterday := datetime.AddDay(today, -1) + + result1 := datetime.BetweenSeconds(today, tomorrow) + result2 := datetime.BetweenSeconds(today, yesterday) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 86400 + // -86400 +} +``` + +### DayOfYear + +Returns which day of the year the parameter date `t` is.
+ +Signature: + +```go +func DayOfYear(t time.Time) int +``` + +Example:[Run](https://go.dev/play/p/0hjqhTwFNlH) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date1 := time.Date(2023, 02, 01, 1, 1, 1, 0, time.Local) + result1 := datetime.DayOfYear(date1) + + date2 := time.Date(2023, 01, 02, 1, 1, 1, 0, time.Local) + result2 := datetime.DayOfYear(date2) + + date3 := time.Date(2023, 01, 01, 1, 1, 1, 0, time.Local) + result3 := datetime.DayOfYear(date3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 31 + // 1 + // 0 +} +``` + +### IsWeekend(Deprecated, Use '== Weekday' instead) + +Checks if passed time is weekend or not.
+ +Signature: + +```go +func IsWeekend(t time.Time) bool +``` + +Example:[Run](https://go.dev/play/p/cupRM5aZOIY) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + date1 := time.Date(2023, 06, 03, 0, 0, 0, 0, time.Local) + date2 := time.Date(2023, 06, 04, 0, 0, 0, 0, time.Local) + date3 := time.Date(2023, 06, 02, 0, 0, 0, 0, time.Local) + + result1 := datetime.IsWeekend(date1) + result2 := datetime.IsWeekend(date2) + result3 := datetime.IsWeekend(date3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### NowDateOrTime + +Return current datetime with specific format and timezone.
+ +Signature: + +```go +func NowDateOrTime(format string, timezone ...string) string +``` + +Example:[Run](https://go.dev/play/p/EZ-begEjtT0) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + result1 := datetime.NowDateOrTime("yyyy-mm-dd hh:mm:ss") + + result2 := datetime.NowDateOrTime("yyyy-mm-dd hh:mm:ss", "EST") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 2023-07-26 15:01:30 + // 2023-07-26 02:01:30 +} +``` + +### Timestamp + +Return current second timestamp.
+ +Signature: + +```go +func Timestamp(timezone ...string) int64 +``` + +Example:[Run](https://go.dev/play/p/iU5b7Vvjx6x) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + ts := datetime.Timestamp() + + fmt.Println(ts) + + // Output: + // 1690363051 +} +``` + +### TimestampMilli + +Return current mill second timestamp.
+ +Signature: + +```go +func TimestampMilli(timezone ...string) int64 +``` + +Example:[Run](https://go.dev/play/p/4gvEusOTu1T) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + ts := datetime.TimestampMilli() + + fmt.Println(ts) + + // Output: + // 1690363051331 +} +``` + +### TimestampMicro + +Return current micro second timestamp.
+ +Signature: + +```go +func TimestampMicro(timezone ...string) int64 +``` + +Example:[Run](https://go.dev/play/p/2maANglKHQE) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + ts := datetime.TimestampMicro() + + fmt.Println(ts) + + // Output: + // 1690363051331784 +} +``` + +### TimestampNano + +Return current nano second timestamp.
+ +Signature: + +```go +func TimestampNano(timezone ...string) int64 +``` + +Example:[Run](https://go.dev/play/p/A9Oq_COrcCF) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + ts := datetime.TimestampNano() + + fmt.Println(ts) + + // Output: + // 1690363051331788000 +} +``` + +### TrackFuncTime + +Tracks function execution time.
+ +Signature: + +```go +func TrackFuncTime(pre time.Time) func() +``` + +Example:[Run](https://go.dev/play/p/QBSEdfXHPTp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + defer datetime.TrackFuncTime(time.Now())() + + var n int + for i := 0; i < 5000000; i++ { + n++ + } + + fmt.Println(1) // Function main execution time: 1.460287ms +} +``` + +### DaysBetween + +Returns the number of days between two times.
+ +Signature: + +```go +func DaysBetween(start, end time.Time) int +``` + +Example:[Run](https://go.dev/play/p/qD6qGb3TbOy) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + start := time.Date(2024, time.September, 1, 0, 0, 0, 0, time.UTC) + end := time.Date(2024, time.September, 10, 0, 0, 0, 0, time.UTC) + + result := datetime.DaysBetween(start, end) + + fmt.Println(result) + + // Output: + // 9 +} +``` + +### GenerateDatetimesBetween + +Returns a slice of strings between two times. `layout`: the format of the datetime string.`interval`: the interval between two datetimes.
+ +Signature: + +```go +func GenerateDatetimesBetween(start, end time.Time, layout string, interval string) ([]string, error) +``` + +Example:[Run](https://go.dev/play/p/6kHBpAxD9ZC) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + start := time.Date(2024, time.September, 1, 0, 0, 0, 0, time.UTC) + end := time.Date(2024, time.September, 1, 2, 0, 0, 0, time.UTC) + + layout := "2006-01-02 15:04:05" + interval := "1h" + + result, err := datetime.GenerateDatetimesBetween(start, end, layout, interval) + + fmt.Println(result) + fmt.Println(err) + + // Output: + // [2024-09-01 00:00:00 2024-09-01 01:00:00 2024-09-01 02:00:00] + //Returns the earliest time among the given times.
+ +Signature: + +```go +func Min(t1 time.Time, times ...time.Time) time.Time +``` + +Example:[Run](https://go.dev/play/p/MCIDvHNOGGb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + minTime := datetime.Min(time.Date(2024, time.September, 1, 0, 0, 0, 0, time.UTC), time.Date(2024, time.September, 2, 0, 0, 0, 0, time.UTC)) + + fmt.Println(minTime) + + // Output: + // 2024-09-01 00:00:00 +0000 UTC +} +``` + +### Max + +Returns the latest time among the given times.
+ +Signature: + +```go +func Max(t1 time.Time, times ...time.Time) time.Time +``` + +Example:[Run](https://go.dev/play/p/9m6JMk1LB7-) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + maxTime := datetime.Min(time.Date(2024, time.September, 1, 0, 0, 0, 0, time.UTC), time.Date(2024, time.September, 2, 0, 0, 0, 0, time.UTC)) + + fmt.Println(maxTime) + + // Output: + // 2024-09-02 00:00:00 +0000 UTC +} +``` + +### MaxMin + +Returns the latest and earliest time among the given times.
+ +Signature: + +```go +func MaxMin(t1 time.Time, times ...time.Time) (maxTime time.Time, minTime time.Time) +``` + +Example:[Run](https://go.dev/play/p/rbW51cDtM_2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/datetime" +) + +func main() { + max, min := datetime.MaxMin(time.Date(2024, time.September, 1, 0, 0, 0, 0, time.UTC), time.Date(2024, time.September, 2, 0, 0, 0, 0, time.UTC), time.Date(2024, time.September, 3, 0, 0, 0, 0, time.UTC)) + + fmt.Println(max) + fmt.Println(min) + + // Output: + // 2024-09-03 00:00:00 +0000 UTC + // 2024-09-01 00:00:00 +0000 UTC +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/eventbus.md b/docs/en/api/packages/eventbus.md new file mode 100644 index 00000000..17427662 --- /dev/null +++ b/docs/en/api/packages/eventbus.md @@ -0,0 +1,407 @@ +# EventBus + +EventBus is an event bus used for handling events within an application. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/eventbus/eventbus.go](https://github.com/duke-git/lancet/blob/main/eventbus/eventbus.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/eventbus" +) +``` + + + +## Index + +- [NewEventBus](#NewEventBus) +- [Subscribe](#Subscribe) +- [Unsubscribe](#Unsubscribe) +- [Publish](#Publish) +- [ClearListeners](#ClearListeners) +- [ClearListenersByTopic](#ClearListenersByTopic) +- [GetListenersCount](#GetListenersCount) +- [GetAllListenersCount](#GetAllListenersCount) +- [GetEvents](#GetEvents) +- [SetErrorHandler](#SetErrorHandler) + + + + +## Documentation + +### NewEventBus + +Create an EventBus instance.
+ +Signature: + +```go +func NewEventBus[T any]() *EventBus[T] +``` + +Example:[Run](https://go.dev/play/p/gHbOPV_NUOJ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 1 +} +``` + +### Subscribe + +Subscribes to an event with a specific event topic and listener function.
+ +Signature: + +```go +func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async bool, priority int, filter func(eventData T) bool) +``` + +Example:[Run](https://go.dev/play/p/EYGf_8cHei-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + filter := func(eventData int) bool { + return eventData == 1 + } + + eb.Subscribe("event1", listener, false, 0, filter) + + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 2}) + + fmt.Println(receivedData) + + // Output: + // 1 +} +``` + +### Unsubscribe + +Unsubscribes from an event with a specific event topic and listener function.
+ +Signature: + +```go +func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T)) +``` + +Example:[Run](https://go.dev/play/p/Tmh7Ttfvprf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Unsubscribe("event1", listener) + + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 0 +} +``` + +### Publish + +Publishes an event with a specific event topic and data payload.
+ +Signature: + +```go +func (eb *EventBus[T]) Publish(event eventbus.Event[T]) +``` + +Example:[Run](https://go.dev/play/p/gHTtVexFSH9) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) { + fmt.Println(eventData) + }, false, 0, nil) + + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // 1 +} +``` + +### ClearListeners + +Clears all the listeners.
+ +Signature: + +```go +func (eb *EventBus[T]) ClearListeners() +``` + +Example:[Run](https://go.dev/play/p/KBfBYlKPgqD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Subscribe("event2", listener, false, 0, nil) + + eb.ClearListeners() + + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(eventbus.Event[int]{Topic: "event2", Payload: 2}) + + fmt.Println(receivedData) + + // Output: + // 0 +} +``` + +### ClearListenersByTopic + +Clears all the listeners by topic.
+ +Signature: + +```go +func (eb *EventBus[T]) ClearListenersByTopic(topic string) +``` + +Example:[Run](https://go.dev/play/p/gvMljmJOZmU) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Subscribe("event2", listener, false, 0, nil) + + eb.ClearListenersByTopic("event1") + + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(eventbus.Event[int]{Topic: "event2", Payload: 2}) + + fmt.Println(receivedData) + + // Output: + // 2 +} +``` + +### GetListenersCount + +Returns the number of listeners for a specific event topic.
+ +Signature: + +```go +func (eb *EventBus[T]) GetListenersCount(topic string) int +``` + +Example:[Run](https://go.dev/play/p/j6yaJ2xAmFz) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + count := eb.GetListenersCount("event1") + + fmt.Println(count) + + // Output: + // 1 +} +``` + +### GetAllListenersCount + +Returns the total number of all listeners.
+ +Signature: + +```go +func (eb *EventBus[T]) GetAllListenersCount() int +``` + +Example:[Run](https://go.dev/play/p/PUlr0xcpEOz) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + count := eb.GetAllListenersCount() + + fmt.Println(count) + + // Output: + // 2 +} +``` + +### GetEvents + +Returns all the events topics.
+ +Signature: + +```go +func (eb *EventBus[T]) GetEvents() []string +``` + +Example:[Run](https://go.dev/play/p/etgjjcOtAjX) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + events := eb.GetEvents() + + for _, event := range events { + fmt.Println(event) + } + + // Output: + // event2 + // event1 +} +``` + +### SetErrorHandler + +Sets the error handler function.
+ +Signature: + +```go +func (eb *EventBus[T]) SetErrorHandler(handler func(err error)) +``` + +Example:[Run](https://go.dev/play/p/gmB0gnFe5mc) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.SetErrorHandler(func(err error) { + fmt.Println(err) + }) + + eb.Subscribe("event1", func(eventData int) { + panic("error") + }, false, 0, nil) + + eb.Publish(eventbus.Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // error +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/fileutil.md b/docs/en/api/packages/fileutil.md new file mode 100644 index 00000000..a236846a --- /dev/null +++ b/docs/en/api/packages/fileutil.md @@ -0,0 +1,1147 @@ +# Fileutil + +Package fileutil implements some basic functions for file operations. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/fileutil" +) +``` + + + +## Index + +- [ClearFile](#ClearFile) +- [CreateFile](#CreateFile) +- [CreateDir](#CreateDir) +- [CopyFile](#CopyFile) +- [CopyDir](#CopyDir) +- [CurrentPath](#CurrentPath) +- [FileMode](#FileMode) +- [MiMeType](#MiMeType) +- [IsExist](#IsExist) +- [IsLink](#IsLink) +- [IsDir](#IsDir) +- [ListFileNames](#ListFileNames) +- [RemoveFile](#RemoveFile) +- [RemoveDir](#RemoveDir) +- [ReadFileToString](#ReadFileToString) +- [ReadFileByLine](#ReadFileByLine) +- [Zip](#Zip) +- [ZipAppendEntry](#ZipAppendEntry) +- [UnZip](#UnZip) +- [IsZipFile](#IsZipFile) +- [FileSize](#FileSize) +- [MTime](#MTime) +- [Sha](#Sha) +- [ReadCsvFile](#ReadCsvFile) +- [WriteCsvFile](#WriteCsvFile) +- [WriteMapsToCsv](#WriteMapsToCsv) +- [WriteStringToFile](#WriteStringToFile) +- [WriteBytesToFile](#WriteBytesToFile) +- [ReadFile](#ReadFile) +- [ChunkRead](#ChunkRead) +- [ParallelChunkRead](#ParallelChunkRead) +- [GetExeOrDllVersion](#GetExeOrDllVersion) + + + +## Documentation + +### ClearFile + +Clear the file content, write empty string to the file.
+ +Signature: + +```go +func ClearFile(path string) error +``` + +Example:[Run](https://go.dev/play/p/NRZ0ZT-G94H) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.ClearFile("./test.txt") + if err != nil { + fmt.Println(err) + } +} +``` + +### CreateFile + +Create file in path. return true if create succeed.
+ +Signature: + +```go +func CreateFile(path string) bool +``` + +Example:[Run](https://go.dev/play/p/lDt8PEsTNKI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + isCreatedSucceed := fileutil.CreateFile("./test.txt") + fmt.Println(isCreatedSucceed) +} +``` + +### CreateDir + +Create directory in absolute path. param `absPath` like /a, /a/b.
+ +Signature: + +```go +func CreateDir(absPath string) error +``` + +Example:[Run](https://go.dev/play/p/qUuCe1OGQnM) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.CreateDir("/a/b") // will create folder /a/b + fmt.Println(err) +} +``` + +### CopyFile + +Copy src file to dest file. If dest file exist will overwrite it.
+ +Signature: + +```go +func CopyFile(srcPath string, dstPath string) error +``` + +Example:[Run](https://go.dev/play/p/Jg9AMJMLrJi) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.CopyFile("./test.txt", "./test_copy.txt") + if err != nil { + fmt.Println(err) + } +} +``` + +### CopyDir + +Copy src directory to dst directory, it will copy all files and directories recursively. the access permission will be the same as the source directory. if dstPath exists, it will return an error.
+ +Signature: + +```go +func CopyDir(srcPath string, dstPath string) error +``` + +Example:[Run](https://go.dev/play/p/YAyFTA_UuPb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.CopyFile("./test_src", "./test_dest") + if err != nil { + fmt.Println(err) + } +} +``` + +### CurrentPath + +return current absolute path.
+ +Signature: + +```go +func CurrentPath() string +``` + +Example:[Run](https://go.dev/play/p/s74a9iBGcSw) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + absPath := CurrentPath() + fmt.Println(absPath) +} +``` + +### FileMode + +Return file mode infomation.
+ +Signature: + +```go +func FileMode(path string) (fs.FileMode, error) +``` + +Example:[Run](https://go.dev/play/p/2l2hI42fA3p) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + mode, err := fileutil.FileMode("./test.txt") + if err != nil { + fmt.Println(err) + } + fmt.Println(mode) +} +``` + +### MiMeType + +Get file mime type, 'file' param's type should be string or *os.File.
+ +Signature: + +```go +func MiMeType(file any) string +``` + +Example:[Run](https://go.dev/play/p/bd5sevSUZNu) + +```go +package main + +import ( + "fmt" + "os" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + type1 := fileutil.MiMeType("./test.txt") + fmt.Println(type1) //text/plain; charset=utf-8 + + f, _ := os.Open("./file.go") + type2 := fileutil.MiMeType(f) + fmt.Println(type2) //text/plain; charset=utf-8 +} +``` + +### IsExist + +Checks if a file or directory exists.
+ +Signature: + +```go +func IsExist(path string) bool +``` + +Example:[Run](https://go.dev/play/p/nKKXt8ZQbmh) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + fileutil.CreateFile("./test.txt") + isFileExist := fileutil.IsExist("./test.txt") + fmt.Println(isFileExist) //true +} +``` + +### IsLink + +Checks if a file is symbol link or not.
+ +Signature: + +```go +func IsLink(path string) bool +``` + +Example:[Run](https://go.dev/play/p/TL-b-Kzvf44) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + isLinkFile := fileutil.IsLink("./test.txt") + fmt.Println(isLinkFile) //false +} +``` + +### IsDir + +Checks if the path is directy or not.
+ +Signature: + +```go +func IsDir(path string) bool +``` + +Example:[Run](https://go.dev/play/p/WkVwEKqtOWk) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + isDir := fileutil.IsDir("./") + fmt.Println(isDir) //true + + isDir = fileutil.IsDir("./test.txt") + fmt.Println(isDir) //false +} +``` + +### ListFileNames + +List all file names in given path.
+ +Signature: + +```go +func ListFileNames(path string) ([]string, error) +``` + +Example:[Run](https://go.dev/play/p/Tjd7Y07rejl) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + fileNames, _ := fileutil.ListFileNames("./") + fmt.Println(fileNames) +} +``` + +### RemoveFile + +Remove the file of path.
+ +Signature: + +```go +func RemoveFile(path string, onDelete ...func(path string)) error +``` + +Example:[Run](https://go.dev/play/p/P2y0XW8a1SH) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.RemoveFile("./test.txt") + if err != nil { + fmt.Println(err) + } +} +``` + +### RemoveDir + +Delete directory.
+ +Signature: + +```go +func RemoveDir(path string, onDelete ...func(path string)) error +``` + +Example:[Run](https://go.dev/play/p/Oa6KnPek2uy) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + var deletedPaths []string + + err := fileutil.RemoveDir("./tempdir", func(p string) { + deletedPaths = append(deletedPaths, p) + }) + + if err != nil { + fmt.Println(err) + } + + fmt.Println(deletedPaths) +} +``` + +### ReadFileToString + +Return string of file content.
+ +Signature: + +```go +func ReadFileToString(path string) (string, error) +``` + +Example:[Run](https://go.dev/play/p/cmfwp_5SQTp) + +```go +package main + +import ( + "fmt" + "os" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + path := "./test.txt" + fileutil.CreateFile(path) + + f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) + f.WriteString("hello world") + + content, _ := fileutil.ReadFileToString(path) + fmt.Println(content) //hello world +} +``` + +### ReadFileByLine + +Read file line by line, and return slice of lines
+ +Signature: + +```go +func ReadFileByLine(path string)([]string, error) +``` + +Example:[Run](https://go.dev/play/p/svJP_7ZrBrD) + +```go +package main + +import ( + "fmt" + "os" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + path := "./text.txt" + fileutil.CreateFile(path) + + f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) + defer f.Close() + f.WriteString("hello\nworld") + + contents, _ := fileutil.ReadFileByLine(path) + fmt.Println(contents) //[]string{"hello", "world"} +} +``` + +### Zip + +Create a zip file of fpath, fpath could be a file or a directory.
+ +Signature: + +```go +func Zip(fpath string, destPath string) error +``` + +Example:[Run](https://go.dev/play/p/j-3sWBp8ik_P) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.Zip("./test.txt", "./test.zip") + if err != nil { + fmt.Println(err) + } +} +``` + +### ZipAppendEntry + +Append a single file or directory by fpath to an existing zip file.
+ +Signature: + +```go +func ZipAppendEntry(fpath string, destPath string) error +``` + +Example:[Run](https://go.dev/play/p/cxvaT8TRNQp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.ZipAppendEntry("./test.txt", "./test.zip") + if err != nil { + fmt.Println(err) + } +} +``` + +### UnZip + +Unzip the file and save it to dest path.
+ +Signature: + +```go +func UnZip(zipFile string, destPath string) error +``` + +Example:[Run](https://go.dev/play/p/g0w34kS7B8m) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + err := fileutil.UnZip("./test.zip", "./test.txt") + if err != nil { + fmt.Println(err) + } +} +``` + +### IsZipFile + +Checks if file is zip file or not.
+ +Signature: + +```go +func IsZipFile(filepath string) bool +``` + +Example:[Run](https://go.dev/play/p/9M0g2j_uF_e) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + isZip := fileutil.IsZipFile("./zipfile.zip") + fmt.Println(isZip) +} +``` + +### FileSize + +Returns file size in bytes.
+ +Signature: + +```go +func FileSize(path string) (int64, error) +``` + +Example:[Run](https://go.dev/play/p/H9Z05uD-Jjc) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + size, err := fileutil.FileSize("./testdata/test.txt") + + fmt.Println(size) + fmt.Println(err) + + // Output: + // 20 + //Returns file modified time(unix timestamp).
+ +Signature: + +```go +func MTime(filepath string) (int64, error) +``` + +Example:[Run](https://go.dev/play/p/s_Tl7lZoAaY) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + mtime, err := fileutil.MTime("./testdata/test.txt") + + fmt.Println(mtime) + fmt.Println(err) + + // Output: + // 1682391110 + //returns file sha value, param `shaType` should be 1, 256 or 512.
+ +Signature: + +```go +func Sha(filepath string, shaType ...int) (string, error) +``` + +Example:[Run](https://go.dev/play/p/VfEEcO2MJYf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + sha1, err := fileutil.Sha("./testdata/test.txt", 1) + sha256, _ := fileutil.Sha("./testdata/test.txt", 256) + sha512, _ := fileutil.Sha("./testdata/test.txt", 512) + + fmt.Println(sha1) + fmt.Println(sha256) + fmt.Println(sha512) + fmt.Println(err) + + // Output: + // dda3cf10c5a6ff6c6659a497bf7261b287af2bc7 + // aa6d0a3fbc3442c228d606da09e0c1dc98c69a1cac3da1909199e0266171df35 + // d22aba2a1b7a2e2f512756255cc1c3708905646920cb1eb95e45b531ba74774dbbb89baebf1f716220eb9cf4908f1cfc5b2a01267704d9a59f59d77cab609870 + //Reads file content into slice.
+ +Signature: + +```go +func ReadCsvFile(filepath string, delimiter ...rune) ([][]string, error) +``` + +Example:[Run](https://go.dev/play/p/OExTkhGEd3_u) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + content, err := fileutil.ReadCsvFile("./testdata/test.csv") + + fmt.Println(content) + fmt.Println(err) + + // Output: + // [[Bob 12 male] [Duke 14 male] [Lucy 16 female]] + //Write content to target csv file.
+ +Signature: + +```go +func WriteCsvFile(filepath string, records [][]string, append bool, delimiter ...rune) error +``` + +Example:[Run](https://go.dev/play/p/dAXm58Q5U1o) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + fpath := "./test.csv" + fileutil.CreateFile(fpath) + + f, _ := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0777) + defer f.Close() + + data := [][]string{ + {"Lili", "22", "female"}, + {"Jim", "21", "male"}, + } + err := fileutil.WriteCsvFile(fpath, data, false) + + if err != nil { + return + } + + content, err := fileutil.ReadCsvFile(fpath) + + if err != nil { + return + } + fmt.Println(content) + + // Output: + // [[Lili 22 female] [Jim 21 male]] +} +``` + +### WriteMapsToCsv + +Write slice of map to csv file.
+ +Signature: + +```go +// filepath: path of the CSV file. +// records: slice of maps to be written. the value of map should be basic type. The maps will be sorted by key in alphabeta order, then be written into csv file. +// appendToExistingFile: If true, data will be appended to the file if it exists. +// delimiter: Delimiter to use in the CSV file. +// headers: order of the csv column headers, needs to be consistent with the key of the map. +func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune, headers ...[]string) error +``` + +Example:[运行](https://go.dev/play/p/umAIomZFV1c) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + fpath := "./test.csv" + fileutil.CreateFile(fpath) + + f, _ := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0777) + defer f.Close() + + records := []map[string]any{ + {"Name": "Lili", "Age": "22", "Gender": "female"}, + {"Name": "Jim", "Age": "21", "Gender": "male"}, + } + + headers := []string{"Name", "Age", "Gender"} + err := fileutil.WriteMapsToCsv(csvFilePath, records, false, ';', headers) + + if err != nil { + log.Fatal(err) + } + + content, err := fileutil.ReadCsvFile(csvFilePath, ';') + + fmt.Println(content) + + // Output: + // [[Name Age Gender] [Lili 22 female] [Jim 21 male]] +} +``` + +### WriteBytesToFile + +Writes bytes to target file.
+ +Signature: + +```go +func WriteBytesToFile(filepath string, content []byte) error +``` + +Example:[Run](https://go.dev/play/p/s7QlDxMj3P8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + filepath := "./bytes.txt" + + file, err := os.Create(filepath) + if err != nil { + return + } + + defer file.Close() + + err = fileutil.WriteBytesToFile(filepath, []byte("hello")) + if err != nil { + return + } + + content, err := fileutil.ReadFileToString(filepath) + if err != nil { + return + } + + os.Remove(filepath) + + fmt.Println(content) + + // Output: + // hello +} +``` + +### WriteStringToFile + +Writes string to target file.
+ +Signature: + +```go +func WriteStringToFile(filepath string, content string, append bool) error +``` + +Example:[Run](https://go.dev/play/p/GhLS6d8lH_g) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + filepath := "./test.txt" + + file, err := os.Create(filepath) + if err != nil { + return + } + + defer file.Close() + + err = fileutil.WriteStringToFile(filepath, "hello", true) + if err != nil { + return + } + + content, err := fileutil.ReadFileToString(filepath) + if err != nil { + return + } + + os.Remove(filepath) + + fmt.Println(content) + + // Output: + // hello +} +``` + +### ReadFile + +Read File or URL.
+ +Signature: + +```go +func ReadFile(path string) (reader io.ReadCloser, closeFn func(), err error) +``` + +Example:[Run](https://go.dev/play/p/uNep3Tr8fqF) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + reader, fn, err := fileutil.ReadFile("https://httpbin.org/robots.txt") + if err != nil { + return + } + defer fn() + + dat, err := io.ReadAll(reader) + if err != nil { + return + } + fmt.Println(string(dat)) + // Output: + // User-agent: * + // Disallow: /deny +} +``` + +### ChunkRead + +reads a block from the file at the specified offset and returns all lines within the block.
+ +Signature : + +```go +func ChunkRead(file *os.File, offset int64, size int, bufPool *sync.Pool) ([]string, error) +``` + +Example:[Run](https://go.dev/play/p/r0hPmKWhsgf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + const mb = 1024 * 1024 + const defaultChunkSizeMB = 100 + + // test1.csv file content: + // Lili,22,female + // Jim,21,male + filePath := "./testdata/test1.csv" + f, err := os.Open(filePath) + if err != nil { + return + } + + defer f.Close() + + var bufPool = sync.Pool{ + New: func() interface{} { + return make([]byte, 0, defaultChunkSizeMB*mb) + }, + } + + lines, err := fileutil.ChunkRead(f, 0, 100, &bufPool) + if err != nil { + return + } + + fmt.Println(lines[0]) + fmt.Println(lines[1]) + + // Output: + // Lili,22,female + // Jim,21,male +} +``` + +### ParallelChunkRead + +Reads the file in parallel and send each chunk of lines to the specified channel.
+ +Signature : + +```go +// filePath: file path. +// chunkSizeMB: The size of the block (in MB, the default is 100MB when set to 0). Setting it too large will be detrimental. Adjust it as appropriate. +// maxGoroutine: The number of concurrent read chunks, the number of CPU cores used when set to 0. +// linesCh: The channel used to receive the returned results. +func ParallelChunkRead(filePath string, linesCh chan<- []string, chunkSizeMB, maxGoroutine int) error +``` + +Example:[Run](https://go.dev/play/p/teMXnCsdSEw) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + const mb = 1024 * 1024 + const defaultChunkSizeMB = 100 // 默认值 + + numParsers := runtime.NumCPU() + + linesCh := make(chan []string, numParsers) + + // test1.csv file content: + // Lili,22,female + // Jim,21,male + filePath := "./testdata/test1.csv" + + go fileutil.ParallelChunkRead(filePath, linesCh, defaultChunkSizeMB, numParsers) + + var totalLines int + for lines := range linesCh { + totalLines += len(lines) + + for _, line := range lines { + fmt.Println(line) + } + } + + fmt.Println(totalLines) + + // Output: + // Lili,22,female + // Jim,21,male + // 2 +} +``` + +### GetExeOrDllVersion + +Get the version of exe or dll file on windows.
+ +Signature: + +```go +func GetExeOrDllVersion(filePath string) (string, error) +``` + +Example:[Run](https://go.dev/play/p/iLRrDBhE38E) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + v, err := fileutil.GetExeOrDllVersion(`C:\Program Files\Tencent\WeChat\WeChat.exe`) + if err != nil { + panic(err) + } + + fmt.Println(v) + + // Output: + // 3.9.10.19 +} +``` diff --git a/docs/en/api/packages/formatter.md b/docs/en/api/packages/formatter.md new file mode 100644 index 00000000..57014cb3 --- /dev/null +++ b/docs/en/api/packages/formatter.md @@ -0,0 +1,310 @@ +# Formatter + +formatter contains some functions for data formatting. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go) +- [https://github.com/duke-git/lancet/blob/main/formatter/byte.go](https://github.com/duke-git/lancet/blob/main/formatter/byte.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/formatter" +) +``` + + + +## Index + +- [Comma](#Comma) +- [Pretty](#Pretty) +- [PrettyToWriter](#PrettyToWriter) +- [DecimalBytes](#DecimalBytes) +- [BinaryBytes](#BinaryBytes) +- [ParseDecimalBytes](#ParseDecimalBytes) +- [ParseBinaryBytes](#ParseBinaryBytes) + + + +## Documentation + +### Comma + +Add comma to a number value by every 3 numbers from right to left. ahead by a prefix symbol char. if value is a invalid number string like "aa", return empty string.
+ +Signature: + +```go +func Comma[T constraints.Float | constraints.Integer | string](value T, prefixSymbol string) string +``` + +Example:[Run](https://go.dev/play/p/eRD5k2vzUVX) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + result1 := formatter.Comma("123", "") + result2 := formatter.Comma("12345", "$") + result3 := formatter.Comma(1234567, "¥") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 123 + // $12,345 + // ¥1,234,567 +} +``` + +### Pretty + +Pretty data to JSON string.
+ +Signature: + +```go +func Pretty(v any) (string, error) +``` + +Example:[Run](https://go.dev/play/p/YsciGj3FH2x) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + result1, _ := formatter.Pretty([]string{"a", "b", "c"}) + result2, _ := formatter.Pretty(map[string]int{"a": 1}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // [ + // "a", + // "b", + // "c" + // ] + // { + // "a": 1 + // } +} +``` + +### PrettyToWriter + +Pretty encode data to writer.
+ +Signature: + +```go +func PrettyToWriter(v any, out io.Writer) error +``` + +Example:[Run](https://go.dev/play/p/LPLZ3lDi5ma) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + type User struct { + Name string `json:"name"` + Aage uint `json:"age"` + } + user := User{Name: "King", Aage: 10000} + + buf := &bytes.Buffer{} + err := formatter.PrettyToWriter(user, buf) + + fmt.Println(buf) + fmt.Println(err) + + // Output: + // { + // "name": "King", + // "age": 10000 + // } + // + //Returns a human readable byte size under decimal standard (base 1000). The precision parameter specifies the number of digits after the decimal point, which is 4 for default.
+ +Signature: + +```go +func DecimalBytes(size float64, precision ...int) string +``` + +Example:[Run](https://go.dev/play/p/FPXs1suwRcs) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + result1 := formatter.DecimalBytes(1000) + result2 := formatter.DecimalBytes(1024) + result3 := formatter.DecimalBytes(1234567) + result4 := formatter.DecimalBytes(1234567, 3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 1KB + // 1.024KB + // 1.2346MB + // 1.235MB +} +``` + +### BinaryBytes + +Returns a human readable byte size under binary standard (base 1024). The precision parameter specifies the number of digits after the decimal point, which is 4 for default.
+ +Signature: + +```go +func BinaryBytes(size float64, precision ...int) string +``` + +Example:[Run](https://go.dev/play/p/G9oHHMCAZxP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + result1 := formatter.BinaryBytes(1024) + result2 := formatter.BinaryBytes(1024 * 1024) + result3 := formatter.BinaryBytes(1234567) + result4 := formatter.BinaryBytes(1234567, 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 1KiB + // 1MiB + // 1.1774MiB + // 1.18MiB +} +``` + +### ParseDecimalBytes + +Returns the human readable bytes size string into the amount it represents(base 1000).
+ +Signature: + +```go +func ParseDecimalBytes(size string) (uint64, error) +``` + +Example:[Run](https://go.dev/play/p/Am98ybWjvjj) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + result1, _ := formatter.ParseDecimalBytes("12") + result2, _ := formatter.ParseDecimalBytes("12k") + result3, _ := formatter.ParseDecimalBytes("12 Kb") + result4, _ := formatter.ParseDecimalBytes("12.2 kb") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 12 + // 12000 + // 12000 + // 12200 +} +``` + +### ParseBinaryBytes + +Returns the human readable bytes size string into the amount it represents(base 1024).
+ +Signature: + +```go +func ParseBinaryBytes(size string) (uint64, error) +``` + +Example:[Run](https://go.dev/play/p/69v1tTT62x8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/formatter" +) + +func main() { + result1, _ := formatter.ParseBinaryBytes("12") + result2, _ := formatter.ParseBinaryBytes("12ki") + result3, _ := formatter.ParseBinaryBytes("12 KiB") + result4, _ := formatter.ParseBinaryBytes("12.2 kib") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 12 + // 12288 + // 12288 + // 12492 +} +``` diff --git a/docs/en/api/packages/function.md b/docs/en/api/packages/function.md new file mode 100644 index 00000000..cf6d165c --- /dev/null +++ b/docs/en/api/packages/function.md @@ -0,0 +1,785 @@ +# Function + +Package function can control the flow of function execution and support part of functional programming. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go) +- [https://github.com/duke-git/lancet/blob/main/function/predicate.go](https://github.com/duke-git/lancet/blob/main/function/predicate.go) +- [https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/function" +) +``` + + + +## Index + +- [After](#After) +- [Before](#Before) +- [CurryFn](#CurryFn) +- [Compose](#Compose) +- [Debounce](#Debounce) +- [Debounceddeprecated](#Debounced) +- [Delay](#Delay) +- [Schedule](#Schedule) +- [Pipeline](#Pipeline) +- [Watcher](#Watcher) +- [And](#And) +- [Or](#Or) +- [Negate](#Negate) +- [Nor](#Nor) +- [Xnor](#Xnor) +- [Nand](#Nand) +- [AcceptIf](#AcceptIf) +- [Throttle](#Throttle) + + + + +## Documentation + +### After + +Creates a function that invokes given func once it's called n or more times.
+ +Signature: + +```go +func After(n int, fn any) func(args ...any) []reflect.Value +``` + +Example:[Run](https://go.dev/play/p/eRD5k2vzUVX) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + fn := function.After(2, func() { + fmt.Println("hello") + }) + + fn() + fn() + + // Output: + // hello +} +``` + +### Before + +creates a function that invokes func once it's called less than n times.
+ +Signature: + +```go +func Before(n int, fn any) func(args ...any) []reflect.Value +``` + +Example:[Run](https://go.dev/play/p/0HqUDIFZ3IL) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + fn := function.Before(2, func() { + fmt.Println("hello") + }) + + fn() + fn() + fn() + fn() + + // Output: + // hello + // hello +} +``` + +### CurryFn + +Make curry function.
+ +Signature: + +```go +type CurryFn[T any] func(...T) T +func (cf CurryFn[T]) New(val T) func(...T) T +``` + +Example:[Run](https://go.dev/play/p/5HopfDwANKX) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + add := func(a, b int) int { + return a + b + } + + var addCurry function.CurryFn[int] = func(values ...int) int { + return add(values[0], values[1]) + } + add1 := addCurry.New(1) + + result := add1(2) + + fmt.Println(result) + + // Output: + // 3 +} +``` + +### Compose + +Compose the function list from right to left, then return the composed function.
+ +Signature: + +```go +func Compose[T any](fnList ...func(...T) T) func(...T) T +``` + +Example:[Run](https://go.dev/play/p/KKfugD4PKYF) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + toUpper := func(strs ...string) string { + return strings.ToUpper(strs[0]) + } + toLower := func(strs ...string) string { + return strings.ToLower(strs[0]) + } + transform := function.Compose(toUpper, toLower) + + result := transform("aBCde") + + fmt.Println(result) + + // Output: + // ABCDE +} +``` +### Debounce + +Creates a debounced version of the provided function. The debounced function will only invoke the original function after the specified delay has passed since the last time it was invoked. It also supports canceling the debounce.
+ +Signature: + +```go +func Debounce(fn func(), delay time.Duration) (debouncedFn func(), cancelFn func()) +``` + +Example:[Run](https://go.dev/play/p/-dGFrYn_1Zi) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + callCount := 0 + fn := func() { + callCount++ + } + + debouncedFn, _ := function.Debounce(fn, 500*time.Millisecond) + + for i := 0; i < 10; i++ { + debouncedFn() + time.Sleep(50 * time.Millisecond) + } + + time.Sleep(1 * time.Second) + fmt.Println(callCount) + + debouncedFn() + + time.Sleep(1 * time.Second) + fmt.Println(callCount) + + // Output: + // 1 + // 2 +} +``` + +### Debounced + +Creates a debounced function that delays invoking fn until after wait duration have elapsed since the last time the debounced function was invoked.
+ +> ⚠️ This function is deprecated. use `Debounce` instead. + +Signature: + +```go +func Debounced(fn func(), duration time.Duration) func() +``` + +Example:[Run](https://go.dev/play/p/absuEGB_GN7) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + count := 0 + + add := func() { + count++ + } + + debouncedAdd := function.Debounced(add, 50*time.Microsecond) + + debouncedAdd() + debouncedAdd() + debouncedAdd() + debouncedAdd() + + time.Sleep(100 * time.Millisecond) + + fmt.Println(count) + + debouncedAdd() + + time.Sleep(100 * time.Millisecond) + + fmt.Println(count) + + // Output: + // 1 + // 2 +} +``` + +### Delay + +Invoke function after delayed time.
+ +Signature: + +```go +func Delay(delay time.Duration, fn any, args ...any) +``` + +Example:[Run](https://go.dev/play/p/Ivtc2ZE-Tye) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + var print = func(s string) { + fmt.Println(s) + } + + function.Delay(2*time.Second, print, "hello") + + // Output: + // hello +} +``` + +### Schedule + +Invoke function every duration time, until close the returned bool chan.
+ +Signature: + +```go +func Schedule(d time.Duration, fn any, args ...any) chan bool +``` + +Example:[Run](https://go.dev/play/p/hbON-Xeyn5N) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + count := 0 + + increase := func() { + count++ + } + + stop := function.Schedule(2*time.Second, increase) + + time.Sleep(2 * time.Second) + close(stop) + + fmt.Println(count) + + // Output: + // 2 +} +``` + +### Pipeline + +Pipeline takes a list of functions and returns a function whose param will be passed into +the functions one by one.
+ +Signature: + +```go +func Pipeline[T any](funcs ...func(T) T) func(T) T +``` + +Example:[Run](https://go.dev/play/p/mPdUVvj6HD6) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + addOne := func(x int) int { + return x + 1 + } + double := func(x int) int { + return 2 * x + } + square := func(x int) int { + return x * x + } + + fn := function.Pipeline(addOne, double, square) + + result := fn(2) + + fmt.Println(result) + + // Output: + // 36 +} +``` + +### Watcher + +Watcher is used for record code excution time. can start/stop/reset the watch timer. get the elapsed time of function execution.
+ +Signature: + +```go +type Watcher struct { + startTime int64 + stopTime int64 + excuting bool +} +func NewWatcher() *Watcher +func (w *Watcher) Start() //start the watcher +func (w *Watcher) Stop() //stop the watcher +func (w *Watcher) Reset() //reset the watcher +func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution +``` + +Example:[Run](https://go.dev/play/p/l2yrOpCLd1I) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + w := function.NewWatcher() + + w.Start() + + longRunningTask() + + fmt.Println(w.excuting) //true + + w.Stop() + + eapsedTime := w.GetElapsedTime().Milliseconds() + + fmt.Println(eapsedTime) + + w.Reset() +} + +func longRunningTask() { + var slice []int64 + for i := 0; i < 10000000; i++ { + slice = append(slice, int64(i)) + } +} + +``` + + +### And + +Returns a composed predicate that represents the logical AND of a list of predicates. It evaluates to true only if all predicates evaluate to true for the given value.
+ +Signature: + +```go +func And[T any](predicates ...func(T) bool) func(T) bool +``` + +Example:[Run](https://go.dev/play/p/dTBHJMQ0zD2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + isNumericAndLength5 := function.And( + func(s string) bool { return strings.ContainsAny(s, "0123456789") }, + func(s string) bool { return len(s) == 5 }, + ) + + fmt.Println(isNumericAndLength5("12345")) + fmt.Println(isNumericAndLength5("1234")) + fmt.Println(isNumericAndLength5("abcde")) + + // Output: + // true + // false + // false +} +``` + +### Or + +Returns a composed predicate that represents the logical OR of a list of predicates. It evaluates to true if at least one of the predicates evaluates to true for the given value.
+ +Signature: + +```go +func Or[T any](predicates ...func(T) bool) func(T) bool +``` + +Example:[Run](https://go.dev/play/p/LitCIsDFNDA) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + containsDigitOrSpecialChar := function.Or( + func(s string) bool { return strings.ContainsAny(s, "0123456789") }, + func(s string) bool { return strings.ContainsAny(s, "!@#$%") }, + ) + + fmt.Println(containsDigitOrSpecialChar("hello!")) + fmt.Println(containsDigitOrSpecialChar("hello")) + + // Output: + // true + // false +} +``` + +### Negate + +Returns a predicate that represents the logical negation of this predicate.
+ +Signature: + +```go +func Negate[T any](predicate func(T) bool) func(T) bool +``` + +Example:[Run](https://go.dev/play/p/jbI8BtgFnVE) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + // Define some simple predicates for demonstration + isUpperCase := func(s string) bool { + return strings.ToUpper(s) == s + } + isLowerCase := func(s string) bool { + return strings.ToLower(s) == s + } + isMixedCase := function.Negate(function.Or(isUpperCase, isLowerCase)) + + fmt.Println(isMixedCase("ABC")) + fmt.Println(isMixedCase("AbC")) + + // Output: + // false + // true +} +``` + + +### Nor + +Returns a composed predicate that represents the logical NOR of a list of predicates. It evaluates to true only if all predicates evaluate to false for the given value.
+ +Signature: + +```go +func Nor[T any](predicates ...func(T) bool) func(T) bool +``` + +Example:[Run](https://go.dev/play/p/2KdCoBEOq84) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + match := function.Nor( + func(s string) bool { return strings.ContainsAny(s, "0123456789") }, + func(s string) bool { return len(s) == 5 }, + ) + + fmt.Println(match("dbcdckkeee")) + + + match = function.Nor( + func(s string) bool { return strings.ContainsAny(s, "0123456789") }, + func(s string) bool { return len(s) == 5 }, + ) + + fmt.Println(match("0123456789")) + + // Output: + // true + // false +} +``` + +### Nand + +Returns a composed predicate that represents the logical NAND of a list of predicates. It evaluates to true only if all predicates evaluate to false for the given value.
+ +Signature: + +```go +func Nand[T any](predicates ...func(T) bool) func(T) bool +``` + +Example:[Run](https://go.dev/play/p/Rb-FdNGpgSO) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + isNumericAndLength5 := function.Nand( + func(s string) bool { return strings.ContainsAny(s, "0123456789") }, + func(s string) bool { return len(s) == 5 }, + ) + + fmt.Println(isNumericAndLength5("12345")) + fmt.Println(isNumericAndLength5("1234")) + fmt.Println(isNumericAndLength5("abcdef")) + + // Output: + // false + // false + // true +} +``` + +### Xnor + +Returns a composed predicate that represents the logical XNOR of a list of predicates. It evaluates to true only if all predicates evaluate to true or false for the given value.
+ +Signature: + +```go +func Xnor[T any](predicates ...func(T) bool) func(T) bool +``` + +Example:[Run](https://go.dev/play/p/FJxko8SFbqc) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + isEven := func(i int) bool { return i%2 == 0 } + isPositive := func(i int) bool { return i > 0 } + + match := function.Xnor(isEven, isPositive) + + fmt.Println(match(2)) + fmt.Println(match(-3)) + fmt.Println(match(3)) + + // Output: + // true + // true + // false +} +``` + +### AcceptIf + +AcceptIf returns another function of the same signature as the apply function but also includes a bool value to indicate success or failure. A predicate function that takes an argument of type T and returns a bool. An apply function that also takes an argument of type T and returns a modified value of the same type.
+ +Signature: + +```go +func AcceptIf[T any](predicate func(T) bool, apply func(T) T) func(T) (T, bool) +``` + +Example:[Run](https://go.dev/play/p/XlXHHtzCf7d) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + + adder := function.AcceptIf( + function.And( + func(x int) bool { + return x > 10 + }, func(x int) bool { + return x%2 == 0 + }), + func(x int) int { + return x + 1 + }, + ) + + result, ok := adder(20) + fmt.Println(result) + fmt.Println(ok) + + result, ok = adder(21) + fmt.Println(result) + fmt.Println(ok) + + // Output: + // 21 + // true + // 0 + // false +} +``` + +### Throttle + +Throttle creates a throttled version of the provided function. The returned function guarantees that it will only be invoked at most once per interval.
+ +Signature: + +```go +func Throttle(fn func(), interval time.Duration) func() +``` + +Example:[Run](https://go.dev/play/p/HpoMov-tJSN) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/function" +) + +func main() { + callCount := 0 + + fn := func() { + callCount++ + } + + throttledFn := function.Throttle(fn, 1*time.Second) + + for i := 0; i < 5; i++ { + throttledFn() + } + + time.Sleep(1 * time.Second) + + fmt.Println(callCount) + + // Output: + // 1 +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/maputil.md b/docs/en/api/packages/maputil.md new file mode 100644 index 00000000..9288c49d --- /dev/null +++ b/docs/en/api/packages/maputil.md @@ -0,0 +1,2365 @@ +# Maputil + +Package maputil includes some functions to manipulate map. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/maputil/map.go](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/concurrentmap.go) +- [https://github.com/duke-git/lancet/blob/main/maputil/orderedmap.go](https://github.com/duke-git/lancet/blob/main/maputil/orderedmap.go) + + + +## Example: + +```go +import ( + "github.com/duke-git/lancet/v2/maputil" +) +``` + + + +## Index + +- [MapTo](#MapTo) +- [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) +- [IsDisjoint](#IsDisjoint) +- [HasKey](#HasKey) +- [MapToStruct](#MapToStruct) +- [ToSortedSlicesDefault](#ToSortedSlicesDefault) +- [ToSortedSlicesWithComparator](#ToSortedSlicesWithComparator) +- [NewOrderedMap](#NewOrderedMap) +- [OrderedMap_Set](#OrderedMap_Set) +- [OrderedMap_Get](#OrderedMap_Get) +- [OrderedMap_Front](#OrderedMap_Front) +- [OrderedMap_Back](#OrderedMap_Back) +- [OrderedMap_Delete](#OrderedMap_Delete) +- [OrderedMap_Clear](#OrderedMap_Clear) +- [OrderedMap_Len](#OrderedMap_Len) +- [OrderedMap_Keys](#OrderedMap_Keys) +- [OrderedMap_Values](#OrderedMap_Values) +- [OrderedMap_Contains](#OrderedMap_Contains) +- [OrderedMap_Range](#OrderedMap_Range) +- [OrderedMap_Elements](#OrderedMap_Elements) +- [OrderedMap_Iter](#OrderedMap_Iter) +- [OrderedMap_ReverseIter](#OrderedMap_ReverseIter) +- [OrderedMap_SortByKey](#OrderedMap_SortByKey) +- [OrderedMap_MarshalJSON](#OrderedMap_MarshalJSON) +- [OrderedMap_UnmarshalJSON](#OrderedMap_UnmarshalJSON) +- [NewConcurrentMap](#NewConcurrentMap) +- [ConcurrentMap_Get](#ConcurrentMap_Get) +- [ConcurrentMap_Set](#ConcurrentMap_Set) +- [ConcurrentMap_GetOrSet](#ConcurrentMap_GetOrSet) +- [ConcurrentMap_Delete](#ConcurrentMap_Delete) +- [ConcurrentMap_GetAndDelete](#ConcurrentMap_GetAndDelete) +- [ConcurrentMap_Has](#ConcurrentMap_Has) +- [ConcurrentMap_Range](#ConcurrentMap_Range) +- [GetOrSet](#GetOrSet) +- [SortByKey](#SortByKey) +- [GetOrDefault](#GetOrDefault) +- [FindValuesBy](#FindValuesBy) + + + +## Documentation + +### MapTo + +Rry to map any interface to struct or base type.
+ +Signature: + +```go +func MapTo(src any, dst any) error +``` + +Example:[Run](https://go.dev/play/p/4K7KBEPgS5M) + +```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: + //Executes iteratee funcation for every key and value pair in map.
+ +Signature: + +```go +func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V)) +``` + +Example:[Run](https://go.dev/play/p/OaThj6iNVXK) + +```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 + +Iterates over map, return a new map contains all key and value pairs pass the predicate function.
+ +Signature: + +```go +func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V +``` + +Example:[Run](https://go.dev/play/p/fSvF3wxuNG7) + +```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 := maputil.Filter(m, isEven) + + fmt.Println(result) + + // Output: + // map[b:2 d:4] +} +``` + +### 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:[Run](https://go.dev/play/p/7ov6BJHbVqh) + +```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:[Run](https://go.dev/play/p/P3-9MdcXegR) + +```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:[Run](https://go.dev/play/p/YJM4Hj5hNwm) + +```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:[Run](https://go.dev/play/p/jXGrWDBfSRp) + +```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:[Run](https://go.dev/play/p/XB7Y10uw20_U) + +```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.
+ +Signature: + +```go +func Intersect[K comparable, V any](maps ...map[K]V) map[K]V +``` + +Example:[Run](https://go.dev/play/p/Zld0oj3sjcC) + +```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 + +Returns a slice of the map's keys.
+ +Signature: + +```go +func Keys[K comparable, V any](m map[K]V) []K +``` + +Example:[Run](https://go.dev/play/p/xNB5bTb97Wd) + +```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", + 4: "c", + 5: "d", + } + + keys := maputil.Keys(m) + sort.Ints(keys) + + fmt.Println(keys) + + // Output: + // [1 2 3 4 5] +} +``` + +### Merge + +Merge maps, next key will overwrite previous key.
+ +Signature: + +```go +func Merge[K comparable, V any](maps ...map[K]V) map[K]V +``` + +Example:[Run](https://go.dev/play/p/H95LENF1uB-) + +```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 + +Creates an map of whose key in mapA but not in mapB.
+ +Signature: + +```go +func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V +``` + +Example:[Run](https://go.dev/play/p/3u5U9K7YZ9m) + +```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 + +Returns a slice of the map's values.
+ +Signature: + +```go +func Values[K comparable, V any](m map[K]V) []V +``` + +Example:[Run](https://go.dev/play/p/CBKdUc5FTW6) + +```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", + 4: "c", + 5: "d", + } + + values := maputil.Values(m) + sort.Strings(values) + + fmt.Println(values) + + // Output: + // [a a b c d] +} +``` + +### 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:[Run](https://go.dev/play/p/hI371iB8Up8) + +```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:[Run](https://go.dev/play/p/sg9-oRidh8f) + +```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:[Run](https://go.dev/play/p/8scDxWeBDKd) + +```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:[Run](https://go.dev/play/p/g92aY3fc7Iw) + +```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:[Run](https://go.dev/play/p/Ltb11LNcElY) + +```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:[Run](https://go.dev/play/p/fTdu4sCNjQO) + +```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:[Run](https://go.dev/play/p/P6ovfToM3zj) + +```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.
+ +Signature: + +```go +func IsDisjoint[K comparable, V any](mapA, mapB map[K]V) bool +``` + +Example:[Run](https://go.dev/play/p/N9qgYg_Ho6f) + +```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 + +Checks if map has key or not. This function is used to replace the following boilerplate code:
+ +```go +_, haskey := amap["baz"]; + +if haskey { + fmt.Println("map has key baz") +} +``` + +Signature: + +```go +func HasKey[K comparable, V any](m map[K]V, key K) bool +``` + +Example:[Run](https://go.dev/play/p/isZZHOsDhFc) + +```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 + +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 + ++Translate the key and value of the map into two slices that are sorted in ascending order according to the key’s value, with the position of the elements in the value slice corresponding to the key.
+ +Signature: + +```go +func ToSortedSlicesDefault[K constraints.Ordered, V any](m map[K]V) ([]K, []V) +``` + +Example:[Run](https://go.dev/play/p/43gEM2po-qy) + +```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 := maputil.ToSortedSlicesDefault(m) + + fmt.Println(keys) + fmt.Println(values) + + // Output: + // [1 2 3] + // [a b c] +} +``` + +### ToSortedSlicesWithComparator + ++Translate the key and value of the map into two slices that are sorted according to a custom sorting rule defined by a comparator function based on the key's value, with the position of the elements in the value slice corresponding to the key. +
+ +Signature: + +```go +func ToSortedSlicesWithComparator[K comparable, V any](m map[K]V, comparator func(a, b K) bool) ([]K, []V) +``` + +Example:[Run](https://go.dev/play/p/0nlPo6YLdt3) + +```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 + +Creates a new OrderedMap.
+ +Signature: + +```go +func NewOrderedMap[K comparable, V any]() *OrderedMap[K, V] +``` + +Example:[Run](https://go.dev/play/p/99QjSYSBdiM) + +```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 + +Sets the given key-value pair.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Set(key K, value V) +``` + +Example:[Run](https://go.dev/play/p/Y4ZJ_oOc1FU) + +```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 + +Returns the value for the given key.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Get(key K) (V, bool) +``` + +Example:[Run](https://go.dev/play/p/Y4ZJ_oOc1FU) + +```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 + +Deletes the key-value pair for the given key.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Delete(key K) +``` + +Example:[Run](https://go.dev/play/p/5bIi4yaZ3K-) + +```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 + +Clears the map.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Clear() +``` + +Example:[Run](https://go.dev/play/p/8LwoJyEfuFr) + +```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 + +Returns the first key-value pair.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Front() (struct { + Key K + Value V +}, bool) +``` + +Example:[Run](https://go.dev/play/p/ty57XSimpoe) + +```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 + +Returns the last key-value pair.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Back() (struct { + Key K + Value V +}, bool) +``` + +Example:[Run](https://go.dev/play/p/rQMjp1yQmpa) + +```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 + +Calls the given function for each key-value pair.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Range(iteratee func(key K, value V) bool) +``` + +Example:[Run](https://go.dev/play/p/U-KpORhc7LZ) + +```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 + +Returns the keys in order.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Keys() []K +``` + +Example:[Run](https://go.dev/play/p/Vv_y9ExKclA) + +```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 + +Returns the values in order.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Values() []V +``` + +Example:[Run](https://go.dev/play/p/TWj5n1-PUfx) + +```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 + +Returns the key-value pairs in order.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Elements() []struct +``` + +Example:[Run](https://go.dev/play/p/4BHG4kKz6bB) + +```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 + +Returns the number of key-value pairs.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Len() int +``` + +Example:[Run](https://go.dev/play/p/cLe6z2VX5N-) + +```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 + +Returns true if the given key exists.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Contains(key K) bool +``` + +Example:[Run](https://go.dev/play/p/QuwqqnzwDNX) + +```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 + +Returns a channel that yields key-value pairs in order.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) Iter() <-chan struct { + Key K + Value V +} +``` + +Example:[Run](https://go.dev/play/p/tlq2tdvicPt) + +```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 + +Returns a channel that yields key-value pairs in reverse order.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) ReverseIter() <-chan struct { + Key K + Value V +} +``` + +Example:[Run](https://go.dev/play/p/8Q0ssg6hZzO) + +```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 + +Sorts the map by key given less function.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) SortByKey(less func(a, b K) bool) +``` + +Example:[Run](https://go.dev/play/p/N7hjD_alZPq) + +```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 + +Implements the json.Marshaler interface.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) MarshalJSON() ([]byte, error) +``` + +Example:[Run](https://go.dev/play/p/C-wAwydIAC7) + +```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 + +Implements the json.Unmarshaler interface.
+ +Signature: + +```go +func (om *OrderedMap[K, V]) UnmarshalJSON(data []byte) error +``` + +Example:[Run](https://go.dev/play/p/8C3MvJ3-mut) + +```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 is like map, but is safe for concurrent use by multiple goroutines.
+ +Signature: + +```go +// NewConcurrentMap create a ConcurrentMap with specific shard count. +func NewConcurrentMap[K comparable, V any](shardCount int) *ConcurrentMap[K, V] +``` + +Example:[Run](https://go.dev/play/p/3PenTPETJT0) + +```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 + +Set the value for a key.
+ +Signature: + +```go +func (cm *ConcurrentMap[K, V]) Set(key K, value V) +``` + +Example:[Run](https://go.dev/play/p/3PenTPETJT0) + +```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 + +Get the value stored in the map for a key, or nil if no.
+ +Signature: + +```go +func (cm *ConcurrentMap[K, V]) Get(key K) (V, bool) +``` + +Example:[Run](https://go.dev/play/p/3PenTPETJT0) + +```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 + +Returns the existing value for the key if present. Otherwise, it sets and returns the given value.
+ +Signature: + +```go +func (cm *ConcurrentMap[K, V]) GetOrSet(key K, value V) (actual V, ok bool) +``` + +Example:[Run](https://go.dev/play/p/aDcDApOK01a) + +```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 + +Delete the value for a key.
+ +Signature: + +```go +func (cm *ConcurrentMap[K, V]) Delete(key K) +``` + +Example:[Run](https://go.dev/play/p/uTIJZYhpVMS) + +```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() + }(j) + } + + wg2.Wait() +} +``` + +### ConcurrentMap_GetAndDelete + +Returns the existing value for the key if present and then delete the value for the key. Otherwise, do nothing, just return false.
+ +Signature: + +```go +func (cm *ConcurrentMap[K, V]) GetAndDelete(key K) (actual V, ok bool) +``` + +Example:[Run](https://go.dev/play/p/ZyxeIXSZUiM) + +```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 + +Checks if map has the value for a key.
+ +Signature: + +```go +func (cm *ConcurrentMap[K, V]) Has(key K) bool +``` + +Example:[Run](https://go.dev/play/p/C8L4ul9TVwf) + +```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 + +Calls iterator sequentially for each key and value present in each of the shards in the map. If iterator returns false, range stops the iteration.
+ +Signature: + +```go +func (cm *ConcurrentMap[K, V]) Range(iterator func(key K, value V) bool) +``` + +Example:[Run](https://go.dev/play/p/iqcy7P8P0Pr) + +```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 + +Returns value of the given key or set the given value value if not present.
+ +Signature: + +```go +func GetOrSet[K comparable, V any](m map[K]V, key K, value V) V +``` + +Example:[Run](https://go.dev/play/p/IVQwO1OkEJC) + +```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 + +Sorts the map by its keys and returns a new map with sorted keys.
+ +Signature: + +```go +func SortByKey[K constraints.Ordered, V any](m map[K]V) (sortedKeysMap map[K]V) +``` + +Example:[Run](https://go.dev/play/p/PVdmBSnm6P_W) + +```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 + +Returns the value of the given key or a default value if the key is not present.
+ +Signature: + +```go +func GetOrDefault[K comparable, V any](m map[K]V, key K, defaultValue V) V +``` + +Example:[Run](https://go.dev/play/p/99QjSYSBdiM) + +```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 +} +``` + +### FindValuesBy + +Returns a slice of values from the map that satisfy the given predicate function.
+ +Signature: + +```go +func FindValuesBy[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) []V +``` + +Example:[Run](https://go.dev/play/p/bvNwNBZDm6v) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/maputil" +) + +func main() { + m := map[int]string{ + 1: "a", + 2: "b", + 3: "c", + 4: "d", + } + + result := maputil.FindValuesBy(m, func(k int, v string) bool { + return k%2 == 0 + }) + + fmt.Println(result) + + // Output: + // [b d] +} +``` diff --git a/docs/en/api/packages/mathutil.md b/docs/en/api/packages/mathutil.md new file mode 100644 index 00000000..61ec2be3 --- /dev/null +++ b/docs/en/api/packages/mathutil.md @@ -0,0 +1,1300 @@ +# Mathutil + +Package mathutil implements some functions for math calculation. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go) + + + +## Example: + +```go +import ( + "github.com/duke-git/lancet/v2/mathutil" +) +``` + + + +## Index + +- [Average](#Average) +- [Exponent](#Exponent) +- [Fibonacci](#Fibonacci) +- [Factorial](#Factorial) +- [Max](#Max) +- [MaxBy](#MaxBy) +- [Min](#Min) +- [MinBy](#MaxBy) +- [Percent](#Percent) +- [RoundToFloat](#RoundToFloat) +- [RoundToString](#RoundToString) +- [TruncRound](#TruncRound) +- [CeilToFloat](#CeilToFloat) +- [CeilToString](#CeilToString) +- [FloorToFloat](#FloorToFloat) +- [FloorToString](#FloorToString) +- [Range](#Range) +- [RangeWithStep](#RangeWithStep) +- [AngleToRadian](#AngleToRadian) +- [RadianToAngle](#RadianToAngle) +- [PointDistance](#PointDistance) +- [IsPrime](#IsPrime) +- [GCD](#GCD) +- [LCM](#LCM) +- [Cos](#Cos) +- [Sin](#Sin) +- [Log](#Log) +- [Sum](#Sum) +- [Abs](#Abs) +- [Div](#Div) +- [Variance](#Variance) +- [StdDev](#StdDev) +- [Permutation](#Permutation) +- [Combination](#Combination) + + + +## Documentation + +### Average + +Return average value of numbers. Maybe call RoundToFloat to round result.
+ +Signature: + +```go +func Average[T constraints.Integer | constraints.Float](numbers ...T) float64 +``` + +Example:[Run](https://go.dev/play/p/Vv7LBwER-pz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Average(1, 2) + + avg := mathutil.Average(1.2, 1.4) + result2 := mathutil.RoundToFloat(avg, 1) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1.5 + // 1.3 +} +``` + +### Exponent + +Calculate x to the nth power.
+ +Signature: + +```go +func Exponent(x, n int64) int64 +``` + +Example:[Run](https://go.dev/play/p/uF3HGNPk8wr) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Exponent(10, 0) + result2 := mathutil.Exponent(10, 1) + result3 := mathutil.Exponent(10, 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 1 + // 10 + // 100 +} +``` + +### Fibonacci + +Calculate the nth number of fibonacci sequence.
+ +Signature: + +```go +func Fibonacci(first, second, n int) int +``` + +Example:[Run](https://go.dev/play/p/IscseUNMuUc) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Fibonacci(1, 1, 1) + result2 := mathutil.Fibonacci(1, 1, 2) + result3 := mathutil.Fibonacci(1, 1, 5) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 1 + // 1 + // 5 +} +``` + +### Factorial + +Calculate the factorial of x.
+ +Signature: + +```go +func Factorial(x uint) uint +``` + +Example:[Run](https://go.dev/play/p/tt6LdOK67Nx) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Factorial(1) + result2 := mathutil.Factorial(2) + result3 := mathutil.Factorial(3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 1 + // 2 + // 6 +} +``` + +### Max + +Return max value of numbers.
+ +Signature: + +```go +func Max[T constraints.Integer | constraints.Float](numbers ...T) T +``` + +Example:[Run](https://go.dev/play/p/cN8DHI0rTkH) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Max(1, 2, 3) + result2 := mathutil.Max(1.2, 1.4, 1.1, 1.4) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 3 + // 1.4 +} +``` + +### MaxBy + +Return the maximum value of a slice using the given comparator function.
+ +Signature: + +```go +func MaxBy[T any](slice []T, comparator func(T, T) bool) T +``` + +Example:[Run](https://go.dev/play/p/pbe2MT-7DV2) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.MaxBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool { + return len(v1) > len(v2) + }) + + result2 := mathutil.MaxBy([]string{"abd", "abc", "ab"}, func(v1, v2 string) bool { + return len(v1) > len(v2) + }) + + result3 := mathutil.MaxBy([]string{}, func(v1, v2 string) bool { + return len(v1) > len(v2) + }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // abc + // abd + // +} +``` + +### Min + +Return the minimum value of numbers.
+ +Signature: + +```go +func Min[T constraints.Integer | constraints.Float](numbers ...T) T +``` + +Example:[Run](https://go.dev/play/p/21BER_mlGUj) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Min(1, 2, 3) + result2 := mathutil.Min(1.2, 1.4, 1.1, 1.4) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1 + // 1.1 +} +``` + +### MinBy + +Return the minimum value of a slice using the given comparator function.
+ +Signature: + +```go +func MinBy[T any](slice []T, comparator func(T, T) bool) T +``` + +Example:[Run](https://go.dev/play/p/N9qgYg_Ho6f) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.MinBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool { + return len(v1) < len(v2) + }) + + result2 := mathutil.MinBy([]string{"ab", "ac", "abc"}, func(v1, v2 string) bool { + return len(v1) < len(v2) + }) + + result3 := mathutil.MinBy([]string{}, func(v1, v2 string) bool { + return len(v1) < len(v2) + }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // a + // ab + // +} +``` + +### Percent + +calculate the percentage of val to total, retain n decimal places.
+ +Signature: + +```go +func Percent(val, total float64, n int) float64 +``` + +Example:[Run](https://go.dev/play/p/s0NdFCtwuyd) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Percent(1, 2, 2) + result2 := mathutil.Percent(0.1, 0.3, 2) + result3 := mathutil.Percent(-30305, 408420, 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 50 + // 33.33 + // -7.42 +} +``` + +### RoundToFloat + +Round float up to n decimal places.
+ +Signature: + +```go +func RoundToFloat[T constraints.Float | constraints.Integer](x T, n int) float64 +``` + +Example:[Run](https://go.dev/play/p/ghyb528JRJL) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.RoundToFloat(0.124, 2) + result2 := mathutil.RoundToFloat(0.125, 2) + result3 := mathutil.RoundToFloat(0.125, 3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 0.12 + // 0.13 + // 0.125 +} +``` + +### RoundToString + +Round float up to n decimal places. will return string.
+ +Signature: + +```go +func RoundToString[T constraints.Float | constraints.Integer](x T, n int) string +``` + +Example:[Run](https://go.dev/play/p/kZwpBRAcllO) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.RoundToString(0.124, 2) + result2 := mathutil.RoundToString(0.125, 2) + result3 := mathutil.RoundToString(0.125, 3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 0.12 + // 0.13 + // 0.125 +} +``` + +### TruncRound + +Round float off n decimal places.
+ +Signature: + +```go +func TruncRound[T constraints.Float | constraints.Integer](x T, n int) T +``` + +Example:[Run](https://go.dev/play/p/aumarSHIGzP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.TruncRound(0.124, 2) + result2 := mathutil.TruncRound(0.125, 2) + result3 := mathutil.TruncRound(0.125, 3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 0.12 + // 0.12 + // 0.125 +} +``` + +### CeilToFloat + +Round float up n decimal places.
+ +Signature: + +```go +func CeilToFloat[T constraints.Float | constraints.Integer](x T, n int) float64 +``` + +Example:[Run](https://go.dev/play/p/8hOeSADZPCo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.CeilToFloat(3.14159, 1) + result2 := mathutil.CeilToFloat(3.14159, 2) + result3 := mathutil.CeilToFloat(5, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 3.2 + // 3.15 + // 5 +} +``` + +### CeilToString + +Round float up n decimal places.
+ +Signature: + +```go +func CeilToString[T constraints.Float | constraints.Integer](x T, n int) string +``` + +Example:[Run](https://go.dev/play/p/wy5bYEyUKKG) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.CeilToString(3.14159, 1) + result2 := mathutil.CeilToString(3.14159, 2) + result3 := mathutil.CeilToString(5, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 3.2 + // 3.15 + // 5.0000 +} +``` + +### FloorToFloat + +Round float down n decimal places.
+ +Signature: + +```go +func FloorToFloat[T constraints.Float | constraints.Integer](x T, n int) float64 +``` + +Example:[Run](https://go.dev/play/p/vbCBrQHZEED) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.FloorToFloat(3.14159, 1) + result2 := mathutil.FloorToFloat(3.14159, 2) + result3 := mathutil.FloorToFloat(5, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 3.1 + // 3.14 + // 5 +} +``` + +### FloorToString + +Round float down n decimal places.
+ +Signature: + +```go +func FloorToString[T constraints.Float | constraints.Integer](x T, n int) string +``` + +Example:[Run](https://go.dev/play/p/Qk9KPd2IdDb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.FloorToString(3.14159, 1) + result2 := mathutil.FloorToString(3.14159, 2) + result3 := mathutil.FloorToString(5, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 3.1 + // 3.14 + // 5.0000 +} +``` + +### Range + +Creates a slice of numbers from start with specified count, element step is 1.
+ +Signature: + +```go +func Range[T constraints.Integer | constraints.Float](start T, count int) []T +``` + +Example:[Run](https://go.dev/play/p/9ke2opxa8ZP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Range(1, 4) + result2 := mathutil.Range(1, -4) + result3 := mathutil.Range(-4, 4) + result4 := mathutil.Range(1.0, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [1 2 3 4] + // [1 2 3 4] + // [-4 -3 -2 -1] + // [1 2 3 4] +} +``` + +### RangeWithStep + +Creates a slice of numbers from start to end with specified step.
+ +Signature: + +```go +func RangeWithStep[T constraints.Integer | constraints.Float](start, end, step T) []T +``` + +Example:[Run](https://go.dev/play/p/akLWz0EqOSM) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.RangeWithStep(1, 4, 1) + result2 := mathutil.RangeWithStep(1, -1, 0) + result3 := mathutil.RangeWithStep(-4, 1, 2) + result4 := mathutil.RangeWithStep(1.0, 4.0, 1.1) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [1 2 3] + // [] + // [-4 -2 0] + // [1 2.1 3.2] +} +``` + +### AngleToRadian + +Converts angle value to radian value.
+ +Signature: + +```go +func AngleToRadian(angle float64) float64 +``` + +Example:[Run](https://go.dev/play/p/CIvlICqrHql) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.AngleToRadian(45) + result2 := mathutil.AngleToRadian(90) + result3 := mathutil.AngleToRadian(180) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 0.7853981633974483 + // 1.5707963267948966 + // 3.141592653589793 +} +``` + +### RadianToAngle + +Converts radian value to angle value.
+ +Signature: + +```go +func RadianToAngle(radian float64) float64 +``` + +Example:[Run](https://go.dev/play/p/dQtmOTUOMgi) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.RadianToAngle(math.Pi) + result2 := mathutil.RadianToAngle(math.Pi / 2) + result3 := mathutil.RadianToAngle(math.Pi / 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 180 + // 90 + // 45 +} +``` + +### PointDistance + +Caculates two points distance.
+ +Signature: + +```go +func PointDistance(x1, y1, x2, y2 float64) float64 +``` + +Example:[Run](https://go.dev/play/p/RrG4JIaziM8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.PointDistance(1, 1, 4, 5) + + fmt.Println(result1) + + // Output: + // 5 +} +``` + +### IsPrime + +Checks if number is prime number.
+ +Signature: + +```go +func IsPrime(n int) bool +``` + +Example:[Run](https://go.dev/play/p/Rdd8UTHZJ7u) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.IsPrime(-1) + result2 := mathutil.IsPrime(0) + result3 := mathutil.IsPrime(1) + result4 := mathutil.IsPrime(2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // false + // true +} +``` + +### GCD + +Return greatest common divisor (GCD) of integers.
+ +Signature: + +```go +func GCD[T constraints.Integer](integers ...T) T +``` + +Example:[Run](https://go.dev/play/p/CiEceLSoAKB) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.GCD(1, 1) + result2 := mathutil.GCD(1, -1) + result3 := mathutil.GCD(-1, 1) + result4 := mathutil.GCD(-1, -1) + result5 := mathutil.GCD(3, 6, 9) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // 1 + // 1 + // -1 + // -1 + // 3 +} +``` + +### LCM + +Return Least Common Multiple (LCM) of integers.
+ +Signature: + +```go +func LCM[T constraints.Integer](integers ...T) T +``` + +Example:[Run](https://go.dev/play/p/EjcZxfY7G_g) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.LCM(1, 1) + result2 := mathutil.LCM(1, 2) + result3 := mathutil.LCM(3, 6, 9) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 1 + // 2 + // 18 +} +``` + +### Cos + +Returns the cosine of the radian argument.
+ +Signature: + +```go +func Cos(radian float64, precision ...int) float64 +``` + +Example:[Run](https://go.dev/play/p/Sm89LoIfvFq) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Cos(0) + result2 := mathutil.Cos(90) + result3 := mathutil.Cos(180) + result4 := mathutil.Cos(math.Pi) + result5 := mathutil.Cos(math.Pi / 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // 1 + // -0.447 + // -0.598 + // -1 + // 0 +} +``` + +### Sin + +Returns the sine of the radian argument.
+ +Signature: + +```go +func Sin(radian float64, precision ...int) float64 +``` + +Example:[Run](https://go.dev/play/p/TWMQlMywDsP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Sin(0) + result2 := mathutil.Sin(90) + result3 := mathutil.Sin(180) + result4 := mathutil.Sin(math.Pi) + result5 := mathutil.Sin(math.Pi / 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // 0 + // 0.894 + // -0.801 + // 0 + // 1 +} +``` + +### Log + +Returns the logarithm of base n.
+ +Signature: + +```go +func Log(n, base float64) float64 +``` + +Example:[Run](https://go.dev/play/p/_d4bi8oyhat) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Log(8, 2) + result2 := mathutil.TruncRound(mathutil.Log(5, 2), 2) + result3 := mathutil.TruncRound(mathutil.Log(27, 3), 0) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 3 + // 2.32 + // 3 +} +``` + +### Sum + +Returns sum of passed numbers.
+ +Signature: + +```go +func Sum[T constraints.Integer | constraints.Float](numbers ...T) T +``` + +Example:[Run](https://go.dev/play/p/1To2ImAMJA7) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Sum(1, 2) + result2 := mathutil.Sum(0.1, float64(1)) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 3 + // 1.1 +} +``` + +### Abs + +Returns the absolute value of x.
+ +Signature: + +```go +func Abs[T constraints.Integer | constraints.Float](x T) T +``` + +Example:[Run](https://go.dev/play/p/fsyBh1Os-1d) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Abs(-1) + result2 := mathutil.Abs(-0.1) + result3 := mathutil.Abs(float32(0.2)) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 1 + // 0.1 + // 0.2 +} +``` + +### Div + +Returns the result of x divided by y.
+ +Signature: + +```go +func Div[T constraints.Float | constraints.Integer](x T, y T) float64 +``` + +Example:[Run](https://go.dev/play/p/WLxDdGXXYat) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Div(9, 4) + result2 := mathutil.Div(1, 2) + result3 := mathutil.Div(0, 666) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + // Output: + // 2.25 + // 0.5 + // 0 +} +``` + +### Variance + +Returns the variance of numbers.
+ +Signature: + +```go +func Variance[T constraints.Float | constraints.Integer](numbers []T) float64 +``` + +Example:[Run](https://go.dev/play/p/uHuV4YgXf8F) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Variance([]int{1, 2, 3, 4, 5}) + result2 := mathutil.Variance([]float64{1.1, 2.2, 3.3, 4.4, 5.5}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 2 + // 2.42 +} +``` + +### StdDev + +Returns the standard deviation of numbers.
+ +Signature: + +```go +func StdDev[T constraints.Float | constraints.Integer](numbers []T) float64 +``` + +Example:[Run](https://go.dev/play/p/FkNZDXvHD2l) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.TruncRound(mathutil.StdDev([]int{1, 2, 3, 4, 5}), 2) + result2 := mathutil.TruncRound(mathutil.StdDev([]float64{1.1, 2.2, 3.3, 4.4, 5.5}), 2) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1.41 + // 1.55 +} +``` + +### Permutation + +Calculates P(n, k).
+ +Signature: + +```go +func Permutation(n, k uint) uint +``` + +Example:[Run](https://go.dev/play/p/MgobwH_FOxj) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Permutation(5, 3) + result2 := mathutil.Permutation(5, 5) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 60 + // 120 +} +``` + +### Combination + +Calculates C(n, k).
+ +Signature: + +```go +func Combination(n, k uint) uint +``` + +Example:[Run](https://go.dev/play/p/ENFQRDQUFi9) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.Combination(5, 3) + result2 := mathutil.Combination(5, 5) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 10 + // 1 +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/netutil.md b/docs/en/api/packages/netutil.md new file mode 100644 index 00000000..6b4cf236 --- /dev/null +++ b/docs/en/api/packages/netutil.md @@ -0,0 +1,1115 @@ +# Netutil + +Package netutil contains functions to get net information and send http request. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go) + +- [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/netutil" +) +``` + + + +## Index + +- [ConvertMapToQueryString](#ConvertMapToQueryString) +- [EncodeUrl](#EncodeUrl) +- [GetInternalIp](#GetInternalIp) +- [GetIps](#GetIps) +- [GetMacAddrs](#GetMacAddrs) +- [GetPublicIpInfo](#GetPublicIpInfo) +- [GetRequestPublicIp](#GetRequestPublicIp) +- [IsPublicIP](#IsPublicIP) +- [IsInternalIP](#IsInternalIP) +- [HttpRequest](#HttpRequest) +- [HttpClient](#HttpClient) +- [SendRequest](#SendRequest) +- [DecodeResponse](#DecodeResponse) +- [StructToUrlValues](#StructToUrlValues) +- [HttpGetDeprecated](#HttpGet) +- [HttpDeleteDeprecated](#HttpDelete) +- [HttpPostDeprecated](#HttpPost) +- [HttpPutDeprecated](#HttpPut) +- [HttpPatchDeprecated](#HttpPatch) +- [ParseHttpResponse](#ParseHttpResponse) +- [DownloadFile](#DownloadFile) +- [UploadFile](#UploadFile) +- [IsPingConnected](#IsPingConnected) +- [IsTelnetConnected](#IsTelnetConnected) +- [BuildUrl](#BuildUrl) +- [AddQueryParams](#AddQueryParams) + + + + + +## Documentation + +### ConvertMapToQueryString + +Convert map to url query string.
+ +Signature: + +```go +func ConvertMapToQueryString(param map[string]any) string +``` + +Example:[Run](https://go.dev/play/p/jnNt_qoSnRi) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + var m = map[string]any{ + "c": 3, + "a": 1, + "b": 2, + } + qs := netutil.ConvertMapToQueryString(m) + + // Output: + // a=1&b=2&c=3 +} +``` + +### EncodeUrl + +Encode url query string values.
+ +Signature: + +```go +func EncodeUrl(urlStr string) (string, error) +``` + +Example:[Run](https://go.dev/play/p/bsZ6BRC4uKI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + urlAddr := "http://www.lancet.com?a=1&b=[2]" + encodedUrl, err := netutil.EncodeUrl(urlAddr) + + if err != nil { + fmt.Println(err) + } + + fmt.Println(encodedUrl) + + // Output: + // http://www.lancet.com?a=1&b=%5B2%5D +} +``` + +### GetInternalIp + +Get internal ip information.
+ +Signature: + +```go +func GetInternalIp() string +``` + +Example:[Run](https://go.dev/play/p/5mbu-gFp7ei) + +```go +package main + +import ( + "fmt" + "net" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + internalIp := netutil.GetInternalIp() + ip := net.ParseIP(internalIp) + + fmt.Println(ip) + + // Output: + // 192.168.1.9 +} +``` + +### GetIps + +Get all ipv4 list.
+ +Signature: + +```go +func GetIps() []string +``` + +Example:[Run](https://go.dev/play/p/NUFfcEmukx1) + +```go +package main + +import ( + "fmt" + "net" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + ips := netutil.GetIps() + fmt.Println(ips) + + // Output: + // [192.168.1.9] +} +``` + +### GetMacAddrs + +Get all mac addresses list.
+ +Signature: + +```go +func GetMacAddrs() []string { +``` + +Example:[Run](https://go.dev/play/p/Rq9UUBS_Xp1) + +```go +package main + +import ( + "fmt" + "net" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + macAddrs := netutil.GetMacAddrs() + fmt.Println(macAddrs) + + // Output: + // [18:31:bf:09:d1:56 76:ee:2a:e6:2e:0f 74:ee:2a:e6:2e:0f 74:ee:2a:e6:2e:0f] +} +``` + +### GetPublicIpInfo + +Get public ip information.
+ +Signature: + +```go +func GetPublicIpInfo() (*PublicIpInfo, error) +type PublicIpInfo struct { + Status string `json:"status"` + Country string `json:"country"` + CountryCode string `json:"countryCode"` + Region string `json:"region"` + RegionName string `json:"regionName"` + City string `json:"city"` + Lat float64 `json:"lat"` + Lon float64 `json:"lon"` + Isp string `json:"isp"` + Org string `json:"org"` + As string `json:"as"` + Ip string `json:"query"` +} +``` + +Example:[Run](https://go.dev/play/p/YDxIfozsRHR) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + publicIpInfo, err := netutil.GetPublicIpInfo() + if err != nil { + fmt.Println(err) + } + + fmt.Println(publicIpInfo) +} +``` + +### GetRequestPublicIp + +Get http request public ip.
+ +Signature: + +```go +func GetRequestPublicIp(req *http.Request) string +``` + +Example:[Run](https://go.dev/play/p/kxU-YDc_eBo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + ip := "36.112.24.10" + + request := http.Request{ + Method: "GET", + Header: http.Header{ + "X-Forwarded-For": {ip}, + }, + } + publicIp := netutil.GetRequestPublicIp(&request) + + fmt.Println(publicIp) + + // Output: + // 36.112.24.10 +} +``` + +### IsPublicIP + +Checks if an ip is public or not.
+ +Signature: + +```go +func IsPublicIP(IP net.IP) bool +``` + +Example:[Run](https://go.dev/play/p/nmktSQpJZnn) + +```go +package main + +import ( + "fmt" + "net" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + ip1 := netutil.IsPublicIP(net.ParseIP("127.0.0.1")) + ip2 := netutil.IsPublicIP(net.ParseIP("192.168.0.1")) + ip3 := netutil.IsPublicIP(net.ParseIP("36.112.24.10")) + + fmt.Println(ip1) + fmt.Println(ip2) + fmt.Println(ip3) + + // Output: + // false + // false + // true +} +``` + +### IsInternalIP + +Checks if an ip is intranet or not.
+ +Signature: + +```go +func IsInternalIP(IP net.IP) bool +``` + +Example:[Run](https://go.dev/play/p/sYGhXbgO4Cb) + +```go +package main + +import ( + "fmt" + "net" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + ip1 := netutil.IsInternalIP(net.ParseIP("127.0.0.1")) + ip2 := netutil.IsInternalIP(net.ParseIP("192.168.0.1")) + ip3 := netutil.IsInternalIP(net.ParseIP("36.112.24.10")) + + fmt.Println(ip1) + fmt.Println(ip2) + fmt.Println(ip3) + + // Output: + // true + // true + // false +} +``` + +### HttpRequest + +HttpRequest is a struct used to abstract HTTP request entity.
+ +Signature: + +```go +type HttpRequest struct { + RawURL string + Method string + Headers http.Header + QueryParams url.Values + FormData url.Values + Body []byte +} +``` + +Example:[Run](https://go.dev/play/p/jUSgynekH7G) + +```go +package main + +import ( + "fmt" + "net" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + header := http.Header{} + header.Add("Content-Type", "multipart/form-data") + + postData := url.Values{} + postData.Add("userId", "1") + postData.Add("title", "testItem") + + request := &netutil.HttpRequest{ + RawURL: "https://jsonplaceholder.typicode.com/todos", + Method: "POST", + Headers: header, + FormData: postData, + } +} +``` + +### HttpClient + +HttpClient is a struct used to send HTTP request. It can be instanced with some configurations or none config.
+ +Signature: + +```go +type HttpClient struct { + *http.Client + TLS *tls.Config + Request *http.Request + Config HttpClientConfig +} + +type HttpClientConfig struct { + SSLEnabled bool + TLSConfig *tls.Config + Compressed bool + HandshakeTimeout time.Duration + ResponseTimeout time.Duration + Verbose bool +} + +func NewHttpClient() *HttpClient + +func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient + +``` + +Example:[Run](https://go.dev/play/p/jUSgynekH7G) + +```go +package main + +import ( + "fmt" + "net" + "time" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + httpClientCfg := netutil.HttpClientConfig{ + SSLEnabled: true, + HandshakeTimeout:10 * time.Second + } + httpClient := netutil.NewHttpClientWithConfig(&httpClientCfg) +} +``` + +### SendRequest + +Use HttpClient to send HTTP request.
+ +Signature: + +```go +func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error) +``` + +Example:[Run](https://go.dev/play/p/jUSgynekH7G) + +```go +package main + +import ( + "fmt" + "net" + "time" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + request := &netutil.HttpRequest{ + RawURL: "https://jsonplaceholder.typicode.com/todos/1", + Method: "GET", + } + + httpClient := netutil.NewHttpClient() + resp, err := httpClient.SendRequest(request) + if err != nil || resp.StatusCode != 200 { + return + } + + type Todo struct { + UserId int `json:"userId"` + Id int `json:"id"` + Title string `json:"title"` + Completed bool `json:"completed"` + } + + var todo Todo + err = httpClient.DecodeResponse(resp, &todo) + if err != nil { + return + } + + fmt.Println(todo.Id) + + // Output: + // 1 +} +``` + +### DecodeResponse + +Decode http response into target object.
+ +Signature: + +```go +func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error +``` + +Example:[Run](https://go.dev/play/p/jUSgynekH7G) + +```go +package main + +import ( + "fmt" + "net" + "time" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + request := &netutil.HttpRequest{ + RawURL: "https://jsonplaceholder.typicode.com/todos/1", + Method: "GET", + } + + httpClient := netutil.NewHttpClient() + resp, err := httpClient.SendRequest(request) + if err != nil || resp.StatusCode != 200 { + return + } + + type Todo struct { + UserId int `json:"userId"` + Id int `json:"id"` + Title string `json:"title"` + Completed bool `json:"completed"` + } + + var todo Todo + err = httpClient.DecodeResponse(resp, &todo) + if err != nil { + return + } + + fmt.Println(todo.Id) + + // Output: + // 1 +} +``` + +### StructToUrlValues + +Convert struct to url values, only convert the field which is exported and has `json` tag.
+ +Signature: + +```go +func StructToUrlValues(targetStruct any) url.Values +``` + +Example:[Run](https://go.dev/play/p/pFqMkM40w9z) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + type TodoQuery struct { + Id int `json:"id"` + UserId int `json:"userId"` + Name string `json:"name,omitempty"` + Status string + } + item := TodoQuery{ + Id: 1, + UserId: 123, + Name: "test", + Status: "completed", + } + queryValues := netutil.StructToUrlValues(item) + + fmt.Println(todoValues.Get("id")) + fmt.Println(todoValues.Get("userId")) + fmt.Println(todoValues.Get("name")) + fmt.Println(todoValues.Get("status")) + + // Output: + // 1 + // 123 + // test + // +} +``` + +### HttpGet + +Send http get request.
+ +> ⚠️ This function is deprecated. use `SendRequest` instead. + +Signature: + +```go +// params[0] is header which type should be http.Header or map[string]string, +// params[1] is query param which type should be url.Values or map[string]string, +// params[2] is post body which type should be []byte. +// params[3] is http client which type should be http.Client. +func HttpGet(url string, params ...any) (*http.Response, error) +``` + +Example: + +```go +package main + +import ( + "fmt" + "io/ioutil" + "log" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + url := "https://jsonplaceholder.typicode.com/todos/1" + header := map[string]string{ + "Content-Type": "application/json", + } + + resp, err := netutil.HttpGet(url, header) + if err != nil { + log.Fatal(err) + } + + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println(body) +} +``` + +### HttpPost + +Send http post request.
+ +> ⚠️ This function is deprecated. use `SendRequest` instead. + +Signature: + +```go +// params[0] is header which type should be http.Header or map[string]string, +// params[1] is query param which type should be url.Values or map[string]string, +// params[2] is post body which type should be []byte. +// params[3] is http client which type should be http.Client. +func HttpPost(url string, params ...any) (*http.Response, error) +``` + +Example: + +```go +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + url := "https://jsonplaceholder.typicode.com/todos" + header := map[string]string{ + "Content-Type": "application/x-www-form-urlencoded", + } + + postData := url.Values{} + postData.Add("userId", "1") + postData.Add("title", "TestToDo") + + resp, err := netutil.HttpPost(apiUrl, header, nil, postData) + if err != nil { + log.Fatal(err) + } + + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println(body) +} +``` + +### HttpPut + +Send http put request.
+ +> ⚠️ This function is deprecated. use `SendRequest` instead. + +Signature: + +```go +// params[0] is header which type should be http.Header or map[string]string, +// params[1] is query param which type should be url.Values or map[string]string, +// params[2] is post body which type should be []byte. +// params[3] is http client which type should be http.Client. +func HttpPut(url string, params ...any) (*http.Response, error) +``` + +Example: + +```go +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + url := "https://jsonplaceholder.typicode.com/todos/1" + header := map[string]string{ + "Content-Type": "application/json", + } + type Todo struct { + Id int `json:"id"` + UserId int `json:"userId"` + Title string `json:"title"` + } + todo := Todo{1, 1, "TestPutToDo"} + bodyParams, _ := json.Marshal(todo) + + resp, err := netutil.HttpPut(url, header, nil, bodyParams) + if err != nil { + log.Fatal(err) + } + + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println(body) +} +``` + +### HttpDelete + +Send http delete request.
+ +> ⚠️ This function is deprecated. use `SendRequest` instead. + +Signature: + +```go +// params[0] is header which type should be http.Header or map[string]string, +// params[1] is query param which type should be url.Values or map[string]string, +// params[2] is post body which type should be []byte. +// params[3] is http client which type should be http.Client. +func HttpDelete(url string, params ...any) (*http.Response, error) +``` + +Example: + +```go +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + url := "https://jsonplaceholder.typicode.com/todos/1" + resp, err := netutil.HttpDelete(url) + if err != nil { + log.Fatal(err) + } + + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println(body) +} +``` + +### HttpPatch + +Send http patch request.
+ +> ⚠️ This function is deprecated. use `SendRequest` instead. + +Signature: + +```go +// params[0] is header which type should be http.Header or map[string]string, +// params[1] is query param which type should be url.Values or map[string]string, +// params[2] is post body which type should be []byte. +// params[3] is http client which type should be http.Client. +func HttpPatch(url string, params ...any) (*http.Response, error) +``` + +Example: + +```go +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + url := "https://jsonplaceholder.typicode.com/todos/1" + header := map[string]string{ + "Content-Type": "application/json", + } + type Todo struct { + Id int `json:"id"` + UserId int `json:"userId"` + Title string `json:"title"` + } + todo := Todo{1, 1, "TestPatchToDo"} + bodyParams, _ := json.Marshal(todo) + + resp, err := netutil.HttpPatch(url, header, nil, bodyParams) + if err != nil { + log.Fatal(err) + } + + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println(body) +} +``` + +### ParseHttpResponse + +Decode http response to specified interface.
+ +Signature: + +```go +func ParseHttpResponse(resp *http.Response, obj any) error +``` + +Example: + +```go +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + url := "https://jsonplaceholder.typicode.com/todos/1" + header := map[string]string{ + "Content-Type": "application/json", + } + + resp, err := netutil.HttpGet(url, header) + if err != nil { + log.Fatal(err) + } + + type Todo struct { + Id int `json:"id"` + UserId int `json:"userId"` + Title string `json:"title"` + Completed bool `json:"completed"` + } + + toDoResp := &Todo{} + err = netutil.ParseHttpResponse(resp, toDoResp) + if err != nil { + log.Fatal(err) + } + + fmt.Println(toDoResp) +} +``` + +### DownloadFile + +Download the file exist in url to a local file.
+ +Signature: + +```go +func DownloadFile(filepath string, url string) error +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + err := netutil.DownloadFile("./lancet_logo.jpg", "https://picx.zhimg.com/v2-fc82a4199749de9cfb71e32e54f489d3_720w.jpg?source=172ae18b") + + fmt.Println(err) +} +``` + +### UploadFile + +Upload the file to a server.
+ +Signature: + +```go +func UploadFile(filepath string, server string) (bool, error) +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + ok, err := netutil.UploadFile("./a.jpg", "http://www.xxx.com/bucket/test") + + fmt.Println(ok) + fmt.Println(err) +} +``` + +### IsPingConnected + +checks if can ping the specified host or not.
+ +Signature: + +```go +func IsPingConnected(host string) bool +``` + +Example:[Run](https://go.dev/play/p/q8OzTijsA87) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + result1 := netutil.IsPingConnected("www.baidu.com") + result2 := netutil.IsPingConnected("www.!@#&&&.com") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsTelnetConnected + +Checks if can telnet the specified host or not.
+ +Signature: + +```go +func IsTelnetConnected(host string, port string) bool +``` + +Example:[Run](https://go.dev/play/p/yiLCGtQv_ZG) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + result1 := netutil.IsTelnetConnected("www.baidu.com", "80") + result2 := netutil.IsTelnetConnected("www.baidu.com", "123") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### BuildUrl + +Builds a URL from the given params.
+ +Signature: + +```go +func BuildUrl(scheme, host, path string, query map[string][]string) (string, error) +``` + +Example:[Run](https://go.dev/play/p/JLXl1hZK7l4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + urlStr, err := netutil.BuildUrl( + "https", + "example.com", + "query", + map[string][]string{ + "a": {"foo", "bar"}, + "b": {"baz"}, + }, + ) + + fmt.Println(urlStr) + fmt.Println(err) + + // Output: + // https://example.com/query?a=foo&a=bar&b=baz + //Adds query parameters to the given URL.
+ +Signature: + +```go +func AddQueryParams(urlStr string, params map[string][]string) (string, error) +``` + +Example:[Run](https://go.dev/play/p/JLXl1hZK7l4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/netutil" +) + +func main() { + urlStr, err := netutil.BuildUrl( + "https", + "example.com", + "query", + map[string][]string{ + "a": {"foo", "bar"}, + "b": {"baz"}, + }, + ) + + fmt.Println(urlStr) + fmt.Println(err) + + // Output: + // https://example.com/query?a=foo&a=bar&b=baz + //Returns a pointer to the pass value `v`.
+ +Signature: + +```go +func Of[T any](v T) *T +``` + +Example:[Run](https://go.dev/play/p/HFd70x4DrMj) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/pointer" +) + +func main() { + result1 := pointer.Of(123) + result2 := pointer.Of("abc") + + fmt.Println(*result1) + fmt.Println(*result2) + + // Output: + // 123 + // abc +} +``` + + +### Unwrap + +Returns the value from the pointer.
+ +Signature: + +```go +func Unwrap[T any](p *T) T +``` + +Example:[Run](https://go.dev/play/p/cgeu3g7cjWb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/pointer" +) + +func main() { + a := 123 + b := "abc" + + result1 := pointer.Unwrap(&a) + result2 := pointer.Unwrap(&b) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 123 + // abc +} +``` + + +### UnwrapOr + +Returns the value from the pointer or fallback if the pointer is nil.
+ +Signature: +```go +UnwrapOr[T any](p *T, fallback T) T +``` + +Example:[Run](https://go.dev/play/p/mmNaLC38W8C) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/pointer" +) + +func main() { + a := 123 + b := "abc" + + var c *int + var d *string + + result1 := pointer.UnwrapOr(&a, 456) + result2 := pointer.UnwrapOr(&b, "abc") + result3 := pointer.UnwrapOr(c, 456) + result4 := pointer.UnwrapOr(d, "def") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 123 + // abc + // 456 + // def +} +``` + + +### UnwrapOrDefault + +Returns the value from the pointer or the default value if the pointer is nil.
+ +Signature: +```go +UnwrapOrDefault[T any](p *T) T +``` + +Example:[Run](https://go.dev/play/p/ZnGIHf8_o4E) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/pointer" +) + +func main() { + a := 123 + b := "abc" + + var c *int + var d *string + + result1 := pointer.UnwrapOrDefault(&a) + result2 := pointer.UnwrapOrDefault(&b) + result3 := pointer.UnwrapOrDefault(c) + result4 := pointer.UnwrapOrDefault(d) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 123 + // abc + // 0 + // +} +``` + + +### ExtractPointer + +Returns the underlying value by the given interface type
+ +Signature: + +```go +func ExtractPointer(value any) any +``` + +Example:[Run](https://go.dev/play/p/D7HFjeWU2ZP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/pointer" +) + +func main() { + a := 1 + b := &a + c := &b + d := &c + + result := pointer.ExtractPointer(d) + + fmt.Println(result) + + // Output: + // 1 +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/random.md b/docs/en/api/packages/random.md new file mode 100644 index 00000000..9ef15926 --- /dev/null +++ b/docs/en/api/packages/random.md @@ -0,0 +1,553 @@ +# Random + +Package random implements some basic functions to generate random int and string. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/random" +) +``` + + + +## Index + +- [RandBytes](#RandBytes) +- [RandInt](#RandInt) +- [RandString](#RandString) +- [RandFromGivenSlice](#RandFromGivenSlice) +- [RandSliceFromGivenSlice](#RandSliceFromGivenSlice) +- [RandUpper](#RandUpper) +- [RandLower](#RandLower) +- [RandNumeral](#RandNumeral) +- [RandNumeralOrLetter](#RandNumeralOrLetter) +- [RandSymbolChar](#RandSymbolChar) +- [UUIdV4](#UUIdV4) +- [RandIntSlice](#RandIntSlice) +- [RandUniqueIntSlice](#RandUniqueIntSlice) +- [RandFloat](#RandFloat) +- [RandFloats](#RandFloats) +- [RandStringSlice](#RandStringSlice) +- [RandBool](#RandBool) +- [RandBoolSlice](#RandBoolSlice) +- [RandNumberOfLength](#RandNumberOfLength) + + + +## Documentation + +### RandBytes + +Generate random byte slice.
+ +Signature: + +```go +func RandBytes(length int) []byte +``` + +Example:[Run](https://go.dev/play/p/EkiLESeXf8d) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randBytes := random.RandBytes(4) + fmt.Println(randBytes) +} +``` + +### RandInt + +Generate random int between min and max, may contain min, not max.
+ +Signature: + +```go +func RandInt(min, max int) int +``` + +Example:[Run](https://go.dev/play/p/pXyyAAI5YxD) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + rInt := random.RandInt(1, 10) + fmt.Println(rInt) +} +``` + +### RandString + +Generate random given length string. only contains letter (a-zA-Z)
+ +Signature: + +```go +func RandString(length int) string +``` + +Example:[Run](https://go.dev/play/p/W2xvRUXA7Mi) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randStr := random.RandString(6) + fmt.Println(randStr) //pGWsze +} +``` + +### RandFromGivenSlice + +Generate a random element from given slice.
+ +Signature: + +```go +func RandFromGivenSlice[T any](slice []T) T +``` + +Example:[Run](https://go.dev/play/p/UrkWueF6yYo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randomSet := []any{"a", 8, "hello", true, 1.1} + randElm := random.RandFromGivenSlice(randomSet) + fmt.Println(randElm) +} +``` + +### RandSliceFromGivenSlice + +Generate a random slice of length num from given slice.
+ +Signature: + +```go +func RandSliceFromGivenSlice[T any](slice []T, num int, repeatable bool) []T +``` + +Example:[Run](https://go.dev/play/p/68UikN9d6VT) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + goods := []string{"apple", "banana", "cherry", "elderberry", "fig", "grape", "honeydew", "kiwi", "lemon", "mango", "nectarine", "orange"} + + chosen3goods := random.RandSliceFromGivenSlice(goods, 3, false) + + fmt.Println(chosen3goods) +} +``` + +### RandUpper + +Generate a random upper case string
+ +Signature: + +```go +func RandUpper(length int) string +``` + +Example:[Run](https://go.dev/play/p/29QfOh0DVuh) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randStr := random.RandString(6) + fmt.Println(randStr) //PACWGF +} +``` + +### RandLower + +Generate a random lower case string
+ +Signature: + +```go +func RandLower(length int) string +``` + +Example:[Run](https://go.dev/play/p/XJtZ471cmtI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randStr := random.RandLower(6) + fmt.Println(randStr) //siqbew +} +``` + +### RandNumeral + +Generate a random numeral string
+ +Signature: + +```go +func RandNumeral(length int) string +``` + +Example:[Run](https://go.dev/play/p/g4JWVpHsJcf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randStr := random.RandNumeral(6) + fmt.Println(randStr) //035172 +} +``` + +### RandNumeralOrLetter + +generate a random numeral or letter string
+ +Signature: + +```go +func RandNumeralOrLetter(length int) string +``` + +Example:[Run](https://go.dev/play/p/19CEQvpx2jD) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randStr := random.RandNumeralOrLetter(6) + fmt.Println(randStr) //0aW7cQ +} +``` + +### RandSymbolChar + +Generate a random symbol char of specified length.
+ +Signature: + +```go +func RandSymbolChar(length int) string +``` + +Example:[Run](https://go.dev/play/p/Im6ZJxAykOm) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + randStr := random.RandSymbolChar(6) + fmt.Println(randStr) // random string like: @#(_") +} +``` + +### UUIdV4 + +Generate a random UUID of version 4 according to RFC 4122.
+ +Signature: + +```go +func UUIdV4() (string, error) +``` + +Example:[Run](https://go.dev/play/p/_Z9SFmr28ft) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + uuid, err := random.UUIdV4() + if err != nil { + return + } + fmt.Println(uuid) +} +``` + +### RandIntSlice + +Generate a slice of random int. Number range in [min, max)
+ +Signature: + +```go +func RandIntSlice(length, min, max int) []int +``` + +Example:[Run](https://go.dev/play/p/GATTQ5xTEG8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + result := random.RandIntSlice(5, 0, 10) + fmt.Println(result) //[1 4 7 1 5] (random) +} +``` + + +### RandUniqueIntSlice + +Generate a slice of random int of length that do not repeat. Number range in [min, max)
+ +Signature: + +```go +func RandUniqueIntSlice(length, min, max int) []int +``` + +Example:[Run](https://go.dev/play/p/uBkRSOz73Ec) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + result := random.RandUniqueIntSlice(5, 0, 10) + fmt.Println(result) //[0 4 7 1 5] (random) +} +``` + +### RandFloat + +Generate a random float64 number between [min, max) with specific precision.
+ +Signature: + +```go +func RandFloat(min, max float64, precision int) float64 +``` + +Example:[Run](https://go.dev/play/p/zbD_tuobJtr) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + floatNumber := random.RandFloat(1.0, 5.0, 2) + fmt.Println(floatNumber) //2.14 (random number) +} +``` + +### RandFloats + +Generate a slice of random float64 numbers of length n that do not repeat. Number range in [min, max)
+ +Signature: + +```go +func RandFloats(length int, min, max float64, precision int) []float64 +``` + +Example:[Run](https://go.dev/play/p/I3yndUQ-rhh) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + floatNumbers := random.RandFloats(5, 1.0, 5.0, 2) + fmt.Println(floatNumbers) //[3.42 3.99 1.3 2.38 4.23] (random) +} +``` + + +### RandStringSlice + +Generate a slice of random string of length strLen based on charset. chartset should be one of the following: random.Numeral, random.LowwerLetters, random.UpperLetters random.Letters, random.SymbolChars, random.AllChars. or a combination of them.
+ +Signature: + +```go +func RandStringSlice(charset string, sliceLen, strLen int) []string +``` + +Example:[Run](https://go.dev/play/p/2_-PiDv3tGn) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + strs := random.RandStringSlice(random.Letters, 4, 6) + fmt.Println(strs) + + // output random string slice like below: + //[CooSMq RUFjDz FAeMPf heRyGv] +} +``` + +### RandBool + +Generate a random boolean value (true or false).
+ +Signature: + +```go +func RandBool() bool +``` + +Example:[Run](https://go.dev/play/p/to6BLc26wBv) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + result := random.RandBool() + fmt.Println(result) // true or false (random) +} +``` + +### RandBoolSlice + +Generates a random boolean slice of specified length.
+ +Signature: + +```go +func RandBoolSlice(length int) []bool +``` + +Example:[Run](https://go.dev/play/p/o-VSjPjnILI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + result := random.RandBoolSlice(2) + fmt.Println(result) // [true false] (random) +} +``` + +### RandNumberOfLength + +Generates a random int number of specified length.
+ +Signature: + +```go +func RandNumberOfLength(len int) int +``` + +Signature:[Run](https://go.dev/play/p/oyZbuV7bu7b) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + i := random.RandNumberOfLength(2) + fmt.Println(i) // 21 (random number of length 2) +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/retry.md b/docs/en/api/packages/retry.md new file mode 100644 index 00000000..56392d6d --- /dev/null +++ b/docs/en/api/packages/retry.md @@ -0,0 +1,464 @@ +# Retry + +Package retry is for executing a function repeatedly until it was successful or canceled by the context. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/retry" +) +``` + + + +## Index + +- [Context](#Context) +- [Retry](#Retry) +- [RetryFunc](#RetryFunc) +- [RetryDuration](#RetryDuration) +- [RetryTimes](#RetryTimes) +- [BackoffStrategy](#BackoffStrategy) +- [RetryWithCustomBackoff](#RetryWithCustomBackoff) +- [RetryWithLinearBackoff](#RetryWithLinearBackoff) +- [RetryWithExponentialWithJitterBackoff](#RetryWithExponentialWithJitterBackoff) + + + +## Documentation + +### Context + +Set retry context config, can cancel the retry with context.
+ +Signature: + +```go +func Context(ctx context.Context) +``` + +Example:[Run](https://go.dev/play/p/xnAOOXv9GkS) + +```go +import ( + "context" + "errors" + "fmt" + "github.com/duke-git/lancet/v2/retry" + "time" +) + +func main() { + ctx, cancel := context.WithCancel(context.TODO()) + + number := 0 + increaseNumber := func() error { + number++ + if number > 3 { + cancel() + } + return errors.New("error occurs") + } + + duration := retry.RetryDuration(time.Microsecond*50) + + retry.Retry(increaseNumber, + duration, + retry.Context(ctx), + ) + + fmt.Println(number) + + // Output: + // 4 +} +``` + +### RetryFunc + +Function that retry executes.
+ +Signature: + +```go +type RetryFunc func() error +``` + +Example:[Run](https://go.dev/play/p/nk2XRmagfVF) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +func main() { + number := 0 + var increaseNumber retry.RetryFunc = func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + duration := retry.RetryDuration(time.Microsecond*50) + + err := retry.Retry(increaseNumber, duration) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` + +### RetryTimes + +Set times of retry. Default times is 5.
+ +Signature: + +```go +func RetryTimes(n uint) +``` + +Example:[Run](https://go.dev/play/p/ssfVeU2SwLO) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +func main() { + number := 0 + + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + err := retry.Retry(increaseNumber, retry.RetryTimes(2)) + if err != nil { + fmt.Println(err) + } + + // Output: + // function main.main.func1 run failed after 2 times retry +} +``` + +### RetryDuration + +Set duration of retries. Default duration is 3 second.
+ +Signature: + +```go +func RetryDuration(d time.Duration) +``` + +Example:[Run](https://go.dev/play/p/nk2XRmagfVF) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +func main() { + number := 0 + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + duration := retry.RetryDuration(time.Microsecond*50) + + err := retry.Retry(increaseNumber, duration) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` + +### Retry + +Executes the retryFunc repeatedly until it was successful or canceled by the context.
+ +Signature: + +```go +func Retry(retryFunc RetryFunc, opts ...Option) error +``` + +Example:[Run](https://go.dev/play/p/nk2XRmagfVF) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +func main() { + number := 0 + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + duration := retry.RetryDuration(time.Microsecond*50) + + err := retry.Retry(increaseNumber, duration) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` + + +### BackoffStrategy + +An interface that defines a method for calculating backoff intervals.
+ +Signature: + +```go +// BackoffStrategy is an interface that defines a method for calculating backoff intervals. +type BackoffStrategy interface { + // CalculateInterval returns the time.Duration after which the next retry attempt should be made. + CalculateInterval() time.Duration +} +``` + +Example: + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +type ExampleCustomBackoffStrategy struct { + interval time.Duration +} + +func (c *ExampleCustomBackoffStrategy) CalculateInterval() time.Duration { + return c.interval + 1 +} + +func main() { + number := 0 + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + err := retry,Retry(increaseNumber, retry.RetryWithCustomBackoff(&ExampleCustomBackoffStrategy{interval: time.Microsecond * 50})) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` + +### RetryWithCustomBackoff + +Set abitary custom backoff strategy.
+ +Signature: + +```go +func RetryWithCustomBackoff(backoffStrategy BackoffStrategy) Option +``` + +Example:[Run](https://go.dev/play/p/jIm_o2vb5Y4) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +type ExampleCustomBackoffStrategy struct { + interval time.Duration +} + +func (c *ExampleCustomBackoffStrategy) CalculateInterval() time.Duration { + return c.interval + 1 +} + +func main() { + number := 0 + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + err := retry.Retry(increaseNumber, retry.RetryWithCustomBackoff(&ExampleCustomBackoffStrategy{interval: time.Microsecond * 50})) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` + + +### RetryWithLinearBackoff + +Set linear strategy backoff.
+ +Signature: + +```go +func RetryWithLinearBackoff(interval time.Duration) Option +``` + +Example:[Run](https://go.dev/play/p/nk2XRmagfVF) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +func main() { + number := 0 + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + err := retry.Retry(increaseNumber, retry.RetryWithLinearBackoff(time.Microsecond*50)) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` + + +### RetryWithExponentialWithJitterBackoff + +Set exponential strategy backoff.
+ +Signature: + +```go +func RetryWithExponentialWithJitterBackoff(interval time.Duration, base uint64, maxJitter time.Duration) Option +``` + +Example:[Run](https://go.dev/play/p/xp1avQmn16X) + +```go +package main + +import ( + "fmt" + "errors" + "log" + "github.com/duke-git/lancet/v2/retry" +) + +func main() { + number := 0 + increaseNumber := func() error { + number++ + if number == 3 { + return nil + } + return errors.New("error occurs") + } + + err := retry.Retry(increaseNumber, retry.RetryWithExponentialWithJitterBackoff(time.Microsecond*50, 2, time.Microsecond*25)) + if err != nil { + return + } + + fmt.Println(number) + + // Output: + // 3 +} +``` diff --git a/docs/en/api/packages/slice.md b/docs/en/api/packages/slice.md new file mode 100644 index 00000000..243981c7 --- /dev/null +++ b/docs/en/api/packages/slice.md @@ -0,0 +1,3160 @@ +# Slice + +Package slice implements some functions to manipulate slice. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go) +- [https://github.com/duke-git/lancet/blob/main/slice/slice_concurrent.go](https://github.com/duke-git/lancet/blob/main/slice/slice_concurrent.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/slice" +) +``` + + + +## Index + +- [AppendIfAbsent](#AppendIfAbsent) +- [Contain](#Contain) +- [ContainBy](#ContainBy) +- [ContainSubSlice](#ContainSubSlice) +- [Chunk](#Chunk) +- [Compact](#Compact) +- [Concat](#Concat) +- [Count](#Count) +- [CountBy](#CountBy) +- [Difference](#Difference) +- [DifferenceBy](#DifferenceBy) +- [DifferenceWith](#DifferenceWith) +- [DeleteAt](#DeleteAt) +- [DeleteRange](#DeleteRange) +- [Drop](#Drop) +- [DropRight](#DropRight) +- [DropWhile](#DropWhile) +- [DropRightWhile](#DropRightWhile) +- [Equal](#Equal) +- [EqualWith](#EqualWith) +- [EqualUnordered](#EqualUnordered) +- [Every](#Every) +- [Filter](#Filter) +- [FilterConcurrent](#FilterConcurrent) +- [Finddeprecated](#Find) +- [FindBy](#FindBy) +- [FindLastdeprecated](#FindLast) +- [FindLastBy](#FindLastBy) +- [Flatten](#Flatten) +- [FlattenDeep](#FlattenDeep) +- [ForEach](#ForEach) +- [ForEachConcurrent](#ForEachConcurrent) +- [ForEachWithBreak](#ForEachWithBreak) +- [GroupBy](#GroupBy) +- [GroupWith](#GroupWith) +- [IntSlicedeprecated](#IntSlice) +- [InterfaceSlicedeprecated](#InterfaceSlice) +- [Intersection](#Intersection) +- [InsertAt](#InsertAt) +- [IndexOf](#IndexOf) +- [LastIndexOf](#LastIndexOf) +- [Map](#Map) +- [MapConcurrent](#MapConcurrent) +- [FilterMap](#FilterMap) +- [FlatMap](#FlatMap) +- [Merge](#Merge) +- [Reverse](#Reverse) +- [ReverseCopy](#ReverseCopy) +- [Reducedeprecated](#Reduce) +- [ReduceConcurrent](#ReduceConcurrent) +- [ReduceBy](#ReduceBy) +- [ReduceRight](#ReduceRight) +- [Replace](#Replace) +- [ReplaceAll](#ReplaceAll) +- [Repeat](#Repeat) +- [Shuffle](#Shuffle) +- [ShuffleCopy](#ShuffleCopy) +- [IsAscending](#IsAscending) +- [IsDescending](#IsDescending) +- [IsSorted](#IsSorted) +- [IsSortedByKey](#IsSortedByKey) +- [Sort](#Sort) +- [SortBy](#SortBy) +- [SortByField](#SortByField) +- [Some](#Some) +- [StringSlicedeprecated](#StringSlice) +- [SymmetricDifference](#SymmetricDifference) +- [ToSlice](#ToSlice) +- [ToSlicePointer](#ToSlicePointer) +- [Unique](#Unique) +- [UniqueBy](#UniqueBy) +- [UniqueByComparator](#UniqueByComparator) +- [UniqueByField](#UniqueByField) +- [UniqueByConcurrent](#UniqueByConcurrent) +- [Union](#Union) +- [UnionBy](#UnionBy) +- [UpdateAt](#UpdateAt) +- [Without](#Without) +- [KeyBy](#KeyBy) +- [Join](#Join) +- [Partition](#Partition) +- [SetToDefaultIf](#SetToDefaultIf) +- [Break](#Break) +- [RightPadding](#RightPadding) +- [LeftPadding](#LeftPadding) +- [Frequency](#Frequency) +- [JoinFunc](#JoinFunc) +- [ConcatBy](#ConcatBy) + + + + + +## Documentation + +### AppendIfAbsent + +If slice doesn't contain the item, append it to the slice.
+ +Signature: + +```go +func AppendIfAbsent[T comparable](slice []T, item T) []T +``` + +Example:[Run](https://go.dev/play/p/GNdv7Jg2Taj) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.AppendIfAbsent([]string{"a", "b"}, "b") + result2 := slice.AppendIfAbsent([]string{"a", "b"}, "c") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // [a b] + // [a b c] +} +``` + +### Contain + +Check if the target value is in the slice or not.
+ +Signature: + +```go +func Contain[T comparable](slice []T, target T) bool +``` + +Example:[Run](https://go.dev/play/p/_454yEHcNjf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.Contain([]string{"a", "b", "c"}, "a") + result2 := slice.Contain([]int{1, 2, 3}, 4) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### ContainBy + +returns true if predicate function return true.
+ +Signature: + +```go +func ContainBy[T any](slice []T, predicate func(item T) bool) bool +``` + +Example:[Run](https://go.dev/play/p/49tkHfX4GNc) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + type foo struct { + A string + B int + } + + array1 := []foo{{A: "1", B: 1}, {A: "2", B: 2}} + result1 := slice.ContainBy(array1, func(f foo) bool { return f.A == "1" && f.B == 1 }) + result2 := slice.ContainBy(array1, func(f foo) bool { return f.A == "2" && f.B == 1 }) + + array2 := []string{"a", "b", "c"} + result3 := slice.ContainBy(array2, func(t string) bool { return t == "a" }) + result4 := slice.ContainBy(array2, func(t string) bool { return t == "d" }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // false + // true + // false +} +``` + +### ContainSubSlice + +Check if the slice contain subslice or not.
+ +Signature: + +```go +func ContainSubSlice[T comparable](slice, subSlice []T) bool +``` + +Example:[Run](https://go.dev/play/p/bcuQ3UT6Sev) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.ContainSubSlice([]string{"a", "b", "c"}, []string{"a", "b"}) + result2 := slice.ContainSubSlice([]string{"a", "b", "c"}, []string{"a", "d"}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### Chunk + +Creates an slice of elements split into groups the length of `size`.
+ +Signature: + +```go +func Chunk[T any](slice []T, size int) [][]T +``` + +Example:[Run](https://go.dev/play/p/b4Pou5j2L_C) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + arr := []string{"a", "b", "c", "d", "e"} + + result1 := slice.Chunk(arr, 1) + result2 := slice.Chunk(arr, 2) + result3 := slice.Chunk(arr, 3) + result4 := slice.Chunk(arr, 4) + result5 := slice.Chunk(arr, 5) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // [[a] [b] [c] [d] [e]] + // [[a b] [c d] [e]] + // [[a b c] [d e]] + // [[a b c d] [e]] + // [[a b c d e]] +} +``` + +### Compact + +Creates an slice with all falsey values removed. The values false, nil, 0, and "" are falsey.
+ +Signature: + +```go +func Compact[T comparable](slice []T) []T +``` + +Example:[Run](https://go.dev/play/p/pO5AnxEr3TK) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.Compact([]int{0}) + result2 := slice.Compact([]int{0, 1, 2, 3}) + result3 := slice.Compact([]string{"", "a", "b", "0"}) + result4 := slice.Compact([]bool{false, true, true}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [] + // [1 2 3] + // [a b 0] + // [true true] +} +``` + +### Concat + +Concat creates a new slice concatenating slice with any additional slices.
+ +Signature: + +```go +func Concat[T any](slices ...[]T) []T +``` + +Example:[Run](https://go.dev/play/p/gPt-q7zr5mk) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.Concat([]int{1, 2}, []int{3, 4}) + result2 := slice.Concat([]string{"a", "b"}, []string{"c"}, []string{"d"}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // [1 2 3 4] + // [a b c d] +} +``` + +### Count + +Returns the number of occurrences of the given item in the slice.
+ +Signature: + +```go +func Count[T comparable](slice []T, item T) int +``` + +Example:[Run](https://go.dev/play/p/Mj4oiEnQvRJ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 3, 4} + + result1 := slice.Count(nums, 1) + result2 := slice.Count(nums, 3) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1 + // 2 +} +``` + +### CountBy + +Iterates over elements of slice with predicate function, returns the number of all matched elements.
+ +Signature: + +```go +func CountBy[T any](slice []T, predicate func(index int, item T) bool) int +``` + +Example:[Run](https://go.dev/play/p/tHOccTMDZCC) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result := slice.CountBy(nums, isEven) + + fmt.Println(result) + + // Output: + // 2 +} +``` + +### Difference + +Creates an slice of whose element not included in the other given slice.
+ +Signature: + +```go +func Difference[T comparable](slice, comparedSlice []T) []T +``` + +Example:[Run](https://go.dev/play/p/VXvadzLzhDa) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + s1 := []int{1, 2, 3, 4, 5} + s2 := []int{4, 5, 6} + + result := slice.Difference(s1, s2) + + fmt.Println(result) + + // Output: + // [1 2 3] +} +``` + +### DifferenceBy + +DifferenceBy accepts iteratee func which is invoked for each element of slice and values to generate the criterion by which they're compared.
+ +Signature: + +```go +func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T +``` + +Example:[Run](https://go.dev/play/p/DiivgwM5OnC) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + s1 := []int{1, 2, 3, 4, 5} + s2 := []int{3, 4, 5} + + addOne := func(i int, v int) int { + return v + 1 + } + + result := slice.DifferenceBy(s1, s2, addOne) + + fmt.Println(result) + + // Output: + // [1 2] +} +``` + +### DifferenceWith + +DifferenceWith accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice.
+ +Signature: + +```go +func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T +``` + +Example:[Run](https://go.dev/play/p/v2U2deugKuV) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + s1 := []int{1, 2, 3, 4, 5} + s2 := []int{4, 5, 6, 7, 8} + + isDouble := func(v1, v2 int) bool { + return v2 == 2*v1 + } + + result := slice.DifferenceWith(s1, s2, isDouble) + + fmt.Println(result) + + // Output: + // [1 5] +} +``` + +### DeleteAt + +Delete delete the element of slice at index.
+ +Signature: + +```go +func DeleteAt[T any](slice []T, index int) +``` + +Example:[Run](https://go.dev/play/p/800B1dPBYyd) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + chars := []string{"a", "b", "c", "d", "e"} + + result1 := slice.DeleteAt(chars, 0) + result2 := slice.DeleteAt(chars, 4) + result3 := slice.DeleteAt(chars, 5) + result4 := slice.DeleteAt(chars, 6) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [b c d e] + // [a b c d] + // [a b c d] + // [a b c d] +} +``` + +### DeleteRange + +Delete the element of slice from start index to end index(exclude)
+ +Signature: + +```go +func DeleteRange[T any](slice []T, start, end int) []T +``` + +Example:[Run](https://go.dev/play/p/945HwiNrnle) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + chars := []string{"a", "b", "c", "d", "e"} + + result1 := slice.DeleteRange(chars, 0, 0) + result2 := slice.DeleteRange(chars, 0, 1) + result3 := slice.DeleteRange(chars, 0, 3) + result4 := slice.DeleteRange(chars, 0, 4) + result5 := slice.DeleteRange(chars, 0, 5) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // [a b c d e] + // [b c d e] + // [d e] + // [e] + // [] + +} +``` + +### Drop + +Drop n elements from the start of a slice.
+ +Signature: + +```go +func Drop[T any](slice []T, n int) []T +``` + +Example:[Run](https://go.dev/play/p/jnPO2yQsT8H) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.Drop([]string{"a", "b", "c"}, 0) + result2 := slice.Drop([]string{"a", "b", "c"}, 1) + result3 := slice.Drop([]string{"a", "b", "c"}, -1) + result4 := slice.Drop([]string{"a", "b", "c"}, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [a b c] + // [b c] + // [a b c] + // [] +} +``` + +### DropRight + +Drop n elements from the end of a slice.
+ +Signature: + +```go +func DropRight[T any](slice []T, n int) []T +``` + +Example:[Run](https://go.dev/play/p/8bcXvywZezG) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.DropRight([]string{"a", "b", "c"}, 0) + result2 := slice.DropRight([]string{"a", "b", "c"}, 1) + result3 := slice.DropRight([]string{"a", "b", "c"}, -1) + result4 := slice.DropRight([]string{"a", "b", "c"}, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [a b c] + // [a b] + // [a b c] + // [] +} +``` + +### DropWhile + +Drop n elements from the start of a slice while predicate function returns true.
+ +Signature: + +```go +func DropWhile[T any](slice []T, predicate func(item T) bool) []T +``` + +Example:[Run](https://go.dev/play/p/4rt252UV_qs) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.DropWhile(numbers, func(n int) bool { + return n != 2 + }) + result2 := slice.DropWhile(numbers, func(n int) bool { + return true + }) + result3 := slice.DropWhile(numbers, func(n int) bool { + return n == 0 + }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // [2 3 4 5] + // [] + // [1 2 3 4 5] +} +``` + +### DropRightWhile + +Drop n elements from the end of a slice while predicate function returns true.
+ +Signature: + +```go +func DropRightWhile[T any](slice []T, predicate func(item T) bool) []T +``` + +Example:[Run](https://go.dev/play/p/6wyK3zMY56e) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + numbers := []int{1, 2, 3, 4, 5} + + result1 := slice.DropRightWhile(numbers, func(n int) bool { + return n != 2 + }) + result2 := slice.DropRightWhile(numbers, func(n int) bool { + return true + }) + result3 := slice.DropRightWhile(numbers, func(n int) bool { + return n == 0 + }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // [1 2] + // [] + // [1 2 3 4 5] +} +``` + +### Equal + +Check if two slices are equal: the same length and all elements' order and value are equal.
+ +Signature: + +```go +func Equal[T comparable](slice1, slice2 []T) bool +``` + +Example:[Run](https://go.dev/play/p/WcRQJ37ifPa) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + s1 := []int{1, 2, 3} + s2 := []int{1, 2, 3} + s3 := []int{1, 3, 2} + + result1 := slice.Equal(s1, s2) + result2 := slice.Equal(s1, s3) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### EqualWith + +Check if two slices are equal with comparator func.
+ +Signature: + +```go +func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool +``` + +Example:[Run](https://go.dev/play/p/b9iygtgsHI1) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + s1 := []int{1, 2, 3} + s2 := []int{2, 4, 6} + + isDouble := func(a, b int) bool { + return b == a*2 + } + + result := slice.EqualWith(s1, s2, isDouble) + + fmt.Println(result) + + // Output: + // true +} +``` + +### EqualUnordered + +Checks if two slices are equal: the same length and all elements value are equal (unordered).
+ +Signature: + +```go +func EqualUnordered[T comparable](slice1, slice2 []T) bool +``` + +Example:[运行](https://go.dev/play/p/n8fSc2w8ZgX) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.EqualUnordered([]int{1, 2, 3}, []int{3, 2, 1}) + result2 := slice.EqualUnordered([]int{1, 2, 3}, []int{4, 5, 6}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### Every + +Return true if all of the values in the slice pass the predicate function.
+ +Signature: + +```go +func Every[T any](slice []T, predicate func(index int, item T) bool) bool +``` + +Example:[Run](https://go.dev/play/p/R8U6Sl-j8cD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result := slice.Every(nums, isEven) + + fmt.Println(result) + + // Output: + // false +} +``` + +### Filter + +Return all elements which match the function.
+ +Signature: + +```go +func Filter[T any](slice []T, predicate func(index int, item T) bool) []T +``` + +Example:[Run](https://go.dev/play/p/SdPna-7qK4T) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result := slice.Filter(nums, isEven) + + fmt.Println(result) + + // Output: + // [2 4] +} +``` + +### FilterConcurrent + +Applies the provided filter function `predicate` to each element of the input slice concurrently.
+ +Signature: + +```go +func FilterConcurrent[T any](slice []T, predicate func(index int, item T) bool, numThreads int) []T +``` + +Example:[Run](https://go.dev/play/p/t_pkwerIRVx) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result := slice.FilterConcurrent(nums, isEven, 2) + + fmt.Println(result) + + // Output: + // [2 4] +} +``` + +### Find + +Iterates over elements of slice, returning the first one that passes a truth test on function.
+ +> ⚠️ This function is deprecated. use `FindBy` instead. + +Signature: + +```go +func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) +``` + +Example:[Run](https://go.dev/play/p/CBKeBoHVLgq) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result, ok := slice.Find(nums, isEven) + + fmt.Println(*result) + fmt.Println(ok) + + // Output: + // 2 + // true +} +``` + +### FindBy + +Iterates over elements of slice, returning the first one that passes a truth test on predicate function.If return T is nil or zero value then no items matched the predicate func. In contrast to Find or FindLast, its return value no longer requires dereferencing.
+ +Signature: + +```go +func FindBy[T any](slice []T, predicate func(index int, item T) bool) (v T, ok bool) +``` + +Example:[Run](https://go.dev/play/p/n1lysBYl-GB) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result, ok := slice.FindBy(nums, isEven) + + fmt.Println(result) + fmt.Println(ok) + + // Output: + // 2 + // true +} +``` + +### FindLast + +iterates over elements of slice from end to begin, returning the last one that passes a truth test on function.
+ +> ⚠️ This function is deprecated. use `FindLastBy` instead. + +Signature: + +```go +func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) +``` + +Example:[Run](https://go.dev/play/p/FFDPV_j7URd) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result, ok := slice.FindLast(nums, isEven) + + fmt.Println(*result) + fmt.Println(ok) + + // Output: + // 4 + // true +} +``` + +### FindLastBy + +FindLastBy iterates over elements of slice, returning the last one that passes a truth test on predicate function. If return T is nil or zero value then no items matched the predicate func. In contrast to Find or FindLast, its return value no longer requires dereferencing.
+ +Signature: + +```go +func FindLastBy[T any](slice []T, predicate func(index int, item T) bool) (v T, ok bool) +``` + +Example:[Run](https://go.dev/play/p/8iqomzyCl_s) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result, ok := slice.FindLastBy(nums, isEven) + + fmt.Println(result) + fmt.Println(ok) + + // Output: + // 4 + // true +} +``` + +### Flatten + +Flatten slice with one level.
+ +Signature: + +```go +func Flatten(slice any) any +``` + +Example:[Run](https://go.dev/play/p/hYa3cBEevtm) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + arrs := [][][]string{{{"a", "b"}}, {{"c", "d"}}} + + result := slice.Flatten(arrs) + + fmt.Println(result) + + // Output: + // [[a b] [c d]] +} +``` + +### FlattenDeep + +flattens slice recursive.
+ +Signature: + +```go +func FlattenDeep(slice any) any +``` + +Example:[Run](https://go.dev/play/p/yjYNHPyCFaF) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + arrs := [][][]string{{{"a", "b"}}, {{"c", "d"}}} + + result := slice.FlattenDeep(arrs) + + fmt.Println(result) + + // Output: + // [a b c d] +} +``` + +### ForEach + +Iterates over elements of slice and invokes function for each element.
+ +Signature: + +```go +func ForEach[T any](slice []T, iteratee func(index int, item T)) +``` + +Example:[Run](https://go.dev/play/p/DrPaa4YsHRF) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3} + + var result []int + addOne := func(_ int, v int) { + result = append(result, v+1) + } + + slice.ForEach(nums, addOne) + + fmt.Println(result) + + // Output: + // [2 3 4] +} +``` + +### ForEachConcurrent + +Applies the iteratee function to each item in the slice concurrently.
+ +Signature: + +```go +func ForEachConcurrent[T any](slice []T, iteratee func(index int, item T), numThreads int) +``` + +Example:[Run](https://go.dev/play/p/kT4XW7DKVoV) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5, 6, 7, 8} + + result := make([]int, len(nums)) + + addOne := func(index int, value int) { + result[index] = value + 1 + } + + slice.ForEachConcurrent(nums, addOne, 4) + + fmt.Println(result) + + // Output: + // [2 3 4 5 6 7 8 9] +} +``` + +### ForEachWithBreak + +Iterates over elements of slice and invokes function for each element, when iteratee return false, will break the for each loop.
+ +Signature: + +```go +func ForEachWithBreak[T any](slice []T, iteratee func(index int, item T) bool) +``` + +Example:[Run](https://go.dev/play/p/qScs39f3D9W) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + numbers := []int{1, 2, 3, 4, 5} + + var sum int + + slice.ForEachWithBreak(numbers, func(_, n int) bool { + if n > 3 { + return false + } + sum += n + return true + }) + + fmt.Println(sum) + + // Output: + // 6 +} +``` + +### GroupBy + +Iterates over elements of the slice, each element will be group by criteria, returns two slices.
+ +Signature: + +```go +func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T) +``` + +Example:[Run](https://go.dev/play/p/QVkPxzPR0iA) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + even, odd := slice.GroupBy(nums, isEven) + + fmt.Println(even) + fmt.Println(odd) + + // Output: + // [2 4] + // [1 3 5] +} +``` + +### GroupWith + +Return a map composed of keys generated from the results of running each element of slice thru iteratee.
+ +Signature: + +```go +func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T +``` + +Example:[Run](https://go.dev/play/p/ApCvMNTLO8a) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []float64{6.1, 4.2, 6.3} + + floor := func(num float64) float64 { + return math.Floor(num) + } + + result := slice.GroupWith(nums, floor) //map[float64][]float64 + + fmt.Println(result) + + // Output: + // map[4:[4.2] 6:[6.1 6.3]] +} +``` + +### IntSlice + +Convert interface slice to int slice.
+ +> ⚠️ This function is deprecated. Use generic feature of go1.18+ for replacement. + +Signature: + +```go +func IntSlice(slice any) []int +``` + +Example:[Run](https://go.dev/play/p/UQDj-on9TGN) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []interface{}{1, 2, 3} + + result := slice.IntSlice(nums) //[]int{1, 2, 3} + fmt.Println(result) + + // Output: + // [1 2 3] +} +``` + +### InterfaceSlice + +Convert value to interface slice.
+ +> ⚠️ This function is deprecated. Use generic feature of go1.18+ for replacement. + +Signature: + +```go +func InterfaceSlice(slice any) []any +``` + +Example:[Run](https://go.dev/play/p/FdQXF0Vvqs-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "b", "c"} + + result := slice.InterfaceSlice(strs) //[]interface{}{"a", "b", "c"} + fmt.Println(result) + + // Output: + // [a b c] +} +``` + +### Intersection + +Creates a slice of unique values that included by all slices.
+ +Signature: + +```go +func Intersection[T comparable](slices ...[]T) []T +``` + +Example:[Run](https://go.dev/play/p/anJXfB5wq_t) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums1 := []int{1, 2, 3} + nums2 := []int{2, 3, 4} + + result := slice.Intersection(nums1, nums2) + + fmt.Println(result) + + // Output: + // [2 3] +} +``` + +### InsertAt + +insert the element into slice at index.
+ +Signature: + +```go +func InsertAt[T any](slice []T, index int, value any) []T +``` + +Example:[Run](https://go.dev/play/p/hMLNxPEGJVE) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.InsertAt([]string{"a", "b", "c"}, 0, "1") + result2 := slice.InsertAt([]string{"a", "b", "c"}, 1, "1") + result3 := slice.InsertAt([]string{"a", "b", "c"}, 2, "1") + result4 := slice.InsertAt([]string{"a", "b", "c"}, 3, "1") + result5 := slice.InsertAt([]string{"a", "b", "c"}, 0, []string{"1", "2", "3"}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // [1 a b c] + // [a 1 b c] + // [a b 1 c] + // [a b c 1] + // [1 2 3 a b c] +} +``` + +### IndexOf + +Returns the index at which the first occurrence of a item is found in a slice or return -1 if the item cannot be found.
+ +Signature: + +```go +func IndexOf[T comparable](slice []T, item T) int +``` + +Example:[Run](https://go.dev/play/p/MRN1f0FpABb) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "a", "b", "c"} + + result1 := slice.IndexOf(strs, "a") + result2 := slice.IndexOf(strs, "d") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // -1 +} +``` + +### LastIndexOf + +Returns the index at which the last occurrence of a item is found in a slice or return -1 if the item cannot be found.
+ +Signature: + +```go +func LastIndexOf[T comparable](slice []T, item T) int +``` + +Example:[Run](https://go.dev/play/p/DokM4cf1IKH) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "a", "b", "c"} + + result1 := slice.LastIndexOf(strs, "a") + result2 := slice.LastIndexOf(strs, "d") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1 + // -1 +} +``` + +### Map + +Creates an slice of values by running each element in slice thru function.
+ +Signature: + +```go +func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U +``` + +Example:[Run](https://go.dev/play/p/biaTefqPquw) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3} + + addOne := func(_ int, v int) int { + return v + 1 + } + + result := slice.Map(nums, addOne) + + fmt.Println(result) + + // Output: + // [2 3 4] +} +``` + +### MapConcurrent + +Applies the iteratee function to each item in the slice by concrrent.
+ +Signature: + +```go +func MapConcurrent[T any, U any](slice []T, iteratee func(index int, item T) U, numThreads int) []U +``` + +Example:[Run](https://go.dev/play/p/H1ehfPkPen0) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5, 6} + + result := slice.MapConcurrent(nums, func(_, n int) int { return n * n }, 4) + + fmt.Println(result) + + // Output: + // [1 4 9 16 25 36] +} +``` + +### FilterMap + +Returns a slice which apply both filtering and mapping to the given slice. iteratee callback function should returntwo values: 1, mapping result. 2, whether the result element should be included or not.
+ +Signature: + +```go +func FilterMap[T any, U any](slice []T, iteratee func(index int, item T) (U, bool)) []U +``` + +Example:[Run](https://go.dev/play/p/J94SZ_9MiIe) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + getEvenNumStr := func(i, num int) (string, bool) { + if num%2 == 0 { + return strconv.FormatInt(int64(num), 10), true + } + return "", false + } + + result := slice.FilterMap(nums, getEvenNumStr) + + fmt.Printf("%#v", result) + + // Output: + // []string{"2", "4"} +} +``` + +### FlatMap + +Manipulates a slice and transforms and flattens it to a slice of another type.
+ +Signature: + +```go +func FlatMap[T any, U any](slice []T, iteratee func(index int, item T) []U) []U +``` + +Example:[Run](https://go.dev/play/p/_QARWlWs1N_F) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4} + + result := slice.FlatMap(nums, func(i int, num int) []string { + s := "hi-" + strconv.FormatInt(int64(num), 10) + return []string{s} + }) + + fmt.Printf("%#v", result) + + // Output: + // []string{"hi-1", "hi-2", "hi-3", "hi-4"} +} +``` + +### Merge + +Merge all given slices into one slice.
+ +> ⚠️ This function is deprecated. use `Concat` instead. + +Signature: + +```go +func Merge[T any](slices ...[]T) []T +``` + +Example:[Run](https://go.dev/play/p/lbjFp784r9N) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums1 := []int{1, 2, 3} + nums2 := []int{3, 4} + + result := slice.Merge(nums1, nums2) + + fmt.Println(result) + + // Output: + // [1 2 3 3 4] +} +``` + +### Reverse + +Reverse the elements order in slice.
+ +Signature: + +```go +func Reverse[T any](slice []T) +``` + +Example:[Run](https://go.dev/play/p/8uI8f1lwNrQ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "b", "c", "d"} + + slice.Reverse(strs) + + fmt.Println(strs) + + // Output: + // [d c b a] +} +``` + +### ReverseCopy + +Return a new slice of element order is reversed to the given slice.
+ +Signature: + +```go +func ReverseCopy[T any](slice []T) []T +``` + +Example:[Run](https://go.dev/play/p/c9arEaP7Cg-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "b", "c", "d"} + + reversedStrs := slice.ReverseCopy(strs) + + fmt.Println(reversedStrs) + fmt.Println(strs) + + // Output: + // [d c b a] + // [a b c d] +} +``` + +### Reduce + +Reduce slice.
+ +> ⚠️ This function is deprecated. use `ReduceBy` instead. + +Signature: + +```go +func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T +``` + +Example:[Run](https://go.dev/play/p/_RfXJJWIsIm) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3} + + sum := func(_ int, v1, v2 int) int { + return v1 + v2 + } + + result := slice.Reduce(nums, sum, 0) + + fmt.Println(result) + + // Output: + // 6 +} +``` + +### ReduceConcurrent + +Reduces the slice to a single value by applying the reducer function to each item in the slice concurrently.
+ +Signature: + +```go +func ReduceConcurrent[T any](slice []T, initial T, reducer func(index int, item T, agg T) T, numThreads int) T +``` + +Example:[运行](https://go.dev/play/p/Tjwe6OtaG07) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + + result := slice.ReduceConcurrent(nums, 0, func(_ int, item, agg int) int { + return agg + item + }, 1) + + fmt.Println(result) + + // Output: + // 55 +} +``` + + +### ReduceBy + +Produces a value from slice by accumulating the result of each element as passed through the reducer function.
+ +Signature: + +```go +func ReduceBy[T any, U any](slice []T, initial U, reducer func(index int, item T, agg U) U) U +``` + +Example:[Run](https://go.dev/play/p/YKDpLi7gtee) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.ReduceBy([]int{1, 2, 3, 4}, 0, func(_ int, item int, agg int) int { + return agg + item + }) + + result2 := slice.ReduceBy([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string { + return agg + fmt.Sprintf("%v", item) + }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 10 + // 1234 +} +``` + +### ReduceRight + +ReduceRight is like ReduceBy, but it iterates over elements of slice from right to left.
+ +Signature: + +```go +func ReduceRight[T any, U any](slice []T, initial U, reducer func(index int, item T, agg U) U) U +``` + +Example:[Run](https://go.dev/play/p/qT9dZC03A1K) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.ReduceRight([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string { + return agg + fmt.Sprintf("%v", item) + }) + + fmt.Println(result) + + // Output: + // 4321 +} +``` + +### Replace + +Returns a copy of the slice with the first n non-overlapping instances of old replaced by new.
+ +Signature: + +```go +func Replace[T comparable](slice []T, old T, new T, n int) []T +``` + +Example:[Run](https://go.dev/play/p/P5mZp7IhOFo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "b", "c", "a"} + + result1 := slice.Replace(strs, "a", "x", 0) + result2 := slice.Replace(strs, "a", "x", 1) + result3 := slice.Replace(strs, "a", "x", 2) + result4 := slice.Replace(strs, "a", "x", 3) + result5 := slice.Replace(strs, "a", "x", -1) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // [a b c a] + // [x b c a] + // [x b c x] + // [x b c x] + // [x b c x] +} +``` + +### ReplaceAll + +Returns a copy of the slice with the first n non-overlapping instances of old replaced by new.
+ +Signature: + +```go +func ReplaceAll[T comparable](slice []T, old T, new T) []T +``` + +Example:[Run](https://go.dev/play/p/CzqXMsuYUrx) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.ReplaceAll([]string{"a", "b", "c", "a"}, "a", "x") + + fmt.Println(result) + + // Output: + // [x b c x] +} +``` + +### Repeat + +Creates a slice with length n whose elements are passed param item.
+ +Signature: + +```go +func Repeat[T any](item T, n int) []T +``` + +Example:[Run](https://go.dev/play/p/1CbOmtgILUU) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.Repeat("a", 3) + + fmt.Println(result) + + // Output: + // [a a a] +} +``` + +### Shuffle + +Creates an slice of shuffled values.
+ +Signature: + +```go +func Shuffle[T any](slice []T) []T +``` + +Example:[Run](https://go.dev/play/p/YHvhnWGU3Ge) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + result := slice.Shuffle(nums) + + fmt.Println(res) + + // Output: + // [3 1 5 4 2] (random order) +} +``` + +### ShuffleCopy + +Return a new slice with elements shuffled.
+ +Signature: + +```go +func ShuffleCopy[T any](slice []T) []T +``` + +Example:[Run](https://go.dev/play/p/vqDa-Gs1vT0) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + result := slice.ShuffleCopy(nums) + + fmt.Println(result) + fmt.Println(nums) + + // Output: + // [3 1 5 4 2] (random order) + // [1 2 3 4 5] +} +``` + +### IsAscending + +Checks if a slice is ascending order.
+ +Signature: + +```go +func IsAscending[T constraints.Ordered](slice []T) bool +``` + +Example:[Run](https://go.dev/play/p/9CtsFjet4SH) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.IsAscending([]int{1, 2, 3, 4, 5}) + result2 := slice.IsAscending([]int{5, 4, 3, 2, 1}) + result3 := slice.IsAscending([]int{2, 1, 3, 4, 5}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsDescending + +Checks if a slice is descending order.
+ +Signature: + +```go +func IsDescending[T constraints.Ordered](slice []T) bool +``` + +Example:[Run](https://go.dev/play/p/U_LljFXma14) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.IsDescending([]int{5, 4, 3, 2, 1}) + result2 := slice.IsDescending([]int{1, 2, 3, 4, 5}) + result3 := slice.IsDescending([]int{2, 1, 3, 4, 5}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsSorted + +Checks if a slice is sorted (ascending or descending).
+ +Signature: + +```go +func IsSorted[T constraints.Ordered](slice []T) bool +``` + +Example:[Run](https://go.dev/play/p/nCE8wPLwSA-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.IsSorted([]int{5, 4, 3, 2, 1}) + result2 := slice.IsSorted([]int{1, 2, 3, 4, 5}) + result3 := slice.IsSorted([]int{2, 1, 3, 4, 5}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### IsSortedByKey + +Checks if a slice is sorted by iteratee function.
+ +Signature: + +```go +func IsSortedByKey[T any, K constraints.Ordered](slice []T, iteratee func(item T) K) bool +``` + +Example:[Run](https://go.dev/play/p/tUoGB7DOHI4) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.IsSortedByKey([]string{"a", "ab", "abc"}, func(s string) int { + return len(s) + }) + result2 := slice.IsSortedByKey([]string{"abc", "ab", "a"}, func(s string) int { + return len(s) + }) + result3 := slice.IsSortedByKey([]string{"abc", "a", "ab"}, func(s string) int { + return len(s) + }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### Sort + +Sorts a slice of any ordered type(number or string), use quick sort algrithm. Default sort order is ascending (asc), if want descending order, set param `sortOrder` to `desc`. Ordered type: number(all ints uints floats) or string.
+ +Signature: + +```go +func Sort[T constraints.Ordered](slice []T, sortOrder ...string) +``` + +Example:[Run](https://go.dev/play/p/V9AVjzf_4Fk) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + numbers := []int{1, 4, 3, 2, 5} + + slice.Sort(numbers) + fmt.Println(numbers) // [1 2 3 4 5] + + slice.Sort(numbers, "desc") + fmt.Println(numbers) // [5 4 3 2 1] + + strings := []string{"a", "d", "c", "b", "e"} + + slice.Sort(strings) + fmt.Println(strings) //[a b c d e} + + slice.Sort(strings, "desc") + fmt.Println(strings) //[e d c b a] +} +``` + +### SortBy + +Sorts the slice in ascending order as determined by the less function. This sort is not guaranteed to be stable.
+ +Signature: + +```go +func SortBy[T any](slice []T, less func(a, b T) bool) +``` + +Example:[Run](https://go.dev/play/p/DAhLQSZEumm) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + numbers := []int{1, 4, 3, 2, 5} + + slice.SortBy(numbers, func(a, b int) bool { + return a < b + }) + fmt.Println(numbers) // [1 2 3 4 5] + + type User struct { + Name string + Age uint + } + + users := []User{ + {Name: "a", Age: 21}, + {Name: "b", Age: 15}, + {Name: "c", Age: 100}} + + slice.SortBy(users, func(a, b User) bool { + return a.Age < b.Age + }) + + fmt.Printf("sort users by age: %v", users) + + // output + // [{b 15} {a 21} {c 100}] +} +``` + +### SortByField + +Sort struct slice by field. Slice element should be struct, `field` param type should be int, uint, string, or bool. Default sort type is ascending (asc), if descending order, set `sortType` param to desc.
+ +Signature: + +```go +func SortByField(slice any, field string, sortType ...string) error +``` + +Example:[Run](https://go.dev/play/p/fU1prOBP9p1) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + type User struct { + Name string + Age uint + } + + users := []User{ + {Name: "a", Age: 21}, + {Name: "b", Age: 15}, + {Name: "c", Age: 100}} + + err := slice.SortByField(users, "Age", "desc") + if err != nil { + return + } + + fmt.Println(users) + + // Output: + // [{c 100} {a 21} {b 15}] +} +``` + +### Some + +Return true if any of the values in the list pass the predicate function.
+ +Signature: + +```go +func Some[T any](slice []T, predicate func(index int, item T) bool) bool +``` + +Example:[Run](https://go.dev/play/p/4pO9Xf9NDGS) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 5} + + isEven := func(i, num int) bool { + return num%2 == 0 + } + + result := slice.Some(nums, isEven) + + fmt.Println(result) + + // Output: + // true +} +``` + +### StringSlice + +Convert interface slice to string slice.
+ +> ⚠️ This function is deprecated. use generic feature of go1.18+ for replacement + +Signature: + +```go +func StringSlice(slice any) []string +``` + +Example:[Run](https://go.dev/play/p/W0TZDWCPFcI) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []interface{}{"a", "b", "c"} + + result := slice.StringSlice(strs) //[]string{"a", "b", "c"} + fmt.Println(result) + + // Output: + // [a b c] +} +``` + +### SymmetricDifference + +Create a slice whose element is in given slices, but not in both slices.
+ +Signature: + +```go +func SymmetricDifference[T comparable](slices ...[]T) []T +``` + +Example:[Run](https://go.dev/play/p/1CbOmtgILUU) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums1 := []int{1, 2, 3} + nums2 := []int{1, 2, 4} + + result := slice.SymmetricDifference(nums1, nums2) + + fmt.Println(result) + + // Output: + // [3 4] +} +``` + +### ToSlice + +Creates a slice of give items.
+ +Signature: + +```go +func ToSlice[T any](items ...T) []T +``` + +Example:[Run](https://go.dev/play/p/YzbzVq5kscN) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.ToSlice("a", "b", "c") + + fmt.Println(result) + + // Output: + // [a b c] +} +``` + +### ToSlicePointer + +Returns a pointer to the slices of a variable parameter transformation
+ +Signature: + +```go +func ToSlicePointer[T any](items ...T) []*T +``` + +Example:[Run](https://go.dev/play/p/gx4tr6_VXSF) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + str1 := "a" + str2 := "b" + + result := slice.ToSlicePointer(str1, str2) + + expect := []*string{&str1, &str2} + + isEqual := reflect.DeepEqual(result, expect) + + fmt.Println(isEqual) + + // Output: + // true +} +``` + +### Unique + +Remove duplicate elements in slice.
+ +Signature: + +```go +func Unique[T comparable](slice []T) []T +``` + +Example:[Run](https://go.dev/play/p/AXw0R3ZTE6a) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.Unique([]string{"a", "a", "b"}) + fmt.Println(result) + + // Output: + // [a b] +} +``` + +### UniqueBy + +Removes duplicate elements from the input slice based on the values returned by the iteratee function. this function maintains the order of the elements.
+ +Signature: + +```go +func UniqueBy[T any, U comparable](slice []T, iteratee func(item T) U) []T +``` + +Example:[Run](https://go.dev/play/p/GY7JE4yikrl) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5, 6} + result := slice.UniqueBy(nums, func(val int) int { + return val % 3 + }) + + fmt.Println(result) + + // Output: + // [1 2 3] +} +``` + +### UniqueByComparator + +Removes duplicate elements from the input slice using the provided comparator function. The function maintains the order of the elements.
+ +Signature: + +```go +func UniqueByComparator[T comparable](slice []T, comparator func(item T, other T) bool) []T +``` + +Example:[Run](https://go.dev/play/p/rwSacr-ZHsR) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/slice" +) + +func main() { + uniqueNums := slice.UniqueByComparator([]int{1, 2, 3, 1, 2, 4, 5, 6, 4}, func(item int, other int) bool { + return item == other + }) + + caseInsensitiveStrings := slice.UniqueByComparator([]string{"apple", "banana", "Apple", "cherry", "Banana", "date"}, func(item string, other string) bool { + return strings.ToLower(item) == strings.ToLower(other) + }) + + fmt.Println(uniqueNums) + fmt.Println(caseInsensitiveStrings) + + // Output: + // [1 2 3 4 5 6] + // [apple banana cherry date] +} +``` + +### UniqueByConcurrent + +Removes duplicate elements from the slice by parallel.
+ +Signature: + +```go +func UniqueByConcurrent[T comparable](slice []T, comparator func(item T, other T) bool, numThreads int) []T +``` + +Example:[Runs](https://go.dev/play/p/wXZ7LcYRMGL) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/slice" +) + +func main() { + nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7} + comparator := func(item int, other int) bool { return item == other } + + result := slice.UniqueByConcurrent(nums,comparator, 4) + + fmt.Println(result) + // Output: + // [1 2 3 4 5 6 7] +} +``` + +### UniqueByField + +Remove duplicate elements in struct slice by struct field.
+ +Signature: + +```go +func UniqueByField[T any](slice []T, field string) ([]T, error) +``` + +Example:[Runs](https://go.dev/play/p/6cifcZSPIGu) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/slice" +) + +func main() { + type User struct { + ID int `json:"id"` + Name string `json:"name"` + } + + users := []User{ + {ID: 1, Name: "a"}, + {ID: 2, Name: "b"}, + {ID: 1, Name: "c"}, + } + + result, err := slice.UniqueByField(users, "ID") + if err != nil { + } + + fmt.Println(result) + + // Output: + // [{1 a} {2 b}] +} +``` + +### Union + +Creates a slice of unique values, in order, from all given slices. using == for equality comparisons.
+ +Signature: + +```go +func Union[T comparable](slices ...[]T) []T +``` + +Example:[Run](https://go.dev/play/p/hfXV1iRIZOf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums1 := []int{1, 3, 4, 6} + nums2 := []int{1, 2, 5, 6} + + result := slice.Union(nums1, nums2) + + fmt.Println(result) + + // Output: + // [1 3 4 6 2 5] +} +``` + +### UnionBy + +UnionBy is like Union, what's more it accepts iteratee which is invoked for each element of each slice.
+ +Signature: + +```go +func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T +``` + +Example:[Run](https://go.dev/play/p/HGKHfxKQsFi) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4} + + divideTwo := func(n int) int { + return n / 2 + } + result := slice.UnionBy(divideTwo, nums) + + fmt.Println(result) + + // Output: + // [1 2 4] +} +``` + +### UpdateAt + +Update the slice element at index. if param index < 0 or index <= len(slice), will return error.
+ +Signature: + +```go +func UpdateAt[T any](slice []T, index int, value T) []T +``` + +Example:[Run](https://go.dev/play/p/f3mh2KloWVm) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.UpdateAt([]string{"a", "b", "c"}, -1, "1") + result2 := slice.UpdateAt([]string{"a", "b", "c"}, 0, "1") + result3 := slice.UpdateAt([]string{"a", "b", "c"}, 1, "1") + result4 := slice.UpdateAt([]string{"a", "b", "c"}, 2, "1") + result5 := slice.UpdateAt([]string{"a", "b", "c"}, 3, "1") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // [a b c] + // [1 b c] + // [a 1 c] + // [a b 1] + // [a b c] +} +``` + +### Without + +Creates a slice excluding all given items.
+ +Signature: + +```go +func Without[T comparable](slice []T, items ...T) []T +``` + +Example:[Run](https://go.dev/play/p/bwhEXEypThg) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.Without([]int{1, 2, 3, 4}, 1, 2) + + fmt.Println(result) + + // Output: + // [3 4] +} +``` + +### KeyBy + +Converts a slice to a map based on a callback function.
+ +Signature: + +```go +func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T +``` + +Example:[Run](https://go.dev/play/p/uXod2LWD1Kg) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.KeyBy([]string{"a", "ab", "abc"}, func(str string) int { + return len(str) + }) + + fmt.Println(result) + + // Output: + // map[1:a 2:ab 3:abc] +} +``` + +### Join + +Join the slice item with specify separator.
+ +Signature: + +```go +func Join[T any](s []T, separator string) string +``` + +Example:[Run](https://go.dev/play/p/huKzqwNDD7V) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + result1 := slice.Join(nums, ",") + result2 := slice.Join(nums, "-") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1,2,3,4,5 + // 1-2-3-4-5 +} +``` + +### Partition + +Partition all slice elements with the evaluation of the given predicate functions.
+ +Signature: + +```go +func Partition[T any](slice []T, predicates ...func(item T) bool) [][]T +``` + +Example:[Run](https://go.dev/play/p/lkQ3Ri2NQhV) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + result1 := slice.Partition(nums) + result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 }) + result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // [[1 2 3 4 5]] + // [[2 4] [1 3 5]] + // [[1 2] [3 4] [5]] +} +``` + +### Random + +Random get a random item of slice, return idx=-1 when slice is empty.
+ +Signature: + +```go +func Random[T any](slice []T) (val T, idx int) +``` + +Example:[Run](https://go.dev/play/p/UzpGQptWppw) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + + val, idx := slice.Random(nums) + if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) { + fmt.Println("okk") + } + // Output: + // okk +} +``` + +### SetToDefaultIf + +Sets elements to their default value if they match the given predicate. It retains the positions of the elements in the slice. It returns slice of T and the count of modified slice items
+ +Signature: + +```go +func SetToDefaultIf[T any](slice []T, predicate func(T) bool) ([]T, int) +``` + +Example:[Run](https://go.dev/play/p/9AXGlPRC0-A) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "b", "a", "c", "d", "a"} + modifiedStrs, count := slice.SetToDefaultIf(strs, func(s string) bool { return "a" == s }) + + fmt.Println(modifiedStrs) + fmt.Println(count) + + // Output: + // [ b c d ] + // 3 +} +``` + +### Break + +Splits a slice into two based on a predicate function. It starts appending to the second slice after the first element that matches the predicate. All elements after the first match are included in the second slice, regardless of whether they match the predicate or not.
+ +Signature: + +```go +func Break[T any](values []T, predicate func(T) bool) ([]T, []T) +``` + +Example:[Run](https://go.dev/play/p/yLYcBTyeQIz) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + even := func(n int) bool { return n%2 == 0 } + + resultEven, resultAfterFirstEven := slice.Break(nums, even) + + fmt.Println(resultEven) + fmt.Println(resultAfterFirstEven) + + // Output: + // [1] + // [2 3 4 5] +} +``` + +### RightPadding + +RightPadding adds padding to the right end of a slice.
+ +Signature: + +```go +func RightPadding[T any](slice []T, paddingValue T, paddingLength int) []T +``` + +Example:[Run](https://go.dev/play/p/0_2rlLEMBXL) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + padded := slice.RightPadding(nums, 0, 3) + fmt.Println(padded) + // Output: + // [1 2 3 4 5 0 0 0] +} +``` + +### LeftPadding + +LeftPadding adds padding to the left begin of a slice.
+ +Signature: + +```go +func LeftPadding[T any](slice []T, paddingValue T, paddingLength int) []T +``` + +Example:[Run](https://go.dev/play/p/jlQVoelLl2k) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + padded := slice.LeftPadding(nums, 0, 3) + fmt.Println(padded) + // Output: + // [0 0 0 1 2 3 4 5] +} +``` + +### Frequency + +Counts the frequency of each element in the slice.
+ +Signature: + +```go +func Frequency[T comparable](slice []T) map[T]int +``` + +Example:[Run](https://go.dev/play/p/CW3UVNdUZOq) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + strs := []string{"a", "b", "b", "c", "c", "c"} + result := slice.Frequency(strs) + + fmt.Println(result) + + // Output: + // map[a:1 b:2 c:3] +} +``` + +### JoinFunc + +Joins the slice elements into a single string with the given separator.
+ +Signature: + +```go +func JoinFunc[T any](slice []T, sep string, transform func(T) T) string +``` + +Example:[Run](https://go.dev/play/p/55ib3SB5fM2) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result := slice.JoinFunc([]string{"a", "b", "c"}, ", ", func(s string) string { + return strings.ToUpper(s) + }) + + fmt.Println(result) + + // Output: + // A, B, C +} +``` + +### ConcatBy + +Concats the elements of a slice into a single value using the provided separator and connector function.
+ +Signature: + +```go +func ConcatBy[T any](slice []T, sep T, connector func(T, T) T) T +``` + +Example:[Run](https://go.dev/play/p/6QcUpcY4UMW) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + type Person struct { + Name string + Age int + } + + people := []Person{ + {Name: "Alice", Age: 30}, + {Name: "Bob", Age: 25}, + {Name: "Charlie", Age: 35}, + } + + sep := Person{Name: " | ", Age: 0} + + personConnector := func(a, b Person) Person { + return Person{Name: a.Name + b.Name, Age: a.Age + b.Age} + } + + result := slice.ConcatBy(people, sep, personConnector) + + fmt.Println(result.Name) + fmt.Println(result.Age) + + // Output: + // Alice | Bob | Charlie + // 90 +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/stream.md b/docs/en/api/packages/stream.md new file mode 100644 index 00000000..23642322 --- /dev/null +++ b/docs/en/api/packages/stream.md @@ -0,0 +1,1007 @@ +# Stream + +Package stream implements a sequence of elements supporting sequential and operations. This package is an experiment to explore if stream in go can work as the way java does. it's feature is very limited. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/stream/stream.go](https://github.com/duke-git/lancet/blob/main/stream/stream.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/stream" +) +``` + + + +## Index + +- [Of](#Of) +- [FromSlice](#FromSlice) +- [FromChannel](#FromChannel) +- [FromRange](#FromRange) +- [Generate](#Generate) +- [Concat](#Concat) +- [Distinct](#Distinct) +- [Filter](#Filter) +- [Map](#Map) +- [Peek](#Peek) +- [Skip](#Skip) +- [Limit](#Limit) +- [Reverse](#Reverse) +- [Range](#Range) +- [Sorted](#Sorted) +- [ForEach](#ForEach) +- [Reduce](#Reduce) +- [FindFirst](#FindFirst) +- [FindLast](#FindLast) +- [Max](#Max) +- [Min](#Min) +- [AllMatch](#AllMatch) +- [AnyMatch](#AnyMatch) +- [NoneMatch](#NoneMatch) +- [Count](#Count) +- [ToSlice](#ToSlice) + + + + +## Documentation + +### Of + +Creates a stream whose elements are the specified values.
+ +Signature: + +```go +func Of[T any](elems ...T) stream[T] +``` + +Example:[Run](https://go.dev/play/p/jI6_iZZuVFE) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s := stream.Of(1, 2, 3) + + data := s.ToSlice() + + fmt.Println(data) + + // Output: + // [1 2 3] +} +``` + +### FromSlice + +Creates a stream from slice.
+ +Signature: + +```go +func FromSlice[T any](source []T) stream[T] +``` + +Example:[Run](https://go.dev/play/p/wywTO0XZtI4) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s := stream.FromSlice([]int{1, 2, 3}) + + data := s.ToSlice() + + fmt.Println(data) + + // Output: + // [1 2 3] +} +``` + +### FromChannel + +Creates a stream from channel.
+ +Signature: + +```go +func FromChannel[T any](source <-chan T) stream[T] +``` + +Example:[Run](https://go.dev/play/p/9TZYugGMhXZ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + ch := make(chan int) + go func() { + for i := 1; i < 4; i++ { + ch <- i + } + close(ch) + }() + + s := stream.FromChannel(ch) + + data := s.ToSlice() + + fmt.Println(data) + + // Output: + // [1 2 3] +} +``` + +### FromRange + +Creates a number stream from start to end. both start and end are included. [start, end]
+ +Signature: + +```go +func FromRange[T constraints.Integer | constraints.Float](start, end, step T) stream[T] +``` + +Example:[Run](https://go.dev/play/p/9Ex1-zcg-B-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s := stream.FromRange(1, 5, 1) + + data := s.ToSlice() + fmt.Println(data) + + // Output: + // [1 2 3 4 5] +} +``` + +### Generate + +Creates a stream where each element is generated by the provided generater function.
+ +Signature: + +```go +func Generate[T any](generator func() func() (item T, ok bool)) stream[T] +``` + +Example:[Run](https://go.dev/play/p/rkOWL1yA3j9) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + n := 0 + max := 4 + + generator := func() func() (int, bool) { + return func() (int, bool) { + n++ + return n, n < max + } + } + + s := stream.Generate(generator) + + data := s.ToSlice() + + fmt.Println(data) + + // Output: + // [1 2 3] +} +``` + +### Concat + +Creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream.
+ +Signature: + +```go +func Concat[T any](a, b stream[T]) stream[T] +``` + +Example:[Run](https://go.dev/play/p/HM4OlYk_OUC) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s1 := stream.FromSlice([]int{1, 2, 3}) + s2 := stream.FromSlice([]int{4, 5, 6}) + + s := Concat(s1, s2) + + data := s.ToSlice() + + fmt.Println(data) + + // Output: + // [1 2 3 4 5 6] +} +``` + +### Distinct + +Creates returns a stream that removes the duplicated items. Support chainable operation
+ +Signature: + +```go +func (s stream[T]) Distinct() stream[T] +``` + +Example:[Run](https://go.dev/play/p/eGkOSrm64cB) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 2, 3, 3, 3}) + distinct := original.Distinct() + + data1 := original.ToSlice() + data2 := distinct.ToSlice() + + fmt.Println(data1) + fmt.Println(data2) + + // Output: + // [1 2 2 3 3 3] + // [1 2 3] +} +``` + +### Filter + +Returns a stream consisting of the elements of this stream that match the given predicate. Support chainable operation
+ +Signature: + +```go +func (s stream[T]) Filter(predicate func(item T) bool) stream[T] +``` + +Example:[Run](https://go.dev/play/p/MFlSANo-buc) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3, 4, 5}) + + isEven := func(n int) bool { + return n%2 == 0 + } + + even := original.Filter(isEven) + + fmt.Println(even.ToSlice()) + + // Output: + // [2 4] +} +``` + +### Map + +Returns a stream consisting of the elements of this stream that apply the given function to elements of stream. Support chainable operation
+ +Signature: + +```go +func (s stream[T]) Map(mapper func(item T) T) stream[T] +``` + +Example:[Run](https://go.dev/play/p/OtNQUImdYko) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + addOne := func(n int) int { + return n + 1 + } + + increament := original.Map(addOne) + + fmt.Println(increament.ToSlice()) + + // Output: + // [2 3 4] +} +``` + +### Peek + +Returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream. Support chainable operation
+ +Signature: + +```go +func (s stream[T]) Peek(consumer func(item T)) stream[T] +``` + +Example:[Run](https://go.dev/play/p/u1VNzHs6cb2) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + data := []string{} + peekStream := original.Peek(func(n int) { + data = append(data, fmt.Sprint("value", n)) + }) + + fmt.Println(original.ToSlice()) + fmt.Println(peekStream.ToSlice()) + fmt.Println(data) + + // Output: + // [1 2 3] + // [1 2 3] + // [value1 value2 value3] +} +``` + +### Skip + +Returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream. If this stream contains fewer than n elements then an empty stream will be returned. Support chainable operation
+ +Signature: + +```go +func (s stream[T]) Skip(n int) stream[T] +``` + +Example:[Run](https://go.dev/play/p/fNdHbqjahum) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3, 4}) + + s1 := original.Skip(-1) + s2 := original.Skip(0) + s3 := original.Skip(1) + s4 := original.Skip(5) + + fmt.Println(s1.ToSlice()) + fmt.Println(s2.ToSlice()) + fmt.Println(s3.ToSlice()) + fmt.Println(s4.ToSlice()) + + // Output: + // [1 2 3 4] + // [1 2 3 4] + // [2 3 4] + // [] +} +``` + +### Limit + +Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length. Support chainable operation
+ +Signature: + +```go +func (s stream[T]) Limit(maxSize int) stream[T] +``` + +Example:[Run](https://go.dev/play/p/qsO4aniDcGf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3, 4}) + + s1 := original.Limit(-1) + s2 := original.Limit(0) + s3 := original.Limit(1) + s4 := original.Limit(5) + + fmt.Println(s1.ToSlice()) + fmt.Println(s2.ToSlice()) + fmt.Println(s3.ToSlice()) + fmt.Println(s4.ToSlice()) + + // Output: + // [] + // [] + // [1] + // [1 2 3 4] +} +``` + +### Reverse + +Returns a stream whose elements are reverse order of given stream. Support chainable operation
+ +Signature: + +```go +func (s stream[T]) Reverse() stream[T] +``` + +Example:[Run](https://go.dev/play/p/A8_zkJnLHm4) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + reverse := original.Reverse() + + fmt.Println(reverse.ToSlice()) + + // Output: + // [3 2 1] +} +``` + +### Range + +Returns a stream whose elements are in the range from start(included) to end(excluded) original stream.Support chainable operation
+ +Signature: + +```go +func (s stream[T]) Range(start, end int) stream[T] +``` + +Example:[Run](https://go.dev/play/p/indZY5V2f4j) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + s1 := original.Range(0, 0) + s2 := original.Range(0, 1) + s3 := original.Range(0, 3) + s4 := original.Range(1, 2) + + fmt.Println(s1.ToSlice()) + fmt.Println(s2.ToSlice()) + fmt.Println(s3.ToSlice()) + fmt.Println(s4.ToSlice()) + + // Output: + // [] + // [1] + // [1 2 3] + // [2] +} +``` + +### Sorted + +Returns a stream consisting of the elements of this stream, sorted according to the provided less function.Support chainable operation
+ +Signature: + +```go +func (s stream[T]) Sorted(less func(a, b T) bool) stream[T] +``` + +Example:[Run](https://go.dev/play/p/XXtng5uonFj) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{4, 2, 1, 3}) + + sorted := original.Sorted(func(a, b int) bool { return a < b }) + + fmt.Println(original.ToSlice()) + fmt.Println(sorted.ToSlice()) + + // Output: + // [4 2 1 3] + // [1 2 3 4] +} +``` + +### ForEach + +Performs an action for each element of this stream.
+ +Signature: + +```go +func (s stream[T]) ForEach(action func(item T)) +``` + +Example:[Run](https://go.dev/play/p/Dsm0fPqcidk) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + result := 0 + original.ForEach(func(item int) { + result += item + }) + + fmt.Println(result) + + // Output: + // 6 +} +``` + +### Reduce + +Performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any.
+ +Signature: + +```go +func (s stream[T]) Reduce(initial T, accumulator func(a, b T) T) T +``` + +Example:[Run](https://go.dev/play/p/6uzZjq_DJLU) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + result := original.Reduce(0, func(a, b int) int { + return a + b + }) + + fmt.Println(result) + + // Output: + // 6 +} +``` + +### FindFirst + +Returns the first element of this stream and true, or zero value and false if the stream is empty.
+ +Signature: + +```go +func (s stream[T]) FindFirst() (T, bool) +``` + +Example:[Run](https://go.dev/play/p/9xEf0-6C1e3) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + result, ok := original.FindFirst() + + fmt.Println(result) + fmt.Println(ok) + + // Output: + // 1 + // true +} +``` + +### FindLast + +Returns the last element of this stream and true, or zero value and false if the stream is empty.
+ +Signature: + +```go +func (s stream[T]) FindLast() (T, bool) +``` + +Example:[Run](https://go.dev/play/p/WZD2rDAW-2h) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{3, 2, 1}) + + result, ok := original.FindLast() + + fmt.Println(result) + fmt.Println(ok) + + // Output: + // 1 + // true +} +``` + +### Max + +Returns the maximum element of this stream according to the provided less function. less fuction: a > b
+ +Signature: + +```go +func (s stream[T]) Max(less func(a, b T) bool) (T, bool) +``` + +Example:[Run](https://go.dev/play/p/fm-1KOPtGzn) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{4, 2, 1, 3}) + + max, ok := original.Max(func(a, b int) bool { return a > b }) + + fmt.Println(max) + fmt.Println(ok) + + // Output: + // 4 + // true +} +``` + +### Min + +Returns the minimum element of this stream according to the provided less function. less fuction: a < b
+ +Signature: + +```go +func (s stream[T]) Min(less func(a, b T) bool) (T, bool) +``` + +Example:[Run](https://go.dev/play/p/vZfIDgGNRe_0) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{4, 2, 1, 3}) + + min, ok := original.Min(func(a, b int) bool { return a < b }) + + fmt.Println(min) + fmt.Println(ok) + + // Output: + // 1 + // true +} +``` + +### AllMatch + +Returns whether all elements of this stream match the provided predicate.
+ +Signature: + +```go +func (s stream[T]) AllMatch(predicate func(item T) bool) bool +``` + +Example:[Run](https://go.dev/play/p/V5TBpVRs-Cx) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + result1 := original.AllMatch(func(item int) bool { + return item > 0 + }) + + result2 := original.AllMatch(func(item int) bool { + return item > 1 + }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### AnyMatch + +Returns whether any elements of this stream match the provided predicate.
+ +Signature: + +```go +func (s stream[T]) AnyMatch(predicate func(item T) bool) bool +``` + +Example:[Run](https://go.dev/play/p/PTCnWn4OxSn) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + result1 := original.AnyMatch(func(item int) bool { + return item > 1 + }) + + result2 := original.AnyMatch(func(item int) bool { + return item > 3 + }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### NoneMatch + +Returns whether no elements of this stream match the provided predicate.
+ +Signature: + +```go +func (s stream[T]) NoneMatch(predicate func(item T) bool) bool +``` + +Example:[Run](https://go.dev/play/p/iWS64pL1oo3) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + original := stream.FromSlice([]int{1, 2, 3}) + + result1 := original.NoneMatch(func(item int) bool { + return item > 3 + }) + + result2 := original.NoneMatch(func(item int) bool { + return item > 1 + }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### Count + +Returns the count of elements in the stream.
+ +Signature: + +```go +func (s stream[T]) Count() int +``` + +Example:[Run](https://go.dev/play/p/r3koY6y_Xo-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s1 := stream.FromSlice([]int{1, 2, 3}) + s2 := stream.FromSlice([]int{}) + + fmt.Println(s1.Count()) + fmt.Println(s2.Count()) + + // Output: + // 3 + // 0 +} +``` + +### ToSlice + +Returns the elements in the stream.
+ +Signature: + +```go +func (s stream[T]) ToSlice() []T +``` + +Example:[Run](https://go.dev/play/p/jI6_iZZuVFE) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s := stream.Of(1, 2, 3) + + data := s.ToSlice() + + fmt.Println(data) + + // Output: + // [1 2 3] +} +``` + +### IndexOf + +Returns the index of the first occurrence of the specified element in this stream, or -1 if this stream does not contain the element.
+ +Signature: + +```go +func (s Stream[T]) IndexOf(target T, equal func(a, b T) bool) int +``` + +Example:[Run](https://go.dev/play/p/tBV5Nc-XDX2) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s := stream.FromSlice([]int{1, 2, 3, 2}) + + result1 := s.IndexOf(0, func(a, b int) bool { return a == b }) + result2 := s.IndexOf(2, func(a, b int) bool { return a == b }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // -1 + // 1 +} +``` + +### LastIndexOf + +Returns the index of the last occurrence of the specified element in this stream, or -1 if this stream does not contain the element.
+ +Signature: + +```go +func (s Stream[T]) LastIndexOf(target T, equal func(a, b T) bool) int +``` + +Example:[Run](https://go.dev/play/p/CjeoNw2eac_G) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/stream" +) + +func main() { + s := stream.FromSlice([]int{1, 2, 3, 2}) + + result1 := s.LastIndexOf(0, func(a, b int) bool { return a == b }) + result2 := s.LastIndexOf(2, func(a, b int) bool { return a == b }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // -1 + // 3 +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/struct.md b/docs/en/api/packages/struct.md new file mode 100644 index 00000000..51534e98 --- /dev/null +++ b/docs/en/api/packages/struct.md @@ -0,0 +1,577 @@ +# Structs + +Struct is abstract struct for provide several high level functions + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/structs/struct.go](https://github.com/duke-git/lancet/blob/main/structs/struct.go) + +- [https://github.com/duke-git/lancet/blob/main/structs/field.go](https://github.com/duke-git/lancet/blob/main/structs/field.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/structs" +) +``` + + + +## Index: + +- [New](#New) +- [ToMap](#ToMap) +- [Fields](#Fields) +- [Field](#Field) +- [IsStruct](#IsStruct) +- [Tag](#Tag) +- [Name](#Name) +- [Value](#Value) +- [Kind](#Kind) +- [IsEmbedded](#IsEmbedded) +- [IsExported](#IsExported) +- [IsZero](#IsZero) +- [IsSlice](#IsSlice) +- [IsTargetType](#IsTargetType) + + + +## Documentation: + +### New + +The constructor function of the `Struct`
+ +Signature: + +```go +func New(value any, tagName ...string) *Struct +``` + +Example: + +```go +package main + +import ( + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type People struct { + Name string `json:"name"` + } + p1 := &People{Name: "11"} + s := structs.New(p1) + // to do something +} +``` + +### ToMap + +convert a valid struct to a map
+ +Signature: + +```go +func (s *Struct) ToMap() (map[string]any, error) +``` + +> In addition, provided a convenient static function ToMap + +```go +func ToMap(v any) (map[string]any, error) +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type People struct { + Name string `json:"name"` + } + p1 := &People{Name: "11"} + // use constructor function + s1 := structs.New(p1) + m1, _ := s1.ToMap() + + fmt.Println(m1) + + // use static function + m2, _ := structs.ToMap(p1) + + fmt.Println(m2) + + // Output: + // map[name:11] + // map[name:11] +} +``` + +### Fields + +Get all fields of a given struct, that the fields are abstract struct field
+ +Signature: + +```go +func (s *Struct) Fields() []*Field +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type People struct { + Name string `json:"name"` + } + p1 := &People{Name: "11"} + s := structs.New(p1) + fields := s.Fields() + + fmt.Println(len(fields)) + + // Output: + // 1 +} +``` + +### Field + +Get an abstract field of a struct by given field name
+ +Signature: + +```go +func (s *Struct) Field(name string) *Field +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type People struct { + Name string `json:"name"` + } + p1 := &People{Name: "11"} + s := structs.New(p1) + f := s.Field("Name") + + fmt.Println(f.Value()) + + // Output: + // 11 +} +``` + +### IsStruct + +Check if the struct is valid
+ +Signature: + +```go +func (s *Struct) IsStruct() bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type People struct { + Name string `json:"name"` + } + p1 := &People{Name: "11"} + s := structs.New(p1) + + fmt.Println(s.IsStruct()) + + // Output: + // true +} +``` + +### Tag + +Get a `Tag` of the `Field`, `Tag` is a abstract struct field tag
+ +Signature: + +```go +func (f *Field) Tag() *Tag +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string `json:"name,omitempty"` + } + p1 := &Parent{"111"} + + s := structs.New(p1) + n, _ := s.Field("Name") + tag := n.Tag() + + fmt.Println(tag.Name) + + // Output: + // name +} +``` + +### Value + +Get the `Field` underlying value
+ +Signature: + +```go +func (f *Field) Value() any +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string `json:"name,omitempty"` + } + p1 := &Parent{"111"} + + s := structs.New(p1) + n, _ := s.Field("Name") + + fmt.Println(n.Value()) + + // Output: + // 111 +} +``` + +### IsEmbedded + +Check if the field is an embedded field
+ +Signature: + +```go +func (f *Field) IsEmbedded() bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + } + type Child struct { + Parent + Age int + } + c1 := &Child{} + c1.Name = "111" + c1.Age = 11 + + s := structs.New(c1) + n, _ := s.Field("Name") + a, _ := s.Field("Age") + + fmt.Println(n.IsEmbedded()) + fmt.Println(a.IsEmbedded()) + + // Output: + // true + // false +} +``` + +### IsExported + +Check if the field is exported
+ +Signature: + +```go +func (f *Field) IsExported() bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + age int + } + p1 := &Parent{Name: "11", age: 11} + s := structs.New(p1) + n, _ := s.Field("Name") + a, _ := s.Field("age") + + fmt.Println(n.IsExported()) + fmt.Println(a.IsExported()) + + // Output: + // true + // false +} +``` + +### IsZero + +Check if the field is zero value
+ +Signature: + +```go +func (f *Field) IsZero() bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + Age int + } + p1 := &Parent{Age: 11} + s := structs.New(p1) + n, _ := s.Field("Name") + a, _ := s.Field("Age") + + fmt.Println(n.IsZero()) + fmt.Println(a.IsZero()) + + // Output: + // true + // false +} +``` + +### Name + +Get the field name
+ +Signature: + +```go +func (f *Field) Name() string +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + Age int + } + p1 := &Parent{Age: 11} + s := structs.New(p1) + n, _ := s.Field("Name") + a, _ := s.Field("Age") + + fmt.Println(n.Name()) + fmt.Println(a.Name()) + + // Output: + // Name + // Age +} +``` + +### Kind + +Get the field's kind
+ +Signature: + +```go +func (f *Field) Kind() reflect.Kind +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + Age int + } + p1 := &Parent{Age: 11} + s := structs.New(p1) + n, _ := s.Field("Name") + a, _ := s.Field("Age") + + fmt.Println(n.Kind()) + fmt.Println(a.Kind()) + + // Output: + // string + // int +} +``` + +### IsSlice + +Check if the field is a slice
+ +Signature: + +```go +func (f *Field) IsSlice() bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + arr []int + } + + p1 := &Parent{arr: []int{1, 2, 3}} + s := structs.New(p1) + a, _ := s.Field("arr") + + fmt.Println(a.IsSlice()) + + // Output: + // true +} +``` + +### IsTargetType + +check if a struct field type is target type or not
+ +Signature: + +```go +func (f *Field) IsTargetType(targetType reflect.Kind) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "reflect" + "github.com/duke-git/lancet/v2/structs" +) + +func main() { + type Parent struct { + Name string + arr []int + } + + p1 := &Parent{arr: []int{1, 2, 3}} + s := structs.New(p1) + n, _ := s.Field("Name") + a, _ := s.Field("arr") + + fmt.Println(n.IsTargetType(reflect.String)) + fmt.Println(a.IsTargetType(reflect.Slice)) + + // Output: + // true + // true +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/strutil.md b/docs/en/api/packages/strutil.md new file mode 100644 index 00000000..90e2d995 --- /dev/null +++ b/docs/en/api/packages/strutil.md @@ -0,0 +1,1793 @@ +# Strutil + +Package strutil contains some functions to manipulate string. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/strutil/string.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/strutil" +) +``` + + + +## Index + +- [After](#After) +- [AfterLast](#AfterLast) +- [Before](#Before) +- [BeforeLast](#BeforeLast) +- [CamelCase](#CamelCase) +- [Capitalize](#Capitalize) +- [IsString](#IsString) +- [KebabCase](#KebabCase) +- [UpperKebabCase](#UpperKebabCase) +- [LowerFirst](#LowerFirst) +- [UpperFirst](#UpperFirst) +- [Pad](#Pad) +- [PadStart](#PadStart) +- [PadEnd](#PadEnd) +- [Reverse](#Reverse) +- [SnakeCase](#SnakeCase) +- [UpperSnakeCase](#UpperSnakeCase) +- [SplitEx](#SplitEx) +- [Substring](#Substring) +- [Wrap](#Wrap) +- [Unwrap](#Unwrap) +- [SplitWords](#SplitWords) +- [WordCount](#WordCount) +- [RemoveNonPrintable](#RemoveNonPrintable) +- [StringToBytes](#StringToBytes) +- [BytesToString](#BytesToString) +- [IsBlank](#IsBlank) +- [IsNotBlank](#IsNotBlank) +- [HasPrefixAny](#HasPrefixAny) +- [HasSuffixAny](#HasSuffixAny) +- [IndexOffset](#IndexOffset) +- [ReplaceWithMap](#ReplaceWithMap) +- [Trim](#Trim) +- [SplitAndTrim](#SplitAndTrim) +- [HideString](#HideString) +- [ContainsAll](#ContainsAll) +- [ContainsAny](#ContainsAny) +- [RemoveWhiteSpace](#RemoveWhiteSpace) +- [SubInBetween](#SubInBetween) +- [HammingDistance](#HammingDistance) +- [Concat](#Concat) +- [Ellipsis](#Ellipsis) +- [Shuffle](#Shuffle) +- [Rotate](#Rotate) +- [TemplateReplace](#TemplateReplace) +- [RegexMatchAllGroups](#RegexMatchAllGroups) +- [ExtractContent](#ExtractContent) +- [FindAllOccurrences](#FindAllOccurrences) + + + + +## Documentation + +### After + +Returns the substring after the first occurrence of a specified string in the source string.
+ +Signature: + +```go +func After(s, char string) string +``` + +Example:[Run](https://go.dev/play/p/RbCOQqCDA7m) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.After("foo", "") + result2 := strutil.After("foo", "foo") + result3 := strutil.After("foo/bar", "foo") + result4 := strutil.After("foo/bar", "/") + result5 := strutil.After("foo/bar/baz", "/") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // foo + // + // /bar + // bar + // bar/baz +} +``` + +### AfterLast + +Returns the substring after the last occurrence of a specified string in the source string.
+ +Signature: + +```go +func AfterLast(s, char string) string +``` + +Example:[Run](https://go.dev/play/p/1TegARrb8Yn) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.AfterLast("foo", "") + result2 := strutil.AfterLast("foo", "foo") + result3 := strutil.AfterLast("foo/bar", "/") + result4 := strutil.AfterLast("foo/bar/baz", "/") + result5 := strutil.AfterLast("foo/bar/foo/baz", "foo") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // foo + // + // bar + // baz + // /baz +} +``` + +### Before + +Returns the substring of the source string up to the first occurrence of the specified string.
+ +Signature: + +```go +func Before(s, char string) string +``` + +Example:[Run](https://go.dev/play/p/JAWTZDS4F5w) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Before("foo", "") + result2 := strutil.Before("foo", "foo") + result3 := strutil.Before("foo/bar", "/") + result4 := strutil.Before("foo/bar/baz", "/") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // foo + // + // foo + // foo +} +``` + +### BeforeLast + +Returns the substring of the source string up to the last occurrence of the specified string.
+ +Signature: + +```go +func BeforeLast(s, char string) string +``` + +Example:[Run](https://go.dev/play/p/pJfXXAoG_Te) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.BeforeLast("foo", "") + result2 := strutil.BeforeLast("foo", "foo") + result3 := strutil.BeforeLast("foo/bar", "/") + result4 := strutil.BeforeLast("foo/bar/baz", "/") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // foo + // + // foo + // foo/bar +} +``` + +### CamelCase + +Coverts string to camelCase string, non letters and numbers will be ignored.
+ +Signature: + +```go +func CamelCase(s string) string +``` + +Example:[Run](https://go.dev/play/p/9eXP3tn2tUy) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "foobar", "&FOO:BAR$BAZ", "$foo%", "Foo-#1😄$_%^&*(1bar"} + + for _, v := range strings { + s := strutil.CamelCase(v) + fmt.Println(s) + } + + // Output: + // + // foobar + // fooBarBaz + // foo + // foo11Bar +} +``` + +### KebabCase + +KebabCase covert string to kebab-case, non letters and numbers will be ignored.
+ +Signature: + +```go +func KebabCase(s string) string +``` + +Example:[Run](https://go.dev/play/p/dcZM9Oahw-Y) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "foo-bar", "Foo Bar-", "FOOBAR", "Foo-#1😄$_%^&*(1bar"} + + for _, v := range strings { + s := strutil.KebabCase(v) + fmt.Println(s) + } + + // Output: + // + // foo-bar + // foo-bar + // foobar + // foo-1-1-bar +} +``` + +### UpperKebabCase + +UpperKebabCase covert string to upper KEBAB-CASE, non letters and numbers will be ignored.
+ +Signature: + +```go +func UpperKebabCase(s string) string +``` + +Example:[Run](https://go.dev/play/p/zDyKNneyQXk) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "foo-bar", "Foo Bar-", "FooBAR", "Foo-#1😄$_%^&*(1bar"} + + for _, v := range strings { + s := strutil.UpperKebabCase(v) + fmt.Println(s) + } + + // Output: + // + // FOO-BAR + // FOO-BAR + // FOO-BAR + // FOO-1-1-BAR +} +``` + +### Capitalize + +Convert the first character of a string to upper case.
+ +Signature: + +```go +func Capitalize(s string) string +``` + +Example:[Run](https://go.dev/play/p/2OAjgbmAqHZ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "Foo", "_foo", "fooBar", "foo-bar"} + + for _, v := range strings { + s := strutil.Capitalize(v) + fmt.Println(s) + } + + // Output: + // + // Foo + // _foo + // Foobar + // Foo-bar +} +``` + +### IsString + +Check if the value's data type is string.
+ +Signature: + +```go +func IsString(v any) bool +``` + +Example:[Run](https://go.dev/play/p/IOgq7oF9ERm) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.IsString("") + result2 := strutil.IsString("a") + result3 := strutil.IsString(1) + result4 := strutil.IsString(true) + result5 := strutil.IsString([]string{"a"}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // true + // true + // false + // false + // false +} +``` + +### LowerFirst + +Convert the first character of string to lower case.
+ +Signature: + +```go +func LowerFirst(s string) string +``` + +Example:[Run](https://go.dev/play/p/CbzAyZmtJwL) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "bar", "BAr", "Bar大"} + + for _, v := range strings { + s := strutil.LowerFirst(v) + fmt.Println(s) + } + + // Output: + // + // bar + // bAr + // bar大 +} +``` + +### UpperFirst + +Convert the first character of string to upper case.
+ +Signature: + +```go +func UpperFirst(s string) string +``` + +Example:[Run](https://go.dev/play/p/sBbBxRbs8MM) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "bar", "BAr", "bar大"} + + for _, v := range strings { + s := strutil.UpperFirst(v) + fmt.Println(s) + } + + // Output: + // + // Bar + // BAr + // Bar大 +} +``` + +### Pad + +Pads string on the left and right side if it's shorter than size.
+ +Signature: + +```go +func Pad(source string, size int, padStr string) string +``` + +Example:[Run](https://go.dev/play/p/NzImQq-VF8q) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Pad("foo", 1, "bar") + result2 := strutil.Pad("foo", 2, "bar") + result3 := strutil.Pad("foo", 3, "bar") + result4 := strutil.Pad("foo", 4, "bar") + result5 := strutil.Pad("foo", 5, "bar") + result6 := strutil.Pad("foo", 6, "bar") + result7 := strutil.Pad("foo", 7, "bar") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + // Output: + // foo + // foo + // foo + // foob + // bfoob + // bfooba + // bafooba +} +``` + +### PadEnd + +Pads string on the right side if it's shorter than size.
+ +Signature: + +```go +func PadEnd(source string, size int, padStr string) string +``` + +Example:[Run](https://go.dev/play/p/9xP8rN0vz--) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.PadEnd("foo", 1, "bar") + result2 := strutil.PadEnd("foo", 2, "bar") + result3 := strutil.PadEnd("foo", 3, "bar") + result4 := strutil.PadEnd("foo", 4, "bar") + result5 := strutil.PadEnd("foo", 5, "bar") + result6 := strutil.PadEnd("foo", 6, "bar") + result7 := strutil.PadEnd("foo", 7, "bar") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + + // Output: + // foo + // foo + // foo + // foob + // fooba + // foobar + // foobarb +} +``` + +### PadStart + +Pads string on the left side if it's shorter than size.
+ +Signature: + +```go +func PadStart(source string, size int, padStr string) string +``` + +Example:[Run](https://go.dev/play/p/xpTfzArDfvT) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.PadStart("foo", 1, "bar") + result2 := strutil.PadStart("foo", 2, "bar") + result3 := strutil.PadStart("foo", 3, "bar") + result4 := strutil.PadStart("foo", 4, "bar") + result5 := strutil.PadStart("foo", 5, "bar") + result6 := strutil.PadStart("foo", 6, "bar") + result7 := strutil.PadStart("foo", 7, "bar") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + fmt.Println(result7) + + // Output: + // foo + // foo + // foo + // bfoo + // bafoo + // barfoo + // barbfoo +} +``` + +### Reverse + +Return string whose char order is reversed to the given string.
+ +Signature: + +```go +func Reverse(s string) string +``` + +Example:[Run](https://go.dev/play/p/adfwalJiecD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + s := "foo" + rs := strutil.Reverse(s) + + fmt.Println(s) + fmt.Println(rs) + + // Output: + // foo + // oof +} +``` + +### SnakeCase + +Coverts string to snake_case, non letters and numbers will be ignored.
+ +Signature: + +```go +func SnakeCase(s string) string +``` + +Example:[Run](https://go.dev/play/p/tgzQG11qBuN) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "foo-bar", "Foo Bar-", "FOOBAR", "Foo-#1😄$_%^&*(1bar"} + + for _, v := range strings { + s := strutil.SnakeCase(v) + fmt.Println(s) + } + + // Output: + // + // foo_bar + // foo_bar + // foobar + // foo_1_1_bar +} +``` + +### UpperSnakeCase + +Coverts string to upper snake_case, non letters and numbers will be ignored.
+ +Signature: + +```go +func UpperSnakeCase(s string) string +``` + +Example:[Run](https://go.dev/play/p/4COPHpnLx38) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + strings := []string{"", "foo-bar", "Foo Bar-", "FooBAR", "Foo-#1😄$_%^&*(1bar"} + + for _, v := range strings { + s := strutil.UpperSnakeCase(v) + fmt.Println(s) + } + + // Output: + // + // FOO_BAR + // FOO_BAR + // FOO_BAR + // FOO_1_1_BAR +} +``` + +### SplitEx + +Split a given string whether the result contains empty string.
+ +Signature: + +```go +func SplitEx(s, sep string, removeEmptyString bool) []string +``` + +Example:[Run](https://go.dev/play/p/Us-ySSbWh-3) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.SplitEx(" a b c ", "", true) + + result2 := strutil.SplitEx(" a b c ", " ", false) + result3 := strutil.SplitEx(" a b c ", " ", true) + + result4 := strutil.SplitEx("a = b = c = ", " = ", false) + result5 := strutil.SplitEx("a = b = c = ", " = ", true) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // [] + // [ a b c ] + // [a b c] + // [a b c ] +} +``` + +### Substring + +Returns a substring of the specified length starting at the specified offset position.
+ +Signature: + +```go +func Substring(s string, offset int, length uint) string +``` + +Example:[Run](https://go.dev/play/p/q3sM6ehnPDp) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Substring("abcde", 1, 3) + result2 := strutil.Substring("abcde", 1, 5) + result3 := strutil.Substring("abcde", -1, 3) + result4 := strutil.Substring("abcde", -2, 2) + result5 := strutil.Substring("abcde", -2, 3) + result6 := strutil.Substring("你好,欢迎你", 0, 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // bcd + // bcde + // e + // de + // de + // 你好 +} +``` + +### Wrap + +Wrap a string with given string.
+ +Signature: + +```go +func Wrap(str string, wrapWith string) string +``` + +Example:[Run](https://go.dev/play/p/KoZOlZDDt9y) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Wrap("foo", "") + result2 := strutil.Wrap("foo", "*") + result3 := strutil.Wrap("'foo'", "'") + result4 := strutil.Wrap("", "*") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // foo + // *foo* + // ''foo'' + // +} +``` + +### Unwrap + +Unwrap a given string from anther string. will change source string.
+ +Signature: + +```go +func Unwrap(str string, wrapToken string) string +``` + +Example:[Run](https://go.dev/play/p/Ec2q4BzCpG-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Unwrap("foo", "") + result2 := strutil.Unwrap("*foo*", "*") + result3 := strutil.Unwrap("*foo", "*") + result4 := strutil.Unwrap("foo*", "*") + result5 := strutil.Unwrap("**foo**", "*") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // foo + // foo + // *foo + // foo* + // *foo* +} +``` + +### SplitWords + +Splits a string into words, word only contains alphabetic characters.
+ +Signature: + +```go +func SplitWords(s string) []string +``` + +Example:[Run](https://go.dev/play/p/KLiX4WiysMM) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.SplitWords("a word") + result2 := strutil.SplitWords("I'am a programmer") + result3 := strutil.SplitWords("Bonjour, je suis programmeur") + result4 := strutil.SplitWords("a -b-c' 'd'e") + result5 := strutil.SplitWords("你好,我是一名码农") + result6 := strutil.SplitWords("こんにちは,私はプログラマーです") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // [a word] + // [I'am a programmer] + // [Bonjour je suis programmeur] + // [a b-c' d'e] + // [] + // [] +} +``` + +### WordCount + +Return the number of meaningful word, word only contains alphabetic characters.
+ +Signature: + +```go +func WordCount(s string) int +``` + +Example:[Run](https://go.dev/play/p/bj7_odx3vRf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.WordCount("a word") + result2 := strutil.WordCount("I'am a programmer") + result3 := strutil.WordCount("Bonjour, je suis programmeur") + result4 := strutil.WordCount("a -b-c' 'd'e") + result5 := strutil.WordCount("你好,我是一名码农") + result6 := strutil.WordCount("こんにちは,私はプログラマーです") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + fmt.Println(result6) + + // Output: + // 2 + // 3 + // 4 + // 3 + // 0 + // 0 +} +``` + +### RemoveNonPrintable + +Remove non-printable characters from a string.
+ +Signature: + +```go +func RemoveNonPrintable(str string) string +``` + +Example:[Run](https://go.dev/play/p/og47F5x_jTZ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.RemoveNonPrintable("hello\u00a0 \u200bworld\n") + result2 := strutil.RemoveNonPrintable("你好😄") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // hello world + // 你好😄 +} +``` + +### StringToBytes + +Converts a string to byte slice without a memory allocation.
+ +Signature: + +```go +func StringToBytes(str string) (b []byte) +``` + +Example:[Run](https://go.dev/play/p/7OyFBrf9AxA) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.StringToBytes("abc") + result2 := reflect.DeepEqual(result1, []byte{'a', 'b', 'c'}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // [97 98 99] + // true +} +``` + +### BytesToString + +Converts a byte slice to string without a memory allocation.
+ +Signature: + +```go +func BytesToString(bytes []byte) string +``` + +Example:[Run](https://go.dev/play/p/6c68HRvJecH) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + bytes := []byte{'a', 'b', 'c'} + result := strutil.BytesToString(bytes) + + fmt.Println(result) + + // Output: + // abc +} +``` + +### IsBlank + +Checks if a string is whitespace or empty.
+ +Signature: + +```go +func IsBlank(str string) bool +``` + +Example:[Run](https://go.dev/play/p/6zXRH_c0Qd3) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.IsBlank("") + result2 := strutil.IsBlank("\t\v\f\n") + result3 := strutil.IsBlank(" 中文") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### IsNotBlank + +Checks if a string is not whitespace or not empty.
+ +Signature: + +```go +func IsNotBlank(str string) bool +``` + +Example:[Run](https://go.dev/play/p/e_oJW0RAquA) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.IsNotBlank("") + result2 := strutil.IsNotBlank(" ") + result3 := strutil.IsNotBlank("\t\v\f\n") + result4 := strutil.IsNotBlank(" 中文") + result5 := strutil.IsNotBlank(" world ") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + // Output: + // false + // false + // false + // true + // true +} +``` + +### HasPrefixAny + +Checks if a string starts with any of an array of specified strings.
+ +Signature: + +```go +func HasPrefixAny(str string, prefixes []string) bool +``` + +Example:[Run](https://go.dev/play/p/8UUTl2C5slo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.HasPrefixAny("foo bar", []string{"fo", "xyz", "hello"}) + result2 := strutil.HasPrefixAny("foo bar", []string{"oom", "world"}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### HasSuffixAny + +Checks if a string ends with any of an array of specified strings.
+ +Signature: + +```go +func HasSuffixAny(str string, suffixes []string) bool +``` + +Example:[Run](https://go.dev/play/p/sKWpCQdOVkx) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.HasSuffixAny("foo bar", []string{"bar", "xyz", "hello"}) + result2 := strutil.HasSuffixAny("foo bar", []string{"oom", "world"}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IndexOffset + +Returns the index of the first instance of substr in string after offsetting the string by `idxFrom`, or -1 if substr is not present in string.
+ +Signature: + +```go +func IndexOffset(str string, substr string, idxFrom int) int +``` + +Example:[Run](https://go.dev/play/p/qZo4lV2fomB) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := "foo bar hello world" + + result1 := strutil.IndexOffset(str, "o", 5) + result2 := strutil.IndexOffset(str, "o", 0) + result3 := strutil.IndexOffset(str, "d", len(str)-1) + result4 := strutil.IndexOffset(str, "d", len(str)) + result5 := strutil.IndexOffset(str, "f", -1) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // 12 + // 1 + // 18 + // -1 + // -1 +} +``` + +### ReplaceWithMap + +Returns a copy of `str`, which is replaced by a map in unordered way, case-sensitively.
+ +Signature: + +```go +func ReplaceWithMap(str string, replaces map[string]string) string +``` + +Example:[Run](https://go.dev/play/p/h3t7CNj2Vvu) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := "ac ab ab ac" + replaces := map[string]string{ + "a": "1", + "b": "2", + } + + result := strutil.ReplaceWithMap(str, replaces) + + fmt.Println(result) + // Output: + // 1c 12 12 1c +} +``` + +### Trim + +Strips whitespace (or other characters) from the beginning and end of a string. The optional parameter `characterMask` specifies the additional stripped characters.
+ +Signature: + +```go +func Trim(str string, characterMask ...string) string +``` + +Example:[Run](https://go.dev/play/p/Y0ilP0NRV3j) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Trim("\nabcd") + + str := "$ ab cd $ " + + result2 := strutil.Trim(str) + result3 := strutil.Trim(str, "$") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // abcd + // $ ab cd $ + // ab cd +} +``` + +### SplitAndTrim + +Splits string `str` by a string `delimiter` to a slice, and calls Trim to every element of slice. It ignores the elements which are empty after Trim.
+ +Signature: + +```go +func SplitAndTrim(str, delimiter string, characterMask ...string) []string +``` + +Example:[Run](https://go.dev/play/p/ZNL6o4SkYQ7) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := " a,b, c,d,$1 " + + result1 := strutil.SplitAndTrim(str, ",") + result2 := strutil.SplitAndTrim(str, ",", "$") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // [a b c d $1] + // [a b c d 1] +} +``` + +### HideString + +Hide some chars in source string with param `replaceChar`. replace range is origin[start : end]. [start, end).
+ +Signature: + +```go +func HideString(origin string, start, end int, replaceChar string) string +``` + +Example:[Run](https://go.dev/play/p/pzbaIVCTreZ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := "13242658976" + + result1 := strutil.HideString(str, 3, 3, "*") + result2 := strutil.HideString(str, 3, 4, "*") + result3 := strutil.HideString(str, 3, 7, "*") + result4 := strutil.HideString(str, 7, 11, "*") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 13242658976 + // 132*2658976 + // 132****8976 + // 1324265**** +} +``` + +### ContainsAll + +Return true if target string contains all the substrings.
+ +Signature: + +```go +func ContainsAll(str string, substrs []string) bool +``` + +Example:[Run](https://go.dev/play/p/KECtK2Os4zq) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := "hello world" + + result1 := strutil.ContainsAll(str, []string{"hello", "world"}) + result2 := strutil.ContainsAll(str, []string{"hello", "abc"}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### ContainsAny + +Return true if target string contains any one of the substrings.
+ +Signature: + +```go +func ContainsAny(str string, substrs []string) bool +``` + +Example:[Run](https://go.dev/play/p/dZGSSMB3LXE) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := "hello world" + + result1 := strutil.ContainsAny(str, []string{"hello", "world"}) + result2 := strutil.ContainsAny(str, []string{"hello", "abc"}) + result3 := strutil.ContainsAny(str, []string{"123", "abc"}) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### RemoveWhiteSpace + +Remove whitespace characters from a string. when set repalceAll is true removes all whitespace, false only replaces consecutive whitespace characters with one space.
+ +Signature: + +```go +func RemoveWhiteSpace(str string, repalceAll bool) string +``` + +Example:[Run](https://go.dev/play/p/HzLC9vsTwkf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := " hello \r\n \t world" + + result1 := strutil.RemoveWhiteSpace(str, true) + result2 := strutil.RemoveWhiteSpace(str, false) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // helloworld + // hello world +} +``` + + +### SubInBetween + +Return substring between the start and end position(excluded) of source string.
+ +Signature: + +```go +func SubInBetween(str string, start string, end string) string +``` + +Example:[Run](https://go.dev/play/p/EDbaRvjeNsv) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + str := "abcde" + + result1 := strutil.SubInBetween(str, "", "de") + result2 := strutil.SubInBetween(str, "a", "d") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // abc + // bc +} +``` + +### HammingDistance + +HammingDistance calculates the Hamming distance between two strings. The Hamming distance is the number of positions at which the corresponding symbols are different.
+ +Signature: + +```go +func HammingDistance(a, b string) (int, error) +``` + +Example:[Run](https://go.dev/play/p/glNdQEA9HUi) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + + result1, _ := strutil.HammingDistance("de", "de") + result2, _ := strutil.HammingDistance("a", "d") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // 1 +} +``` + + +### Concat + +Concatenates strings. length is the length of the concatenated string. If unsure, pass 0 or a negative number.
+ +Signature: + +```go +func Concat(length int, str ...string) string +``` + +Example:[Run](https://go.dev/play/p/gD52SZHr4Kp) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Concat(12, "Hello", " ", "World", "!") + result2 := strutil.Concat(11, "Go", " ", "Language") + result3 := strutil.Concat(0, "An apple a ", "day,", "keeps the", " doctor away") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // Hello World! + // Go Language + // An apple a day,keeps the doctor away +} +``` + +### Ellipsis + +Truncates a string to a specified length and appends an ellipsis.
+ +Signature: + +```go +func Ellipsis(str string, length int) string +``` + +Example:[Run](https://go.dev/play/p/i1vbdQiQVRR) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := strutil.Ellipsis("hello world", 5) + result2 := strutil.Ellipsis("你好,世界!", 2) + result3 := strutil.Ellipsis("😀😃😄😁😆", 3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // hello... + // 你好... + // 😀😃😄... +} +``` + +### Shuffle + +Shuffle the order of characters of given string.
+ +Signature: + +```go +func Shuffle(str string) string +``` + +Example:[Run](https://go.dev/play/p/iStFwBwyGY7) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result := strutil.Shuffle("hello") + fmt.Println(result) //olelh (random order) +} +``` + +### Rotate + +Rotates the string by the specified number of characters.
+ +Signature: + +```go +func Rotate(str string, shift int) string +``` + +Example:[Run](https://go.dev/play/p/Kf03iOeT5bd) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result1 := Rotate("Hello", 0) + result2 := Rotate("Hello", 1) + result3 := Rotate("Hello", 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // Hello + // oHell + // loHel +} +``` +### TemplateReplace + +Replaces the placeholders in the template string with the corresponding values in the data map.The placeholders are enclosed in curly braces, e.g. {key}. for example, the template string is "Hello, {name}!", and the data map is {"name": "world"}, the result will be "Hello, world!".
+ +Signature: + +```go +func TemplateReplace(template string, data map[string]string string +``` + +example:[Run](https://go.dev/play/p/cXSuFvyZqv9) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + template := `Hello, my name is {name}, I'm {age} years old.` + data := map[string]string{ + "name": "Bob", + "age": "20", + } + + result := strutil.TemplateReplace(template, data) + + fmt.Println(result) + + // Output: + // Hello, my name is Bob, I'm 20 years old. +} +``` + +### RegexMatchAllGroups + +Matches all subgroups in a string using a regular expression and returns the result.
+ +Signature: + +```go +func RegexMatchAllGroups(pattern, str string) [][]string +``` + +Example:[Run](https://go.dev/play/p/JZiu0RXpgN-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + pattern := `(\w+\.+\w+)@(\w+)\.(\w+)` + str := "Emails: john.doe@example.com and jane.doe@example.com" + + result := strutil.RegexMatchAllGroups(pattern, str) + + fmt.Println(result[0]) + fmt.Println(result[1]) + + // Output: + // [john.doe@example.com john.doe example com] + // [jane.doe@example.com jane.doe example com] +} +``` + +### ExtractContent + +Extracts the content between the start and end strings in the source string.
+ +Signature: + +```go +func ExtractContent(s, start, end string) []string +``` + +Example:[Run](https://go.dev/play/p/Ay9UIk7Rum9) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + html := `content1aacontent2bbcontent1` + + result := strutil.ExtractContent(html, "", "") + + fmt.Println(result) + + // Output: + // [content1 content2 content1] +} +``` + +### FindAllOccurrences + +Returns the positions of all occurrences of a substring in a string.
+ +Signature: + +```go +func FindAllOccurrences(str, substr string) []int +``` + +Example:[Run](https://go.dev/play/p/uvyA6azGLB1) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + result := strutil.FindAllOccurrences("ababab", "ab") + + fmt.Println(result) + + // Output: + // [0 2 4] +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/system.md b/docs/en/api/packages/system.md new file mode 100644 index 00000000..290aa317 --- /dev/null +++ b/docs/en/api/packages/system.md @@ -0,0 +1,445 @@ +# System + +Package system contains some functions about os, runtime, shell command. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/system" +) +``` + + + +## Index + +- [IsWindows](#IsWindows) +- [IsLinux](#IsLinux) +- [IsMac](#IsMac) +- [GetOsEnv](#GetOsEnv) +- [SetOsEnv](#SetOsEnv) +- [RemoveOsEnv](#RemoveOsEnv) +- [CompareOsEnv](#CompareOsEnv) +- [ExecCommand](#ExecCommand) +- [GetOsBits](#GetOsBits) +- [StartProcess](#StartProcess) +- [StopProcess](#StopProcess) +- [KillProcess](#KillProcess) +- [GetProcessInfo](#GetProcessInfo) + + + + + +## Documentation + +### IsWindows + +Check if current os is windows.
+ +Signature: + +```go +func IsWindows() bool +``` + +Example:[Run](https://go.dev/play/p/zIflQgZNuxD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + isOsWindows := system.IsWindows() + fmt.Println(isOsWindows) +} +``` + +### IsLinux + +Check if current os is linux.
+ +Signature: + +```go +func IsLinux() bool +``` + +Example:[Run](https://go.dev/play/p/zIflQgZNuxD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + isOsLinux := system.IsLinux() + fmt.Println(isOsLinux) +} +``` + +### IsMac + +Check if current os is macos.
+ +Signature: + +```go +func IsMac() bool +``` + +Example:[Run](https://go.dev/play/p/Mg4Hjtyq7Zc) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + isOsMac := system.IsMac() + fmt.Println(isOsMac) +} +``` + +### GetOsEnv + +Gets the value of the environment variable named by the key.
+ +Signature: + +```go +func GetOsEnv(key string) string +``` + +Example:[Run](https://go.dev/play/p/D88OYVCyjO-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + err := system.SetOsEnv("foo", "abc") + result := system.GetOsEnv("foo") + + fmt.Println(err) + fmt.Println(result) + // Output: + //Sets the value of the environment variable named by the key.
+ +Signature: + +```go +func SetOsEnv(key, value string) error +``` + +Example:[Run](https://go.dev/play/p/D88OYVCyjO-) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + err := system.SetOsEnv("foo", "abc") + result := system.GetOsEnv("foo") + + fmt.Println(err) + fmt.Println(result) + // Output: + //Remove a single environment variable.
+ +Signature: + +```go +func RemoveOsEnv(key string) error +``` + +Example:[Run](https://go.dev/play/p/fqyq4b3xUFQ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + err1 := system.SetOsEnv("foo", "abc") + result1 := GetOsEnv("foo") + + err2 := system.RemoveOsEnv("foo") + result2 := GetOsEnv("foo") + + fmt.Println(err1) + fmt.Println(err2) + fmt.Println(result1) + fmt.Println(result2) + + // Output: + //Get env named by the key and compare it with comparedEnv.
+ +Signature: + +```go +func CompareOsEnv(key, comparedEnv string) bool +``` + +Example:[Run](https://go.dev/play/p/BciHrKYOHbp) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + err := system.SetOsEnv("foo", "abc") + if err != nil { + return + } + + result := system.CompareOsEnv("foo", "abc") + + fmt.Println(result) + + // Output: + // true +} +``` + +### ExecCommand + +Execute shell command, return the stdout and stderr string of command, and error if error occur. param `command` is a complete command string, like, ls -a (linux), dir(windows), ping 127.0.0.1. In linux, use /bin/bash -c to execute command, In windows, use powershell.exe to execute command. +The second parameter of the function is the cmd option control parameter. The type is func(*exec.Cmd). You can set the cmd attribute through this parameter.
+ +Signature: + +```go +type ( + Option func(*exec.Cmd) +) +func ExecCommand(command string, opts ...Option) (stdout, stderr string, err error) +``` + +Example:[Run](https://go.dev/play/p/n-2fLyZef-4) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + // linux or mac + stdout, stderr, err := system.ExecCommand("ls", func(cmd *exec.Cmd) { + cmd.Dir = "/tmp" + }) + fmt.Println("std out: ", stdout) + fmt.Println("std err: ", stderr) + assert.Equal("", stderr) + + // windows + stdout, stderr, err = system.ExecCommand("dir") + fmt.Println("std out: ", stdout) + fmt.Println("std err: ", stderr) + + // error command + stdout, stderr, err = system.ExecCommand("abc") + fmt.Println("std out: ", stdout) + fmt.Println("std err: ", stderr) + if err != nil { + fmt.Println(err.Error()) + } +} +``` + +### GetOsBits + +Get current os bits, 32bit or 64bit. return 32 or 64.
+ +Signature: + +```go +func GetOsBits() int +``` + +Example:[Run](https://go.dev/play/p/ml-_XH3gJbW) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + osBit := system.GetOsBits() + fmt.Println(osBit) // 32 or 64 +} +``` + +### StartProcess + +Start a new process with the specified name and arguments.
+ +Signature: + +```go +func StartProcess(command string, args ...string) (int, error) +``` + +Example:[Run](https://go.dev/play/p/5GVol6ryS_X) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + pid, err := system.StartProcess("sleep", "2") + if err != nil { + return + } + + fmt.Println(pid) +} +``` + +### StopProcess + +Stop a process by pid.
+ +Signature: + +```go +func StopProcess(pid int) error +``` + +Example:[Run](https://go.dev/play/p/jJZhRYGGcmD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + pid, err := system.StartProcess("sleep", "10") + if err != nil { + return + } + time.Sleep(1 * time.Second) + + err = system.StopProcess(pid) + + fmt.Println(err) + + // Output: + //Kill a process by pid.
+ +Signature: + +```go +func KillProcess(pid int) error +``` + +Example:[Run](https://go.dev/play/p/XKmvV-ExBWa) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + pid, err := system.StartProcess("sleep", "10") + if err != nil { + return + } + time.Sleep(1 * time.Second) + + err = system.KillProcess(pid) + + fmt.Println(err) + + // Output: + //Retrieves detailed process information by pid.
+ +Signature: + +```go +func GetProcessInfo(pid int) (*ProcessInfo, error) +``` + +Example:[Run](https://go.dev/play/p/NQDVywEYYx7) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/system" +) + +func main() { + pid, err := system.StartProcess("ls", "-a") + if err != nil { + return + } + + processInfo, err := system.GetProcessInfo(pid) + if err != nil { + return + } + + fmt.Println(processInfo) +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/tuple.md b/docs/en/api/packages/tuple.md new file mode 100644 index 00000000..2936567e --- /dev/null +++ b/docs/en/api/packages/tuple.md @@ -0,0 +1,1198 @@ +# Tuple + +tuple package implements tuple data type and some operations on it. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/tuple/tuple.go](https://github.com/duke-git/lancet/blob/main/tuple/tuple.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/pointer" +) +``` + + + +## Index + +- [Tuple2](#Tuple2) +- [Tuple2_Unbox](#Tuple2_Unbox) +- [Zip2](#Zip2) +- [Unzip2](#Unzip2) +- [Tuple3](#Tuple3) +- [Tuple3_Unbox](#Tuple3_Unbox) +- [Zip3](#Zip3) +- [Unzip3](#Unzip3) +- [Tuple4](#Tuple4) +- [Tuple4_Unbox](#Tuple4_Unbox) +- [Zip4](#Zip4) +- [Unzip4](#Unzip4) +- [Tuple5](#Tuple5) +- [Tuple5_Unbox](#Tuple5_Unbox) +- [Zip5](#Zip5) +- [Unzip5](#Unzip5) +- [Tuple6](#Tuple6) +- [Tuple6_Unbox](#Tuple6_Unbox) +- [Zip6](#Zip6) +- [Unzip6](#Unzip6) +- [Tuple7](#Tuple7) +- [Tuple7_Unbox](#Tuple7_Unbox) +- [Zip7](#Zip7) +- [Unzip7](#Unzip7) +- [Tuple8](#TTuple8uple6) +- [Tuple8_Unbox](#Tuple8_Unbox) +- [Zip8](#Zip8) +- [Unzip8](#Unzip8) +- [Tuple9](#Tuple9) +- [Tuple9_Unbox](#Tuple9_Unbox) +- [Zip9](#Zip9) +- [Unzip9](#Unzip9) +- [Tuple10](#Tuple10) +- [Tuple10_Unbox](#Tuple10_Unbox) +- [Zip10](#Zip10) +- [Unzip10](#Unzip10) + + + + +## Documentation + +### Tuple2 + +Tuple2 represents a 2 elemnets tuple.
+ +Signature: + +```go +type Tuple2[A any, B any] struct { + FieldA A + FieldB B +} + +func NewTuple2[A any, B any](a A, b B) Tuple2[A, B] +``` + +Example:[Run](https://go.dev/play/p/3sHVqBQpLYN) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple2(1, 0.1) + fmt.Printf("%v %v", t.FieldA, t.FieldB) + + // Output: 1 0.1 +} +``` + +### Tuple2_Unbox + +Tuple2 Unbox returns values in tuple.
+ +Signature: + +```go +func (t Tuple2[A, B]) Unbox() (A, B) +``` + +Example:[Run](https://go.dev/play/p/0fD1qfCVwjm) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple2(1, 0.1) + v1, v2 := t.Unbox() + fmt.Printf("%v %v", v1, v2) + + // Output: 1 0.1 +} +``` + +### Zip2 + +Create a slice of Tuple2, whose elements are correspond to the given slice elements.
+ +Signature: + +```go +func Zip2[A any, B any](a []A, b []B) []Tuple2[A, B] +``` + +Example:[Run](https://go.dev/play/p/4ncWJJ77Xio) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip2([]int{1}, []float64{0.1}) + fmt.Println(result) + + // Output: [{1 0.1}] +} +``` + +### Unzip2 + +Create a group of slice from a slice of Tuple2.
+ +Signature: + +```go +func Unzip2[A any, B any](tuples []Tuple2[A, B]) ([]A, []B) +``` + +Example:[Run](https://go.dev/play/p/KBecr60feXb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2 := tuple.Unzip2([]tuple.Tuple2[int, float64]{{FieldA: 1, FieldB: 0.1}}) + + fmt.Printf("%v %v", v1, v2) + + // Output: [1] [0.1] +} +``` + +### Tuple3 + +Tuple3 represents a 3 elemnets tuple.
+ +Signature: + +```go +type Tuple3[A any, B any, C any] struct { + FieldA A + FieldB B + FieldC C +} + +func NewTuple3[A any, B any, C any](a A, b B c C) Tuple3[A, B, C] +``` + +Example:[Run](https://go.dev/play/p/FtH2sdCLlCf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple3(1, 0.1, "a") + fmt.Printf("%v %v %v", t.FieldA, t.FieldB, t.FieldC) + + // Output: 1 0.1 a +} +``` + +### Tuple3_Unbox + +Tuple3 Unbox returns values in tuple.
+ +Signature: + +```go +func (t Tuple3[A, B, C]) Unbox() (A, B, C) +``` + +Example:[Run](https://go.dev/play/p/YojLy-id1BS) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple3(1, 0.1, "a") + v1, v2, v3 := t.Unbox() + fmt.Printf("%v %v %v", v1, v2, v3) + + // Output: 1 0.1 a +} +``` + +### Zip3 + +Create a slice of Tuple3, whose elements are correspond to the given slice elements.
+ +Signature: + +```go +func Zip3[A any, B any, C any](a []A, b []B, c []C) []Tuple3[A, B, C] +``` + +Example:[Run](https://go.dev/play/p/97NgmsTILfu) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip3([]int{1}, []float64{0.1}, []string{"a"}) + fmt.Println(result) + + // Output: [{1 0.1 a}] +} +``` + +### Unzip3 + +Create a group of slice from a slice of Tuple3.
+ +Signature: + +```go +func Unzip3[A any, B any, C any](tuples []Tuple3[A, B, C]) ([]A, []B, []C) +``` + +Example:[Run](https://go.dev/play/p/bba4cpAa7KO) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3 := tuple.Unzip3([]tuple.Tuple3[int, float64, string]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a"}, + }) + + fmt.Printf("%v %v %v", v1, v2, v3) + + // Output: [1] [0.1] [a] +} +``` + +### Tuple4 + +Tuple4 represents a 4 elemnets tuple.
+ +Signature: + +```go +type Tuple4[A any, B any, C any, D any] struct { + FieldA A + FieldB B + FieldC C + FieldD D +} + +func NewTuple4[A any, B any, C any, D any](a A, b B, c C, d D) Tuple4[A, B, C, D] +``` + +Example:[Run](https://go.dev/play/p/D2EqDz096tk) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple4(1, 0.1, "a", true) + fmt.Printf("%v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD) + + // Output: 1 0.1 a true +} +``` + +### Tuple4_Unbox + +Tuple4 Unbox returns values in tuple.
+ +Signature: + +```go +func (t Tuple4[A, B, C, D]) Unbox() (A, B, C, D) +``` + +Example:[Run](https://go.dev/play/p/ACj9YuACGgW) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple4(1, 0.1, "a", true) + v1, v2, v3, v4 := t.Unbox() + fmt.Printf("%v %v %v %v", v1, v2, v3, v4) + + // Output: 1 0.1 a true +} +``` + +### Zip4 + +Create a slice of Tuple4, whose elements are correspond to the given slice elements.
+ +Signature: + +```go +func Zip4[A any, B any, C any, D any](a []A, b []B, c []C, d []D) []Tuple4[A, B, C, D] +``` + +Example:[Run](https://go.dev/play/p/PEmTYVK5hL4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip4([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}) + fmt.Println(result) + + // Output: [{1 0.1 a true}] +} +``` + +### Unzip4 + +Create a group of slice from a slice of Tuple4.
+ +Signature: + +```go +func Unzip4[A any, B any, C any, D any](tuples []Tuple4[A, B, C, D]) ([]A, []B, []C, []D) +``` + +Example:[Run](https://go.dev/play/p/rb8z4gyYSRN) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4 := tuple.Unzip4([]tuple.Tuple4[int, float64, string, bool]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true}, + }) + + fmt.Printf("%v %v %v %v", v1, v2, v3, v4) + + // Output: [1] [0.1] [a] [true] +} +``` + +### Tuple5 + +Tuple5 represents a 5 elemnets tuple.
+ +Signature: + +```go +type Tuple5[A any, B any, C any, D any, E any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E +} + +func NewTuple5[A any, B any, C any, D any, E any](a A, b B, c C, d D, e E) Tuple5[A, B, C, D, E] +``` + +Example:[Run](https://go.dev/play/p/2WndmVxPg-r) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple5(1, 0.1, "a", true, 2) + fmt.Printf("%v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE) + + // Output: 1 0.1 a true 2 +} +``` + +### Tuple5_Unbox + +Tuple5 Unbox returns values in tuple.
+ +Signature: + +```go +func (t Tuple5[A, B, C, D, E]) Unbox() (A, B, C, D, E) +``` + +Example:[Run](https://go.dev/play/p/GyIyZHjCvoS) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple5(1, 0.1, "a", true, 2) + v1, v2, v3, v4, v5 := t.Unbox() + fmt.Printf("%v %v %v %v %v", v1, v2, v3, v4, v5) + + // Output: 1 0.1 a true 2 +} +``` + +### Zip5 + +Create a slice of Tuple5, whose elements are correspond to the given slice elements.
+ +Signature: + +```go +func Zip5[A any, B any, C any, D any, E any](a []A, b []B, c []C, d []D, e []E) []Tuple5[A, B, C, D, E] +``` + +Example:[Run](https://go.dev/play/p/fCAAJLMfBIP) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip5([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}, []int{2}) + fmt.Println(result) + + // Output: [{1 0.1 a true 2}] +} +``` + +### Unzip5 + +Create a group of slice from a slice of Tuple5.
+ +Signature: + +```go +func Unzip5[A any, B any, C any, D any, E any](tuples []Tuple5[A, B, C, D, E]) ([]A, []B, []C, []D, []E) +``` + +Example:[Run](https://go.dev/play/p/gyl6vKfhqPb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4, v5 := tuple.Unzip5([]tuple.Tuple5[int, float64, string, bool, int]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2}, + }) + + fmt.Printf("%v %v %v %v %v", v1, v2, v3, v4, v5) + + // Output: [1] [0.1] [a] [true] [2] +} +``` + +### Tuple6 + +Tuple6 represents a 6 elemnets tuple.
+ +Signature: + +```go +type Tuple6[A any, B any, C any, D any, E any, F any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F +} + +func NewTuple6[A any, B any, C any, D any, E any, F any](a A, b B, c C, d D, e E, f F) Tuple6[A, B, C, D, E, F] +``` + +Example:[Run](https://go.dev/play/p/VjqcCwEJZbs) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple6(1, 0.1, "a", true, 2, 2.2) + fmt.Printf("%v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF) + + // Output: 1 0.1 a true 2 2.2 +} +``` + +### Tuple6_Unbox + +Tuple6 Unbox returns values in tuple.
+ +Signature: + +```go +func (t Tuple6[A, B, C, D, E, F]) Unbox() (A, B, C, D, E, F) +``` + +Example:[Run](https://go.dev/play/p/FjIHV7lpxmW) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple6(1, 0.1, "a", true, 2, 2.2) + v1, v2, v3, v4, v5, v6 := t.Unbox() + fmt.Printf("%v %v %v %v %v %v", v1, v2, v3, v4, v5, v6) + + // Output: 1 0.1 a true 2 2.2 +} +``` + +### Zip6 + +Create a slice of Tuple6, whose elements are correspond to the given slice elements.
+ +Signature: + +```go +func Zip6[A any, B any, C any, D any, E any, F any](a []A, b []B, c []C, d []D, e []E, f []F) []Tuple6[A, B, C, D, E, F] +``` + +Example:[Run](https://go.dev/play/p/oWPrnUYuFHo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip6([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}, []int{2}, []float32{2.2}) + fmt.Println(result) + + // Output: [{1 0.1 a true 2 2.2}] +} +``` + +### Unzip6 + +Create a group of slice from a slice of Tuple6.
+ +Signature: + +```go +func Unzip6[A any, B any, C any, D any, E any, F any](tuples []Tuple6[A, B, C, D, E, F]) ([]A, []B, []C, []D, []E, []F) +``` + +Example:[Run](https://go.dev/play/p/l41XFqCyh5E) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4, v5, v6 := tuple.Unzip6([]tuple.Tuple6[int, float64, string, bool, int, float32]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2}, + }) + + fmt.Printf("%v %v %v %v %v %v", v1, v2, v3, v4, v5, v6) + + // Output: [1] [0.1] [a] [true] [2] [2.2] +} +``` + +### Tuple7 + +Tuple7 represents a 7 elemnets tuple.
+ +Signature: + +```go +type Tuple7[A any, B any, C any, D any, E any, F any, G any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F + FieldG G +} + +func NewTuple7[A any, B any, C any, D any, E any, F any, G any](a A, b B, c C, d D, e E, f F, g G) Tuple7[A, B, C, D, E, F, G] +``` + +Example:[Run](https://go.dev/play/p/dzAgv_Ezub9) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple7(1, 0.1, "a", true, 2, 2.2, "b") + fmt.Printf("%v %v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG) + + // Output: 1 0.1 a true 2 2.2 b +} +``` + +### Tuple7_Unbox + +Tuple7 Unbox returns values in tuple.
+ +Signature: + +```go +func (t Tuple7[A, B, C, D, E, F, G]) Unbox() (A, B, C, D, E, F, G) +``` + +Example:[Run](https://go.dev/play/p/R9I8qeDk0zs) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple7(1, 0.1, "a", true, 2, 2.2, "b") + v1, v2, v3, v4, v5, v6, v7 := t.Unbox() + fmt.Printf("%v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7) + + // Output: 1 0.1 a true 2 2.2 b +} +``` + +### Zip7 + +Create a slice of Tuple7, whose elements are correspond to the given slice elements.
+ +Signature: + +```go +func Zip7[A any, B any, C any, D any, E any, F any, G any](a []A, b []B, c []C, d []D, e []E, f []F, g []G) []Tuple7[A, B, C, D, E, F, G] +``` + +Example:[Run](https://go.dev/play/p/WUJuo897Egf) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip7([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}, []int{2}, []float32{2.2}, []string{"b"}) + fmt.Println(result) + + // Output: [{1 0.1 a true 2 2.2 b}] +} +``` + +### Unzip7 + +Create a group of slice from a slice of Tuple7.
+ +Signature: + +```go +func Unzip7[A any, B any, C any, D any, E any, F any, G any](tuples []Tuple7[A, B, C, D, E, F, G]) ([]A, []B, []C, []D, []E, []F, []G) +``` + +Example:[Run](https://go.dev/play/p/hws_P1Fr2j3) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4, v5, v6, v7 := tuple.Unzip7([]tuple.Tuple7[int, float64, string, bool, int, float32, string]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b"}, + }) + + fmt.Printf("%v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7) + + // Output: [1] [0.1] [a] [true] [2] [2.2] [b] +} +``` + +### Tuple8 + +Tuple8 represents a 8 elemnets tuple.
+ +Signature: + +```go +type Tuple8[A any, B any, C any, D any, E any, F any, G any, H any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F + FieldG G + FieldH H +} + +func NewTuple8[A any, B any, C any, D any, E any, F any, G any, H any](a A, b B, c C, d D, e E, f F, g G, h H) Tuple8[A, B, C, D, E, F, G, H] +``` + +Example:[Run](https://go.dev/play/p/YA9S0rz3dRz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple8(1, 0.1, "a", true, 2, 2.2, "b", "c") + fmt.Printf("%v %v %v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH) + + // Output: 1 0.1 a true 2 2.2 b c +} +``` + +### Tuple8_Unbox + +Tuple8 Unbox returns values in tuple.
+ +Signature: + +```go +func (t Tuple8[A, B, C, D, E, F, G, H]) Unbox() (A, B, C, D, E, F, G, H) +``` + +Example:[Run](https://go.dev/play/p/PRxLBBb4SMl) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple8(1, 0.1, "a", true, 2, 2.2, "b", "c") + v1, v2, v3, v4, v5, v6, v7, v8 := t.Unbox() + fmt.Printf("%v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8) + + // Output: 1 0.1 a true 2 2.2 b c +} +``` + +### Zip8 + +Create a slice of Tuple8, whose elements are correspond to the given slice elements.
+ +Signature: + +```go +func Zip8[A any, B any, C any, D any, E any, F any, G any, H any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H) []Tuple8[A, B, C, D, E, F, G, H] +``` + +Example:[Run](https://go.dev/play/p/8V9jWkuJfaQ) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip8([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}, []int{2}, []float32{2.2}, []string{"b"}, []string{"c"}) + fmt.Println(result) + + // Output: [{1 0.1 a true 2 2.2 b c}] +} +``` + +### Unzip8 + +Create a group of slice from a slice of Tuple8.
+ +Signature: + +```go +func Unzip8[A any, B any, C any, D any, E any, F any, G any, H any](tuples []Tuple8[A, B, C, D, E, F, G, H]) ([]A, []B, []C, []D, []E, []F, []G, []H) +``` + +Example:[Run](https://go.dev/play/p/1SndOwGsZB4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4, v5, v6, v7, v8 := tuple.Unzip8([]tuple.Tuple8[int, float64, string, bool, int, float32, string, string]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b", FieldH: "c"}, + }) + + fmt.Printf("%v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8) + + // Output: [1] [0.1] [a] [true] [2] [2.2] [b] [c] +} +``` + +### Tuple9 + +Tuple9 represents a 9 elemnets tuple.
+ +Signature: + +```go + +type Tuple9[A any, B any, C any, D any, E any, F any, G any, H any, I any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F + FieldG G + FieldH H + FieldI I +} + +func NewTuple9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a A, b B, c C, d D, e E, f F, g G, h H, i I) Tuple9[A, B, C, D, E, F, G, H, I] + +``` + +Example:[Run](https://go.dev/play/p/yS2NGGtZpQr) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple9(1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}) + fmt.Printf("%v %v %v %v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH, t.FieldI) + + // Output: 1 0.1 a true 2 2.2 b c map[a:1] +} +``` + +### Tuple9_Unbox + +Tuple9 Unbox returns values in tuple.
+ +Signature: + +```go +func (t Tuple9[A, B, C, D, E, F, G, H, I]) Unbox() (A, B, C, D, E, F, G, H, I) +``` + +Example:[Run](https://go.dev/play/p/oFJFGTAuOa8) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + t := tuple.NewTuple9(1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}) + v1, v2, v3, v4, v5, v6, v7, v8, v9 := t.Unbox() + fmt.Printf("%v %v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8, v9) + + // Output: 1 0.1 a true 2 2.2 b c map[a:1] +} +``` + +### Zip9 + +Create a slice of Tuple9, whose elements are correspond to the given slice elements.
+ +Signature: + +```go +func Zip9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I) []Tuple9[A, B, C, D, E, F, G, H, I] +``` + +Example:[Run](https://go.dev/play/p/cgsL15QYnfz) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip9([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}, []int{2}, []float32{2.2}, []string{"b"}, []string{"c"}, []int64{3}) + fmt.Println(result) + + // Output: [{1 0.1 a true 2 2.2 b c 3}] +} +``` + +### Unzip9 + +Create a group of slice from a slice of Tuple9.
+ +Signature: + +```go +func Unzip9[A any, B any, C any, D any, E any, F any, G any, H any, I any](tuples []Tuple9[A, B, C, D, E, F, G, H, I]) ([]A, []B, []C, []D, []E, []F, []G, []H, []I) +``` + +Example:[Run](https://go.dev/play/p/91-BU_KURSA) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4, v5, v6, v7, v8, v9 := tuple.Unzip9([]tuple.Tuple9[int, float64, string, bool, int, float32, string, string, int64]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b", FieldH: "c", FieldI: 3}, + }) + + fmt.Printf("%v %v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8, v9) + + // Output: [1] [0.1] [a] [true] [2] [2.2] [b] [c] [3] +} +``` + +### Tuple10 + +Tuple10 represents a 10 elemnets tuple.
+ +Signature: + +```go + +type Tuple10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F + FieldG G + FieldH H + FieldI I + FieldJ J +} + +func NewTuple10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](a A, b B, c C, d D, e E, f F, g G, h H, i I, j J) Tuple10[A, B, C, D, E, F, G, H, I, J] + +``` + +Example:[Run](https://go.dev/play/p/799qqZg0hUv) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + type foo struct { + A string + } + t := tuple.NewTuple10(1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}, foo{A: "a"}) + fmt.Printf("%v %v %v %v %v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH, t.FieldI, t.FieldJ) + + // Output: 1 0.1 a true 2 2.2 b c map[a:1] {a} +} +``` + +### Tuple10_Unbox + +Tuple10 Unbox returns values in tuple.
+ +Signature: + +```go +func (t Tuple10[A, B, C, D, E, F, G, H, I, J]) Unbox() (A, B, C, D, E, F, G, H, I, J) +``` + +Example:[Run](https://go.dev/play/p/qfyx3x_X0Cu) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + type foo struct { + A string + } + t := tuple.NewTuple10(1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}, foo{A: "a"}) + v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 := t.Unbox() + fmt.Printf("%v %v %v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) + + // Output: 1 0.1 a true 2 2.2 b c map[a:1] {a} +} +``` + +### Zip10 + +Create a slice of Tuple10, whose elements are correspond to the given slice elements.
+ +Signature: + +```go +func Zip10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I, j []J) []Tuple10[A, B, C, D, E, F, G, H, I, J] +``` + +Example:[Run](https://go.dev/play/p/YSR-2cXnrY4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + result := tuple.Zip10([]int{1}, []float64{0.1}, []string{"a"}, []bool{true}, []int{2}, []float32{2.2}, []string{"b"}, []string{"c"}, []int64{3}, []bool{false}) + fmt.Println(result) + + // Output: [{1 0.1 a true 2 2.2 b c 3 false}] +} +``` + +### Unzip10 + +Create a group of slice from a slice of Tuple10.
+ +Signature: + +```go +func Unzip10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](tuples []Tuple10[A, B, C, D, E, F, G, H, I, J]) ([]A, []B, []C, []D, []E, []F, []G, []H, []I, []J) +``` + +Example:[Run](https://go.dev/play/p/-taQB6Wfre_z) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/tuple" +) + +func main() { + v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 := tuple.Unzip10([]tuple.Tuple10[int, float64, string, bool, int, float32, string, string, int64, bool]{ + {FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b", FieldH: "c", FieldI: 3, FieldJ: false}, + }) + + fmt.Printf("%v %v %v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) + + // Output: [1] [0.1] [a] [true] [2] [2.2] [b] [c] [3] [false] +} +``` diff --git a/docs/en/api/packages/validator.md b/docs/en/api/packages/validator.md new file mode 100644 index 00000000..2ab510dc --- /dev/null +++ b/docs/en/api/packages/validator.md @@ -0,0 +1,1571 @@ +# Validator + +Package validator contains some functions for data validation. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/validator/validator.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/validator" +) +``` + + + +## Index + +- [ContainChinese](#ContainChinese) +- [ContainLetter](#ContainLetter) +- [ContainLower](#ContainLower) +- [ContainUpper](#ContainUpper) +- [IsAlpha](#IsAlpha) +- [IsAllUpper](#IsAllUpper) +- [IsAllLower](#IsAllLower) +- [IsASCII](#IsASCII) +- [IsBase64](#IsBase64) +- [IsChineseMobile](#IsChineseMobile) +- [IsChineseIdNum](#IsChineseIdNum) +- [IsChinesePhone](#IsChinesePhone) +- [IsCreditCard](#IsCreditCard) +- [IsDns](#IsDns) +- [IsEmail](#IsEmail) +- [IsEmptyString](#IsEmptyString) +- [IsInt](#IsInt) +- [IsFloat](#IsFloat) +- [IsNumber](#IsNumber) +- [IsIntStr](#IsIntStr) +- [IsFloatStr](#IsFloatStr) +- [IsNumberStr](#IsNumberStr) +- [IsJSON](#IsJSON) +- [IsRegexMatch](#IsRegexMatch) +- [IsIp](#IsIp) +- [IsIpV4](#IsIpV4) +- [IsIpV6](#IsIpV6) +- [IsIpPort](#IsIpPort) +- [IsStrongPassword](#IsStrongPassword) +- [IsUrl](#IsUrl) +- [IsWeakPassword](#IsWeakPassword) +- [IsZeroValue](#IsZeroValue) +- [IsGBK](#IsGBK) +- [IsPrintable](#IsPrintable) +- [IsBin](#IsBin) +- [IsHex](#IsHex) +- [IsBase64URL](#IsBase64URL) +- [IsJWT](#IsJWT) +- [IsVisa](#IsVisa) +- [IsMasterCard](#IsMasterCard) +- [IsAmericanExpress](#IsAmericanExpress) +- [IsUnionPay](#IsUnionPay) +- [IsChinaUnionPay](#IsChinaUnionPay) + + + + + +## Documentation + +### ContainChinese + +Check if the string contain mandarin chinese.
+ +Signature: + +```go +func ContainChinese(s string) bool +``` + +Example:[Run](https://go.dev/play/p/7DpU0uElYeM) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.ContainChinese("你好") + result2 := validator.ContainChinese("你好hello") + result3 := validator.ContainChinese("hello") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### ContainLetter + +Check if the string contain at least one letter.
+ +Signature: + +```go +func ContainLetter(str string) bool +``` + +Example:[Run](https://go.dev/play/p/lqFD04Yyewp) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.ContainLetter("你好") + result2 := validator.ContainLetter("&@#$%^&*") + result3 := validator.ContainLetter("ab1") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // false + // false + // true +} +``` + +### ContainLower + +Check if the string contain at least one lower case letter a-z.
+ +Signature: + +```go +func ContainLower(str string) bool +``` + +Example:[Run](https://go.dev/play/p/Srqi1ItvnAA) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.ContainLower("abc") + result2 := validator.ContainLower("aBC") + result3 := validator.ContainLower("ABC") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### ContainUpper + +Check if the string contain at least one upper case letter A-Z.
+ +Signature: + +```go +func ContainUpper(str string) bool +``` + +Example:[Run](https://go.dev/play/p/CmWeBEk27-z) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.ContainUpper("ABC") + result2 := validator.ContainUpper("abC") + result3 := validator.ContainUpper("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### IsAlpha + +Check if the string contains only letters (a-zA-Z).
+ +Signature: + +```go +func IsAlpha(s string) bool +``` + +Example:[Run](https://go.dev/play/p/7Q5sGOz2izQ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsAlpha("abc") + result2 := validator.IsAlpha("ab1") + result3 := validator.IsAlpha("") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsAllUpper + +Check if string is all upper case letters A-Z.
+ +Signature: + +```go +func IsAllUpper(str string) bool +``` + +Example:[Run](https://go.dev/play/p/ZHctgeK1n4Z) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsAllUpper("ABC") + result2 := validator.IsAllUpper("ABc") + result3 := validator.IsAllUpper("AB1") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsAllLower + +Check if string is all lower case letters a-z.
+ +Signature: + +```go +func IsAllLower(str string) bool +``` + +Example:[Run](https://go.dev/play/p/GjqCnOfV6cM) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsAllLower("abc") + result2 := validator.IsAllLower("abC") + result3 := validator.IsAllLower("ab1") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsASCII + +Checks if string is all ASCII char.
+ +Signature: + +```go +func IsASCII(str string) bool +``` + +Example:[Run](https://go.dev/play/p/hfQNPLX0jNa) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsASCII("ABC") + result2 := validator.IsASCII("123") + result3 := validator.IsASCII("") + result4 := validator.IsASCII("😄") + result5 := validator.IsASCII("你好") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // true + // true + // true + // false + // false +} +``` + +### IsBase64 + +Check if the string is base64 string.
+ +Signature: + +```go +func IsBase64(base64 string) bool +``` + +Example:[Run](https://go.dev/play/p/sWHEySAt6hl) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsBase64("aGVsbG8=") + result2 := validator.IsBase64("123456") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsChineseMobile + +Check if the string is valid chinese mobile number.
+ +Signature: + +```go +func IsChineseMobile(mobileNum string) bool +``` + +Example:[Run](https://go.dev/play/p/GPYUlGTOqe3) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsChineseMobile("13263527980") + result2 := validator.IsChineseMobile("434324324") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsChineseIdNum + +Check if the string is chinese id number.
+ +Signature: + +```go +func IsChineseIdNum(id string) bool +``` + +Example:[Run](https://go.dev/play/p/d8EWhl2UGDF) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsChineseIdNum("210911192105130715") + result2 := validator.IsChineseIdNum("123456") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsChinesePhone + +Check if the string is chinese phone number.
+ +Signature: + +```go +func IsChinesePhone(phone string) bool +``` + +Example:[Run](https://go.dev/play/p/RUD_-7YZJ3I) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsChinesePhone("010-32116675") + result2 := validator.IsChinesePhone("123-87562") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsCreditCard + +Check if the string is credit card.
+ +Signature: + +```go +func IsCreditCard(creditCart string) bool +``` + +Example:[Run](https://go.dev/play/p/sNwwL6B0-v4) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsCreditCard("4111111111111111") + result2 := validator.IsCreditCard("123456") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsDns + +Check if the string is valid dns.
+ +Signature: + +```go +func IsDns(dns string) bool +``` + +Example:[Run](https://go.dev/play/p/jlYApVLLGTZ) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsDns("abc.com") + result2 := validator.IsDns("a.b.com") + result3 := validator.IsDns("http://abc.com") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsEmail + +Check if the string is email address.
+ +Signature: + +```go +func IsEmail(email string) bool +``` + +Example:[Run](https://go.dev/play/p/Os9VaFlT33G) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsEmail("abc@xyz.com") + result2 := validator.IsEmail("a.b@@com") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsEmptyString + +Check if the string is empty or not.
+ +Signature: + +```go +func IsEmptyString(s string) bool +``` + +Example:[Run](https://go.dev/play/p/dpzgUjFnBCX) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsEmptyString("") + result2 := validator.IsEmptyString(" ") + result3 := validator.IsEmptyString("\t") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // false + // false +} +``` + +### IsInt + +Check if the value is integer(int, unit) or not.
+ +Signature: + +```go +func IsInt(v any) bool +``` + +Example:[Run](https://go.dev/play/p/eFoIHbgzl-z) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsInt("") + result2 := validator.IsInt("3") + result3 := validator.IsInt(0.1) + result4 := validator.IsInt(0) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // false + // true +} +``` + +### IsFloat + +Check if the value is float(float32, float34) or not.
+ +Signature: + +```go +func IsFloat(v any) bool +``` + +Example:[Run](https://go.dev/play/p/vsyG-sxr99_Z) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsFloat("") + result2 := validator.IsFloat("3") + result3 := validator.IsFloat(0) + result4 := validator.IsFloat(0.1) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // false + // true +} +``` + +### IsNumber + +Check if the value is number(integer, float) or not.
+ +Signature: + +```go +func IsNumber(v any) bool +``` + +Example:[Run](https://go.dev/play/p/mdJHOAvtsvF) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsNumber("") + result2 := validator.IsNumber("3") + result3 := validator.IsNumber(0.1) + result4 := validator.IsNumber(0) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // true + // true +} +``` + +### IsIntStr + +Check if the string can convert to a integer.
+ +Signature: + +```go +func IsIntStr(s string) bool +``` + +Example:[Run](https://go.dev/play/p/jQRtFv-a0Rk) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsIntStr("+3") + result2 := validator.IsIntStr("-3") + result3 := validator.IsIntStr("3.") + result4 := validator.IsIntStr("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsFloatStr + +Check if the string can convert to a float.
+ +Signature: + +```go +func IsFloatStr(s string) bool +``` + +Example:[Run](https://go.dev/play/p/LOYwS_Oyl7U) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsFloatStr("3.") + result2 := validator.IsFloatStr("+3.") + result3 := validator.IsFloatStr("12") + result4 := validator.IsFloatStr("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // true + // false +} +``` + +### IsNumberStr + +Check if the string can convert to a number.
+ +Signature: + +```go +func IsNumberStr(s string) bool +``` + +Example:[Run](https://go.dev/play/p/LzaKocSV79u) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsNumberStr("3.") + result2 := validator.IsNumberStr("+3.") + result3 := validator.IsNumberStr("+3e2") + result4 := validator.IsNumberStr("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // true + // false +} +``` + +### IsAlphaNumeric + +Check if the string is alphanumeric.
+ +Signature: + +```go +func IsAlphaNumeric(s string) bool +``` + +Example:[Run](https://go.dev/play/p/RHeESLrLg9c) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsAlphaNumeric("ABC") + result2 := validator.IsAlphaNumeric("123") + result3 := validator.IsAlphaNumeric("abc123") + result4 := validator.IsAlphaNumeric("abc123@#$") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // true + // false +} +``` + +### IsJSON + +Check if the string is valid JSON.
+ +Signature: + +```go +func IsJSON(str string) bool +``` + +Example:[Run](https://go.dev/play/p/8Kip1Itjiil) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsJSON("{}") + result2 := validator.IsJSON("{\"name\": \"test\"}") + result3 := validator.IsJSON("") + result4 := validator.IsJSON("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsRegexMatch + +Check if the string match the regexp.
+ +Signature: + +```go +func IsRegexMatch(s, regex string) bool +``` + +Example:[Run](https://go.dev/play/p/z_XeZo_litG) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsRegexMatch("abc", `^[a-zA-Z]+$`) + result2 := validator.IsRegexMatch("ab1", `^[a-zA-Z]+$`) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsIp + +Check if the string is a ip address.
+ +Signature: + +```go +func IsIp(ipstr string) bool +``` + +Example:[Run](https://go.dev/play/p/FgcplDvmxoD) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsIp("127.0.0.1") + result2 := validator.IsIp("::0:0:0:0:0:0:1") + result3 := validator.IsIp("127.0.0") + result4 := validator.IsIp("::0:0:0:0:") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsIpV4 + +Check if the string is a ipv4 address.
+ +Signature: + +```go +func IsIpV4(ipstr string) bool +``` + +Example:[Run](https://go.dev/play/p/zBGT99EjaIu) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsIpV4("127.0.0.1") + result2 := validator.IsIpV4("::0:0:0:0:0:0:1") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsIpV6 + +Check if the string is a ipv6 address.
+ +Signature: + +```go +func IsIpV6(ipstr string) bool +``` + +Example:[Run](https://go.dev/play/p/AHA0r0AzIdC) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsIpV6("127.0.0.1") + result2 := validator.IsIpV6("::0:0:0:0:0:0:1") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // false + // true +} +``` + +### IsIpPort + +Check if the string is ip:port
+ +Signature: + +```go +func IsIpPort(str string) bool +``` + +Example:[Run](https://go.dev/play/p/xUmls_b9L29) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsIpPort("127.0.0.1:8080") + result2 := validator.IsIpPort("[0:0:0:0:0:0:0:1]:8080") + result3 := validator.IsIpPort(":8080") + result4 := validator.IsIpPort("::0:0:0:0:") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsStrongPassword + +Check if the string is strong password (alpha(lower+upper) + number + special chars(!@#$%^&*()?gt<)).
+ +Signature: + +```go +func IsStrongPassword(password string, length int) bool +``` + +Example:[Run](https://go.dev/play/p/QHdVcSQ3uDg) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsStrongPassword("abcABC", 6) + result2 := validator.IsStrongPassword("abcABC123@#$", 10) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // false + // true +} +``` + +### IsUrl + +Check if the string is url.
+ +Signature: + +```go +func IsUrl(str string) bool +``` + +Example:[Run](https://go.dev/play/p/pbJGa7F98Ka) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsUrl("abc.com") + result2 := validator.IsUrl("http://abc.com") + result3 := validator.IsUrl("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // true + // true + // false +} +``` + +### IsWeakPassword + +Checks if the string is weak password(only letter or only number or letter + number) +.
+ +Signature: + +```go +func IsWeakPassword(password string, length int) bool +``` + +Example:[Run](https://go.dev/play/p/wqakscZH5gH) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsWeakPassword("abcABC") + result2 := validator.IsWeakPassword("abc123@#$") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsZeroValue + +Checks if passed value is a zero value.
+ +Signature: + +```go +func IsZeroValue(value any) bool +``` + +Example:[Run](https://go.dev/play/p/UMrwaDCi_t4) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsZeroValue("") + result2 := validator.IsZeroValue(0) + result3 := validator.IsZeroValue("abc") + result4 := validator.IsZeroValue(1) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsGBK + +Checks if data encoding is gbk(Chinese character internal code extension specification). this function is implemented by whether double bytes fall within the encoding range of gbk,while each byte of utf-8 encoding format falls within the encoding range of gbk.Therefore, utf8.valid() should be called first to check whether it is not utf-8 encoding and then call IsGBK() to check gbk encoding. like the example.
+ +Signature: + +```go +func IsGBK(data []byte) bool +``` + +Example:[Run](https://go.dev/play/p/E2nt3unlmzP) + +```go +import ( + "fmt" + "golang.org/x/text/encoding/simplifiedchinese" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + str := "你好" + gbkData, _ := simplifiedchinese.GBK.NewEncoder().Bytes([]byte(str)) + + result := validator.IsGBK(gbkData) + + fmt.Println(result) + + // Output: + // true +} +``` + +### IsPrintable + +Checks if string is all printable chars.
+ +Signature: + +```go +func IsPrintable(str string) bool +``` + +Example:[Run](https://go.dev/play/p/Pe1FE2gdtTP) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsPrintable("ABC") + result2 := validator.IsPrintable("{id: 123}") + result3 := validator.IsPrintable("") + result4 := validator.IsPrintable("😄") + result5 := validator.IsPrintable("\u0000") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // true + // true + // true + // true + // false +} +``` + +### IsBin + +Checks if a give string is a valid binary value or not.
+ +Signature: + +```go +func IsBin(v string) bool +``` + +Example:[Run](https://go.dev/play/p/ogPeg2XJH4P) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsBin("0101") + result2 := validator.IsBin("0b1101") + result3 := validator.IsBin("b1101") + result4 := validator.IsBin("1201") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsHex + +Checks if a give string is a valid hexadecimal value or not.
+ +Signature: + +```go +func IsHex(v string) bool +``` + +Example:[Run](https://go.dev/play/p/M2qpHbEwmm7) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsHex("0xabcde") + result2 := validator.IsHex("0XABCDE") + result3 := validator.IsHex("cdfeg") + result4 := validator.IsHex("0xcdfeg") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsBase64URL + +Checks if a give string is a valid URL-safe Base64 encoded string.
+ +Signature: + +```go +func IsBase64URL(v string) bool +``` + +Example:[Run](https://go.dev/play/p/vhl4mr8GZ6S) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ") + result2 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ==") + result3 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ=") + result4 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ===") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + +### IsJWT + +Checks if a give string is is a valid JSON Web Token (JWT).
+ +Signature: + +```go +func IsJWT(v string) bool +``` + +Example:[Run](https://go.dev/play/p/R6Op7heJbKI) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsJWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibWVzc2FnZSI6IlB1dGluIGlzIGFic29sdXRlIHNoaXQiLCJpYXQiOjE1MTYyMzkwMjJ9.wkLWA5GtCpWdxNOrRse8yHZgORDgf8TpJp73WUQb910") + result2 := validator.IsJWT("abc") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsVisa + +Checks if a give string is a valid visa card nubmer or not.
+ +Signature: + +```go +func IsVisa(v string) bool +``` + +Example:[Run](https://go.dev/play/p/SdS2keOyJsl) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsVisa("4111111111111111") + result2 := validator.IsVisa("123") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsMasterCard + +Checks if a give string is a valid mastercard nubmer or not.
+ +Signature: + +```go +func IsMasterCard(v string) bool +``` + +Example:[Run](https://go.dev/play/p/CwWBFRrG27b) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsMasterCard("5425233430109903") + result2 := validator.IsMasterCard("4111111111111111") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsAmericanExpress + +Checks if a give string is a valid american express nubmer or not.
+ +Signature: + +```go +func IsAmericanExpress(v string) bool +``` + +Example:[Run](https://go.dev/play/p/HIDFpcOdpkd) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsAmericanExpress("342883359122187") + result2 := validator.IsAmericanExpress("3782822463100007") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsVisa + +Checks if a give string is a valid union pay nubmer or not.
+ +Signature: + +```go +func IsUnionPay(v string) bool +``` + +Example:[Run](https://go.dev/play/p/CUHPEwEITDf) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsUnionPay("6221263430109903") + result2 := validator.IsUnionPay("3782822463100007") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + +### IsChinaUnionPay + +Checks if a give string is a valid china union pay nubmer or not.
+ +Signature: + +```go +func IsChinaUnionPay(v string) bool +``` + +Example:[Run](https://go.dev/play/p/yafpdxLiymu) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/validator" +) + +func main() { + result1 := validator.IsChinaUnionPay("6250941006528599") + result2 := validator.IsChinaUnionPay("3782822463100007") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` diff --git a/docs/en/api/packages/xerror.md b/docs/en/api/packages/xerror.md new file mode 100644 index 00000000..364e821f --- /dev/null +++ b/docs/en/api/packages/xerror.md @@ -0,0 +1,543 @@ +# Xerror + +Package xerror implements helpers for errors. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/xerror/xerror.go](https://github.com/duke-git/lancet/blob/main/xerror/xerror.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/xerror" +) +``` + + + +## Index + +- [New](#New) +- [Wrap](#Wrap) +- [Unwrap](#Unwrap) +- [XError_Wrap](#XError_Wrap) +- [XError_Unwrap](#XError_Unwrap) +- [XError_With](#XError_With) +- [XError_Is](#XError_Is) +- [XError_Id](#XError_Id) +- [XError_Values](#XError_Values) +- [XError_StackTrace](#XError_StackTrace) +- [XError_Info](#XError_Info) +- [XError_Error](#XError_Error) +- [TryUnwrap](#TryUnwrap) +- [TryCatch](#TryCatch) + + + +## Documentation + +### New + +Creates a new XError pointer instance with message.
+ +Signature: + +```go +type XError struct { + id string + message string + stack *stack + cause error + values map[string]any +} + +func New(format string, args ...any) *XError +``` + +Example:[Run](https://go.dev/play/p/w4oWZts7q7f) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err := xerror.New("error") + fmt.Println(err.Error()) + + // Output: + // error +} +``` + +### Wrap + +Creates a new XError pointer instance based on error object, and add message.
+ +Signature: + +```go +func Wrap(cause error, message ...any) *XError +``` + +Example:[Run](https://go.dev/play/p/5385qT2dCi4) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err := xerror.New("wrong password") + wrapErr := xerror.Wrap(err, "error") + + fmt.Println(wrapErr.Error()) + + // Output: + // error: wrong password +} +``` + +### Unwrap + +Returns unwrapped XError from err by errors.As. If no XError, returns nil.
+ +Signature: + +```go +func Unwrap(err error) *XError +``` + +Example:[Run](https://go.dev/play/p/LKMLep723tu) + +```go +package main + +import ( + "fmt" + "github.com/pkg/errors" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err1 := xerror.New("error").With("level", "high") + wrapErr := errors.Wrap(err1, "oops") + + err := xerror.Unwrap(wrapErr) + + values := err.Values() + fmt.Println(values["level"]) + + // Output: + // high +} +``` + +### XError_Wrap + +Creates a new XError and copy message and id to new one.
+ +Signature: + +```go +func (e *XError) Wrap(cause error) *XError +``` + +Example:[Run](https://go.dev/play/p/RpjJ5u5sc97) + +```go +package main + +import ( + "fmt" + "errors" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err1 := xerror.New("error").With("level", "high") + err2 := err1.Wrap(errors.New("invalid username")) + + fmt.Println(err2.Error()) + + // Output: + // error: invalid username +} +``` + +### XError_Unwrap + +Compatible with github.com/pkg/errors.
+ +Signature: + +```go +func (e *XError) Unwrap() error +``` + +Example:[Run](https://go.dev/play/p/VUXJ8BST4c6) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err1 := xerror.New("error").With("level", "high") + err2 := err1.Wrap(errors.New("invalid username")) + + err := err2.Unwrap() + + fmt.Println(err.Error()) + + // Output: + // invalid username +} +``` + +### XError_With + +Adds key and value related to the XError object.
+ +Signature: + +```go +func (e *XError) With(key string, value any) *XError +``` + +Example:[Run](https://go.dev/play/p/ow8UISXX_Dp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err := xerror.New("error").With("level", "high") + + errLevel := err.Values()["level"] + + fmt.Println(errLevel) + + // Output: + // high +} +``` + +### XError_Id + +Sets XError object id to check equality in XError.Is.
+ +Signature: + +```go +func (e *XError) Id(id string) *XError +``` + +Example:[Run](https://go.dev/play/p/X6HBlsy58U9) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err1 := xerror.New("error").Id("e001") + err2 := xerror.New("error").Id("e001") + err3 := xerror.New("error").Id("e003") + + equal := err1.Is(err2) + notEqual := err1.Is(err3) + + fmt.Println(equal) + fmt.Println(notEqual) + + // Output: + // true + // false +} +``` + +### XError_Is + +Checks if target error is XError and Error.id of two errors are matched.
+ +Signature: + +```go +func (e *XError) Is(target error) bool +``` + +Example:[Run](https://go.dev/play/p/X6HBlsy58U9) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err1 := xerror.New("error").Id("e001") + err2 := xerror.New("error").Id("e001") + err3 := xerror.New("error").Id("e003") + + equal := err1.Is(err2) + notEqual := err1.Is(err3) + + fmt.Println(equal) + fmt.Println(notEqual) + + // Output: + // true + // false +} +``` + +### XError_Values + +Returns map of key and value that is set by With. All wrapped xerror.XError key and values will be merged. Key and values of wrapped error is overwritten by upper xerror.XError.
+ +Signature: + +```go +func (e *XError) Values() map[string]any +``` + +Example:[Run](https://go.dev/play/p/ow8UISXX_Dp) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err := xerror.New("error").With("level", "high") + + errLevel := err.Values()["level"] + + fmt.Println(errLevel) + + // Output: + // high +} +``` + + +### XError_StackTrace + +Returns stack trace which is compatible with pkg/errors.
+ +Signature: + +```go +func (e *XError) StackTrace() StackTrace +``` + +Example:[Run](https://go.dev/play/p/6FAvSQpa7pc) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err := xerror.New("error") + + stacks := err.Stacks() + + fmt.Println(stacks[0].Func) + fmt.Println(stacks[0].Line) + + containFile := strings.Contains(stacks[0].File, "xxx.go") + fmt.Println(containFile) +} +``` + + +### XError_Info + +Returns information of xerror, which can be printed.
+ +Signature: + +```go +func (e *XError) Info() *errInfo +``` + +Example:[Run](https://go.dev/play/p/1ZX0ME1F-Jb) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + cause := errors.New("error") + err := xerror.Wrap(cause, "invalid username").Id("e001").With("level", "high") + + errInfo := err.Info() + + fmt.Println(errInfo.Id) + fmt.Println(errInfo.Cause) + fmt.Println(errInfo.Values["level"]) + fmt.Println(errInfo.Message) + + // Output: + // e001 + // error + // high + // invalid username +} +``` + + +### XError_Error + +Error implements standard error interface.
+ +Signature: + +```go +func (e *XError) Error() string +``` + +Example:[Run](https://go.dev/play/p/w4oWZts7q7f) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + err := xerror.New("error") + fmt.Println(err.Error()) + + // Output: + // error +} +``` +### TryUnwrap + +TryUnwrap if err is nil then it returns a valid value. If err is not nil, Unwrap panics with err.
+ +Signature: + +```go +func TryUnwrap[T any](val T, err error) T +``` + +Example:[Run](https://go.dev/play/p/acyZVkNZEeW) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + result1 := xerror.TryUnwrap(strconv.Atoi("42")) + fmt.Println(result1) + + _, err := strconv.Atoi("4o2") + defer func() { + v := recover() + result2 := reflect.DeepEqual(err.Error(), v.(*strconv.NumError).Error()) + fmt.Println(result2) + }() + + xerror.TryUnwrap(strconv.Atoi("4o2")) + + // Output: + // 42 + // true +} +``` + +### TryCatch + +Simple simulation of Java-style try-catch. It does not align with Go's error-handling philosophy. It is recommended to use it with caution.
+ +Signature: + +```go +func NewTryCatch(ctx context.Context) *TryCatch + +func (tc *TryCatch) Try(tryFunc func(ctx context.Context) error) *TryCatch + +func (tc *TryCatch) Catch(catchFunc func(ctx context.Context, err error)) *TryCatch + +func (tc *TryCatch) Finally(finallyFunc func(ctx context.Context)) *TryCatch + +func (tc *TryCatch) Do() +``` + +Example:[Run](https://go.dev/play/p/D5Mdb0mRj0P) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/xerror" +) + +func main() { + calledFinally := false + calledCatch := false + + tc := xerror.NewTryCatch(context.Background()) + + tc.Try(func(ctx context.Context) error { + return errors.New("error message ") + }).Catch(func(ctx context.Context, err error) { + calledCatch = true + // Error in try block at /path/xxx.go:{line_number} - Cause: error message + // fmt.Println(err.Error()) + }).Finally(func(ctx context.Context) { + calledFinally = true + }).Do() + + fmt.Println(calledCatch) + fmt.Println(calledFinally) + + // Output: + // true + // true +} +``` diff --git a/docs/en/guide/contribution_guide.md b/docs/en/guide/contribution_guide.md new file mode 100644 index 00000000..f16cfb2a --- /dev/null +++ b/docs/en/guide/contribution_guide.md @@ -0,0 +1,37 @@ +# Lancet Contribution Guide + +Hi! Thank you for choosing Lancet. + +Lancet is a powerful, efficient, and reusable util function library of go. It makes Go dev easier by taking the hassle out of working with concurrency, net, math, slice, string, etc. + +We are excited that you are interested in contributing to lancet. Before submitting your contribution though, please make sure to take a moment and read through the following guidelines. + +## Issue Guidelines + +- Issues are exclusively for bug reports, feature requests and design-related topics. Other questions may be closed directly. + +- Before submitting an issue, please check if similar problems have already been issued. + +- Please specify which version of Lancet and Go you are using, and provide OS information. [Go Playground](https://go.dev/play/) is recommended to build a live demo so that your issue can be reproduced clearly. + +## Pull Request Guidelines + +- Fork this repository to your own account. Do not create branches here. + +- Commit info should be formatted as `type(scope): info about commit`. eg. `fix(package): [scrollbar] fix xxx bug`. + + 1. type: type must be one of [chore, docs, feat, fix, refactor, release, test]. + + 2. scope: scope must be one of [package, file, internal]. + + 3. header: header must not be longer than 72 characters. + +- Rebase before creating a PR to keep commit history clear. + +- Before submitting a PR, please execute the unit test command: `go test -v ./...` to ensure that all unit test tasks should pass. + +- Make sure PRs are created to `rc` branch instead of other branch. + +- If your PR fixes a bug, please provide a description about the related bug. + +- If the PR is for a new feature, make sure to complete the relevant documentation (/lancet/docs/en/api/packages). diff --git a/docs/en/guide/contributors.md b/docs/en/guide/contributors.md new file mode 100644 index 00000000..59a7c1c3 --- /dev/null +++ b/docs/en/guide/contributors.md @@ -0,0 +1,6 @@ +# Contributors +Thank you to all the people who contributed to lancet! + + +
+
+
+
Clear the file content, write empty string to the file.
- -Signature: - -```go -func ClearFile(path string) error -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - err := fileutil.ClearFile("./test.txt") - if err != nil { - fmt.Println(err) - } -} -``` - -### CreateFile -Create file in path. return true if create succeed.
- -Signature: - -```go -func CreateFile(path string) bool -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - isCreatedSucceed := fileutil.CreateFile("./test.txt") - fmt.Println(isCreatedSucceed) -} -``` - - -### CopyFile -Copy src file to dest file. If dest file exist will overwrite it.
- -Signature: - -```go -func CopyFile(srcFilePath string, dstFilePath string) error -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - err := fileutil.CopyFile("./test.txt", "./test_copy.txt") - if err != nil { - fmt.Println(err) - } -} -``` - - - -### FileMode -Return file mode infomation.
- -Signature: - -```go -func FileMode(path string) (fs.FileMode, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - mode, err := fileutil.FileMode("./test.txt") - if err != nil { - fmt.Println(err) - } - fmt.Println(mode) -} -``` - - - -### MiMeType -Get file mime type, 'file' param's type should be string or *os.File.
- -Signature: - -```go -func MiMeType(file interface{}) string -``` -Example: - -```go -package main - -import ( - "fmt" - "os" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - type1 := fileutil.MiMeType("./test.txt") - fmt.Println(type1) //text/plain; charset=utf-8 - - f, _ := os.Open("./file.go") - type2 := fileutil.MiMeType(f) - fmt.Println(type2) //text/plain; charset=utf-8 -} -``` - - - - -### IsExist -Checks if a file or directory exists.
- -Signature: - -```go -func IsExist(path string) bool -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - fileutil.CreateFile("./test.txt") - isFileExist := fileutil.IsExist("./test.txt") - fmt.Println(isFileExist) //true -} -``` - - - -### IsLink -Checks if a file is symbol link or not.
- -Signature: - -```go -func IsLink(path string) bool -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - isLinkFile := fileutil.IsLink("./test.txt") - fmt.Println(isLinkFile) //false -} -``` - - - -### IsDir -Checks if the path is directy or not.
- -Signature: - -```go -func IsDir(path string) bool -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - isDir := fileutil.IsDir("./") - fmt.Println(isDir) //true - - isDir = fileutil.IsDir("./test.txt") - fmt.Println(isDir) //false -} -``` - - - -### ListFileNames -List all file names in given path.
- -Signature: - -```go -func ListFileNames(path string) ([]string, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - fileNames, _ := fileutil.ListFileNames("./") - fmt.Println(fileNames) -} -``` - - - -### RemoveFile -Remove the file of path.
- -Signature: - -```go -func RemoveFile(path string) error -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - err := fileutil.RemoveFile("./test.txt") - if err != nil { - fmt.Println(err) - } -} -``` - - -### ReadFileToString -Return string of file content.
- -Signature: - -```go -func ReadFileToString(path string) (string, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "os" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - path := "./test.txt" - fileutil.CreateFile(path) - - f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) - f.WriteString("hello world") - - content, _ := fileutil.ReadFileToString(path) - fmt.Println(content) //hello world -} -``` - - - -### ReadFileByLine -Read file line by line, and return slice of lines
- -Signature: - -```go -func ReadFileByLine(path string)([]string, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "os" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - path := "./text.txt" - fileutil.CreateFile(path) - - f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) - defer f.Close() - f.WriteString("hello\nworld") - - contents, _ := fileutil.ReadFileByLine(path) - fmt.Println(contents) //[]string{"hello", "world"} -} -``` - - - -### Zip -Create a zip file of fpath, fpath could be a file or a directory.
- -Signature: - -```go -func Zip(fpath string, destPath string) error -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - err := fileutil.Zip("./test.txt", "./test.zip") - if err != nil { - fmt.Println(err) - } -} -``` - - - - -### UnZip -Unzip the file and save it to dest path.
- -Signature: - -```go -func UnZip(zipFile string, destPath string) error -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - err := fileutil.Zip("./test.zip", "./unzip/test.txt") - if err != nil { - fmt.Println(err) - } -} -``` - - - - - diff --git a/docs/fileutil_zh-CN.md b/docs/fileutil_zh-CN.md deleted file mode 100644 index d25ce566..00000000 --- a/docs/fileutil_zh-CN.md +++ /dev/null @@ -1,444 +0,0 @@ -# Fileutil -fileutil包支持文件基本操作。 - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go) - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/fileutil" -) -``` - - - -## 目录 -- [ClearFile](#ClearFile) -- [CreateFile](#CreateFile) -- [CopyFile](#CopyFile) -- [FileMode](#FileMode) -- [MiMeType](#MiMeType) -- [IsExist](#IsExist) -- [IsLink](#IsLink) -- [IsDir](#IsDir) - -- [ListFileNames](#ListFileNames) -- [RemoveFile](#RemoveFile) -- [ReadFileToString](#ReadFileToString) -- [ReadFileByLine](#ReadFileByLine) -- [Zip](#Zip) -- [UnZip](#UnZip) - - - -## 文档 - - - -### ClearFile -清空文件内容
- -函数签名: - -```go -func ClearFile(path string) error -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - err := fileutil.ClearFile("./test.txt") - if err != nil { - fmt.Println(err) - } -} -``` - -### CreateFile -创建文件,创建成功返回true, 否则返回false
- -函数签名: - -```go -func CreateFile(path string) bool -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - isCreatedSucceed := fileutil.CreateFile("./test.txt") - fmt.Println(isCreatedSucceed) -} -``` - - -### CopyFile -拷贝文件,会覆盖原有的拷贝文件
- -函数签名: - -```go -func CopyFile(srcFilePath string, dstFilePath string) error -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - err := fileutil.CopyFile("./test.txt", "./test_copy.txt") - if err != nil { - fmt.Println(err) - } -} -``` - - - -### FileMode -获取文件mode信息
- -函数签名: - -```go -func FileMode(path string) (fs.FileMode, error) -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - mode, err := fileutil.FileMode("./test.txt") - if err != nil { - fmt.Println(err) - } - fmt.Println(mode) -} -``` - - - -### MiMeType -获取文件mime类型, 'file'参数的类型必须是string或者*os.File
- -函数签名: - -```go -func MiMeType(file interface{}) string -``` -例子: - -```go -package main - -import ( - "fmt" - "os" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - type1 := fileutil.MiMeType("./test.txt") - fmt.Println(type1) //text/plain; charset=utf-8 - - f, _ := os.Open("./file.go") - type2 := fileutil.MiMeType(f) - fmt.Println(type2) //text/plain; charset=utf-8 -} -``` - - - - -### IsExist -判断文件或目录是否存在
- -函数签名: - -```go -func IsExist(path string) bool -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - fileutil.CreateFile("./test.txt") - isFileExist := fileutil.IsExist("./test.txt") - fmt.Println(isFileExist) //true -} -``` - - - -### IsLink -判断文件是否是符号链接
- -函数签名: - -```go -func IsLink(path string) bool -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - isLinkFile := fileutil.IsLink("./test.txt") - fmt.Println(isLinkFile) //false -} -``` - - - -### IsDir -判断目录是否存在
- -函数签名: - -```go -func IsDir(path string) bool -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - isDir := fileutil.IsDir("./") - fmt.Println(isDir) //true - - isDir = fileutil.IsDir("./test.txt") - fmt.Println(isDir) //false -} -``` - - - -### ListFileNames -返回目录下所有文件名
- -函数签名: - -```go -func ListFileNames(path string) ([]string, error) -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - fileNames, _ := fileutil.ListFileNames("./") - fmt.Println(fileNames) -} -``` - - - -### RemoveFile -删除文件
- -函数签名: - -```go -func RemoveFile(path string) error -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - err := fileutil.RemoveFile("./test.txt") - if err != nil { - fmt.Println(err) - } -} -``` - - -### ReadFileToString -读取文件内容并返回字符串
- -函数签名: - -```go -func ReadFileToString(path string) (string, error) -``` -例子: - -```go -package main - -import ( - "fmt" - "os" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - path := "./test.txt" - fileutil.CreateFile(path) - - f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) - f.WriteString("hello world") - - content, _ := fileutil.ReadFileToString(path) - fmt.Println(content) //hello world -} -``` - - - -### ReadFileByLine -按行读取文件内容,返回字符串切片包含每一行
- -函数签名: - -```go -func ReadFileByLine(path string)([]string, error) -``` -例子: - -```go -package main - -import ( - "fmt" - "os" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - path := "./text.txt" - fileutil.CreateFile(path) - - f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) - defer f.Close() - f.WriteString("hello\nworld") - - contents, _ := fileutil.ReadFileByLine(path) - fmt.Println(contents) //[]string{"hello", "world"} -} -``` - - - -### Zip -zip压缩文件, fpath参数可以是文件或目录
- -函数签名: - -```go -func Zip(fpath string, destPath string) error -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - err := fileutil.Zip("./test.txt", "./test.zip") - if err != nil { - fmt.Println(err) - } -} -``` - - - - -### UnZip -zip解压缩文件并保存在目录中
- -Signature: - -```go -func UnZip(zipFile string, destPath string) error -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/fileutil" -) - -func main() { - err := fileutil.Zip("./test.zip", "./unzip/test.txt") - if err != nil { - fmt.Println(err) - } -} -``` - - - - - diff --git a/docs/formatter.md b/docs/formatter.md deleted file mode 100644 index c07e9408..00000000 --- a/docs/formatter.md +++ /dev/null @@ -1,53 +0,0 @@ -# Formatter -formatter contains some functions for data formatting. - - - -## Source: - -[https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go) - - - -## Usage: -```go -import ( - "github.com/duke-git/lancet/formatter" -) -``` - - - -## Index -- [Comma](#Comma) - - - -## Documentation - - - -### Comma -Add comma to number by every 3 numbers from right. ahead by symbol char. -Param should be number or numberic string.
- -Signature: - -```go -func Comma(v interface{}, symbol string) string -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/formatter" -) - -func main() { - fmt.Println(formatter.Comma("12345", "")) // "12,345" - fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67" -} -``` diff --git a/docs/formatter_zh-CN.md b/docs/formatter_zh-CN.md deleted file mode 100644 index 4b178ae7..00000000 --- a/docs/formatter_zh-CN.md +++ /dev/null @@ -1,52 +0,0 @@ -# Formatter -formatter格式化器包含一些数据格式化处理方法。 - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go) - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/formatter" -) -``` - - - -## 目录 -- [Comma](#Comma) - - - -## 文档 - - - -### Comma -用逗号每隔3位分割数字/字符串,签名添加符号。参数必须是数字或者可以转为数字的字符串
- -函数签名: - -```go -func Comma(v interface{}, symbol string) string -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/formatter" -) - -func main() { - fmt.Println(formatter.Comma("12345", "")) // "12,345" - fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67" -} -``` diff --git a/docs/function.md b/docs/function.md deleted file mode 100644 index 8ca3d9aa..00000000 --- a/docs/function.md +++ /dev/null @@ -1,364 +0,0 @@ -# Function -Package function can control the flow of function execution and support part of functional programming. - - - -## Source: - -[https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go) -[https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go) - - - -## Usage: -```go -import ( - "github.com/duke-git/lancet/function" -) -``` - - - -## Index -- [After](#After) -- [Before](#Before) -- [Curry](#Curry) -- [Compose](#Compose) -- [Debounced](#Debounced) -- [Delay](#Delay) -- [Watcher](#Watcher) - - - -## Documentation - - - -### After -Creates a function that invokes given func once it's called n or more times.
- -Signature: - -```go -func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - arr := []string{"a", "b"} - f := function.After(len(arr), func(i int) int { - fmt.Println("last print") - return i - }) - - type cb func(args ...interface{}) []reflect.Value - print := func(i int, s string, fn cb) { - fmt.Printf("arr[%d] is %s \n", i, s) - fn(i) - } - - fmt.Println("arr is", arr) - for i := 0; i < len(arr); i++ { - print(i, arr[i], f) - } - - //output: - // arr is [a b] - // arr[0] is a - // arr[1] is b - // last print -} -``` - - - -### Before - -creates a function that invokes func once it's called less than n times.
- -Signature: - -```go -func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" - "github.com/duke-git/lancet/internal" -) - -func main() { - assert := internal.NewAssert(t, "TestBefore") - - arr := []string{"a", "b", "c", "d", "e"} - f := function.Before(3, func(i int) int { - return i - }) - - var res []int64 - type cb func(args ...interface{}) []reflect.Value - appendStr := func(i int, s string, fn cb) { - v := fn(i) - res = append(res, v[0].Int()) - } - - for i := 0; i < len(arr); i++ { - appendStr(i, arr[i], f) - } - - expected := []int64{0, 1, 2, 2, 2} - assert.Equal(expected, res) -} -``` - - - -### Curry - -Make a curry function.
- -Signature: - -```go -type Fn func(...interface{}) interface{} -func (f Fn) Curry(i interface{}) func(...interface{}) interface{} -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - add := func(a, b int) int { - return a + b - } - var addCurry function.Fn = func(values ...interface{}) interface{} { - return add(values[0].(int), values[1].(int)) - } - add1 := addCurry.Curry(1) - result := add1(2) - fmt.Println(result) //3 -} -``` - - - -### Compose - -Compose the function list from right to left, then return the composed function.
- -Signature: - -```go -func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{} -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - add1 := func(v ...interface{}) interface{} { - return v[0].(int) + 1 - } - add2 := func(v ...interface{}) interface{} { - return v[0].(int) + 2 - } - - add3 := function.Compose(add1, add2) - result := add3(1) - - fmt.Println(result) //4 -} -``` - - - -### Debounced - -Creates a debounced function that delays invoking fn until after wait duration have elapsed since the last time the debounced function was invoked.
- -Signature: - -```go -func Debounced(fn func(), duration time.Duration) func() -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - count := 0 - add := func() { - count++ - } - - debouncedAdd := function.Debounced(add, 50*time.Microsecond) - function.debouncedAdd() - function.debouncedAdd() - function.debouncedAdd() - function.debouncedAdd() - - time.Sleep(100 * time.Millisecond) - fmt.Println(count) //1 - - function.debouncedAdd() - time.Sleep(100 * time.Millisecond) - fmt.Println(count) //2 -} -``` - - - -### Delay - -Invoke function after delayed time.
- -Signature: - -```go -func Delay(delay time.Duration, fn interface{}, args ...interface{}) -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - var print = func(s string) { - fmt.Println(count) //test delay - } - function.Delay(2*time.Second, print, "test delay") -} -``` - - - -### Schedule - -Invoke function every duration time, until close the returned bool chan.
- -Signature: - -```go -func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - var res []string - appendStr := func(s string) { - res = append(res, s) - } - - stop := function.Schedule(1*time.Second, appendStr, "*") - time.Sleep(5 * time.Second) - close(stop) - - fmt.Println(res) //[* * * * *] -} -``` - - - -### Watcher - -Watcher is used for record code excution time. can start/stop/reset the watch timer. get the elapsed time of function execution.
- -Signature: - -```go -type Watcher struct { - startTime int64 - stopTime int64 - excuting bool -} -func (w *Watcher) Start() //start the watcher -func (w *Watcher) Stop() //stop the watcher -func (w *Watcher) Reset() //reset the watcher -func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - w := &function.Watcher{} - w.Start() - - longRunningTask() - - fmt.Println(w.excuting) //true - - w.Stop() - - eapsedTime := w.GetElapsedTime().Milliseconds() - fmt.Println(eapsedTime) - - w.Reset() - - fmt.Println(w.excuting) //false - - fmt.Println(w.startTime) //0 - fmt.Println(w.stopTime) //0 -} - -func longRunningTask() { - var slice []int64 - for i := 0; i < 10000000; i++ { - slice = append(slice, int64(i)) - } -} - -``` - - - diff --git a/docs/function_zh-CN.md b/docs/function_zh-CN.md deleted file mode 100644 index 8fdfaaa1..00000000 --- a/docs/function_zh-CN.md +++ /dev/null @@ -1,364 +0,0 @@ -# Function -function函数包控制函数执行流程,包含部分函数式编程。 - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go) -[https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go) - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/function" -) -``` - - - -## 目录 -- [After](#After) -- [Before](#Before) -- [Curry](#Curry) -- [Compose](#Compose) -- [Debounced](#Debounced) -- [Delay](#Delay) -- [Watcher](#Watcher) - - - -## 文档 - - - -### After -创建一个函数,当他被调用n或更多次之后将马上触发fn
- -函数签名: - -```go -func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - arr := []string{"a", "b"} - f := function.After(len(arr), func(i int) int { - fmt.Println("last print") - return i - }) - - type cb func(args ...interface{}) []reflect.Value - print := func(i int, s string, fn cb) { - fmt.Printf("arr[%d] is %s \n", i, s) - fn(i) - } - - fmt.Println("arr is", arr) - for i := 0; i < len(arr); i++ { - print(i, arr[i], f) - } - - //output: - // arr is [a b] - // arr[0] is a - // arr[1] is b - // last print -} -``` - - - -### Before - -创建一个函数,调用次数不超过n次,之后再调用这个函数,将返回一次最后调用fn的结果
- -函数签名: - -```go -func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" - "github.com/duke-git/lancet/internal" -) - -func main() { - assert := internal.NewAssert(t, "TestBefore") - - arr := []string{"a", "b", "c", "d", "e"} - f := function.Before(3, func(i int) int { - return i - }) - - var res []int64 - type cb func(args ...interface{}) []reflect.Value - appendStr := func(i int, s string, fn cb) { - v := fn(i) - res = append(res, v[0].Int()) - } - - for i := 0; i < len(arr); i++ { - appendStr(i, arr[i], f) - } - - expected := []int64{0, 1, 2, 2, 2} - assert.Equal(expected, res) -} -``` - - - -### Curry - -创建一个柯里化的函数
- -函数签名: - -```go -type Fn func(...interface{}) interface{} -func (f Fn) Curry(i interface{}) func(...interface{}) interface{} -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - add := func(a, b int) int { - return a + b - } - var addCurry function.Fn = func(values ...interface{}) interface{} { - return add(values[0].(int), values[1].(int)) - } - add1 := addCurry.Curry(1) - result := add1(2) - fmt.Println(result) //3 -} -``` - - - -### Compose - -从右至左组合函数列表fnList, 返回组合后的函数
- -函数签名: - -```go -func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{} -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - add1 := func(v ...interface{}) interface{} { - return v[0].(int) + 1 - } - add2 := func(v ...interface{}) interface{} { - return v[0].(int) + 2 - } - - add3 := function.Compose(add1, add2) - result := add3(1) - - fmt.Println(result) //4 -} -``` - - - -### Debounced - -创建一个 debounced 函数,该函数延迟调用 fn 直到自上次调用 debounced 函数后等待持续时间过去。
- -函数签名: - -```go -func Debounced(fn func(), duration time.Duration) func() -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - count := 0 - add := func() { - count++ - } - - debouncedAdd := function.Debounced(add, 50*time.Microsecond) - function.debouncedAdd() - function.debouncedAdd() - function.debouncedAdd() - function.debouncedAdd() - - time.Sleep(100 * time.Millisecond) - fmt.Println(count) //1 - - function.debouncedAdd() - time.Sleep(100 * time.Millisecond) - fmt.Println(count) //2 -} -``` - - - -### Delay - -延迟delay时间后调用函数
- -函数签名: - -```go -func Delay(delay time.Duration, fn interface{}, args ...interface{}) -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - var print = func(s string) { - fmt.Println(count) //test delay - } - function.Delay(2*time.Second, print, "test delay") -} -``` - - - -### Schedule - -每次持续时间调用函数,直到关闭返回的 bool chan
- -函数签名: - -```go -func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - var res []string - appendStr := func(s string) { - res = append(res, s) - } - - stop := function.Schedule(1*time.Second, appendStr, "*") - time.Sleep(5 * time.Second) - close(stop) - - fmt.Println(res) //[* * * * *] -} -``` - - - -### Watcher - -Watcher 用于记录代码执行时间。可以启动/停止/重置手表定时器。获取函数执行的时间。
- -函数签名: - -```go -type Watcher struct { - startTime int64 - stopTime int64 - excuting bool -} -func (w *Watcher) Start() //start the watcher -func (w *Watcher) Stop() //stop the watcher -func (w *Watcher) Reset() //reset the watcher -func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/function" -) - -func main() { - w := &function.Watcher{} - w.Start() - - longRunningTask() - - fmt.Println(w.excuting) //true - - w.Stop() - - eapsedTime := w.GetElapsedTime().Milliseconds() - fmt.Println(eapsedTime) - - w.Reset() - - fmt.Println(w.excuting) //false - - fmt.Println(w.startTime) //0 - fmt.Println(w.stopTime) //0 -} - -func longRunningTask() { - var slice []int64 - for i := 0; i < 10000000; i++ { - slice = append(slice, int64(i)) - } -} - -``` - - - diff --git a/docs/guide/contribution_guide.md b/docs/guide/contribution_guide.md new file mode 100644 index 00000000..2921e215 --- /dev/null +++ b/docs/guide/contribution_guide.md @@ -0,0 +1,37 @@ +# Lancet 贡献指南 + +Hi! 首先感谢你使用 Lancet。 + +lancet(柳叶刀)是一个功能强大、全面、高效、可复用的go语言工具函数库。它消除了处理并发、网络、数学、切片、字符串等的麻烦,使 Go 开发变得更容易。 + +Lancet 的成长离不开大家的支持,如果你愿意为 Lancet 贡献代码或提供建议,请阅读以下内容。 + +## Issue 规范 + +- issue 仅用于提交 Bug 或 Feature 以及设计相关的内容,其它内容可能会被直接关闭。 + +- 在提交 issue 之前,请搜索相关内容是否已被提出。 + +- 请说明 Lancet 和 Go 的版本号,并提供操作系统信息。推荐使用 [Go Playground](https://go.dev/play/) 生成在线 demo,这能够更直观地重现问题。 + +## Pull Request 规范 + +- 请先 fork 一份到自己的项目下,不要直接在仓库下建分支。 + +- commit 信息要以 `type(scope): 描述信息` 的形式填写,例如 `fix(package): [scrollbar] fix xxx bug`。 + + 1. type: 必须是 chore, docs, feat, fix, refactor, release, test 其中的一个。 + + 2. scope: 必须是 package, file, internal 其中的一个。 + + 3. header: 描述信息不要超过 72 个字符。 + +- 提交 PR 前请 rebase,确保 commit 记录的整洁。 + +- 提交 PR 前请执行单元测试命令:go test -v ./...,确保所有单元测试任务通过。 + +- 确保 PR 是提交到 `rc` 分支,而不是其他分支。 + +- 如果是修复 bug,请在 PR 中给出描述信息。 + +- 如果PR是新功能,确保完成相关文档(/lancet/docs/api/packages/)。 \ No newline at end of file diff --git a/docs/guide/contributors.md b/docs/guide/contributors.md new file mode 100644 index 00000000..aabf17ee --- /dev/null +++ b/docs/guide/contributors.md @@ -0,0 +1,7 @@ +# 贡献者 + +感谢所有为lancet贡献过代码的人! + + +
+
+
+
Calculate x to the nth power.
- -Signature: - -```go -func Exponent(x, n int64) int64 -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.Exponent(10, 0)) //1 - fmt.Println(mathutil.Exponent(10, 1)) //10 - fmt.Println(mathutil.Exponent(10, 2)) //100 -} -``` - - - -### Fibonacci -Calculate the nth number of fibonacci sequence.
- -Signature: - -```go -func Fibonacci(first, second, n int) int -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1 - fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1 - fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2 - fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3 - fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5 -} -``` - - - -### Factorial -Calculate the factorial of x.
- -Signature: - -```go -func Factorial(x uint) uint -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.Factorial(0)) //1 - fmt.Println(mathutil.Factorial(1)) //1 - fmt.Println(mathutil.Factorial(2)) //2 - fmt.Println(mathutil.Factorial(3)) //6 -} -``` - - - -### Percent -calculate the percentage of val to total, retain n decimal places.
- -Signature: - -```go -func Percent(val, total float64, n int) float64 -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.Percent(1, 2, 2)) //1 - fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //33.33 -} -``` - - - -### RoundToFloat -Round float up to n decimal places.
- -Signature: - -```go -func RoundToFloat(x float64, n int) float64 -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.RoundToFloat(0, 0)) //0 - fmt.Println(mathutil.RoundToFloat(0, 1)) //0 - fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12 - fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13 - fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125 -} -``` - - - - -### RoundToString -Round float up to n decimal places. will return string.
- -Signature: - -```go -func RoundToString(x float64, n int) string -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.RoundToString(0, 0)) //"0" - fmt.Println(mathutil.RoundToString(0, 1)) //"0.0: - fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12" - fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13" - fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125" -} -``` - - - -### TruncRound -Round float off n decimal places.
- -Signature: - -```go -func TruncRound(x float64, n int) float64 -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.TruncRound(0, 0)) //0 - fmt.Println(mathutil.TruncRound(0, 1)) //0 - fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12 - fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12 - fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125 -} -``` - - - diff --git a/docs/mathutil_zh-CN.md b/docs/mathutil_zh-CN.md deleted file mode 100644 index a0ceb6a9..00000000 --- a/docs/mathutil_zh-CN.md +++ /dev/null @@ -1,234 +0,0 @@ -# Mathutil -mathutil包实现了一些数学计算的函数. - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go) - - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/mathutil" -) -``` - - - -## 目录 -- [Exponent](#Exponent) -- [Fibonacci](#Fibonacci) -- [Factorial](#Factorial) - -- [Percent](#Percent) -- [RoundToFloat](#RoundToFloat) -- [RoundToString](#RoundToString) -- [TruncRound](#TruncRound) - - - -## Documentation - - -### Exponent -指数计算(x的n次方)
- -函数签名: - -```go -func Exponent(x, n int64) int64 -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.Exponent(10, 0)) //1 - fmt.Println(mathutil.Exponent(10, 1)) //10 - fmt.Println(mathutil.Exponent(10, 2)) //100 -} -``` - - - -### Fibonacci -计算斐波那契数列的第n个数
- -函数签名: - -```go -func Fibonacci(first, second, n int) int -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1 - fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1 - fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2 - fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3 - fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5 -} -``` - - - -### Factorial -计算阶乘
- -函数签名: - -```go -func Factorial(x uint) uint -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.Factorial(0)) //1 - fmt.Println(mathutil.Factorial(1)) //1 - fmt.Println(mathutil.Factorial(2)) //2 - fmt.Println(mathutil.Factorial(3)) //6 -} -``` - - - -### Percent -计算百分比,保留n位小数
- -函数签名: - -```go -func Percent(val, total float64, n int) float64 -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.Percent(1, 2, 2)) //1 - fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //33.33 -} -``` - - - -### RoundToFloat -四舍五入,保留n位小数
- -函数签名: - -```go -func RoundToFloat(x float64, n int) float64 -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.RoundToFloat(0, 0)) //0 - fmt.Println(mathutil.RoundToFloat(0, 1)) //0 - fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12 - fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13 - fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125 -} -``` - - - - -### RoundToString -四舍五入,保留n位小数,返回字符串
- -函数签名: - -```go -func RoundToString(x float64, n int) string -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.RoundToString(0, 0)) //"0" - fmt.Println(mathutil.RoundToString(0, 1)) //"0.0: - fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12" - fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13" - fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125" -} -``` - - - -### TruncRound -截短n位小数(不进行四舍五入)
- -函数签名: - -```go -func TruncRound(x float64, n int) float64 -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/mathutil" -) - -func main() { - fmt.Println(mathutil.TruncRound(0, 0)) //0 - fmt.Println(mathutil.TruncRound(0, 1)) //0 - fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12 - fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12 - fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125 -} -``` - - - diff --git a/docs/netutil.md b/docs/netutil.md deleted file mode 100644 index ac8eb1ff..00000000 --- a/docs/netutil.md +++ /dev/null @@ -1,511 +0,0 @@ -# Netutil -Package netutil contains functions to get net information and send http request. - - - -## Source: - -[https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go) - -[https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go) - - - -## Usage: -```go -import ( - "github.com/duke-git/lancet/netutil" -) -``` - - - -## Index -- [ConvertMapToQueryString](#ConvertMapToQueryString) -- [GetInternalIp](#GetInternalIp) -- [GetIps](#GetIps) -- [GetMacAddrs](#GetMacAddrs) -- [GetPublicIpInfo](#GetPublicIpInfo) -- [IsPublicIP](#IsPublicIP) -- [HttpGet](#HttpGet) -- [HttpDelete](#HttpDelete) -- [HttpPost](#HttpPost) -- [HttpPut](#HttpPut) - -- [HttpPatch](#HttpPatch) -- [ParseHttpResponse](#ParseHttpResponse) - - - -## Documentation - - -### ConvertMapToQueryString -Convert map to url query string.
- -Signature: - -```go -func ConvertMapToQueryString(param map[string]interface{}) string -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/netutil" -) - -func main() { - var m = map[string]interface{}{ - "c": 3, - "a": 1, - "b": 2, - } - qs := netutil.ConvertMapToQueryString(m) - - fmt.Println(qs) //a=1&b=2&c=3 -} -``` - - - -### GetInternalIp -Get internal ip information.
- -Signature: - -```go -func GetInternalIp() string -``` -Example: - -```go -package main - -import ( - "fmt" - "net" - "github.com/duke-git/lancet/netutil" -) - -func main() { - internalIp := netutil.GetInternalIp() - ip := net.ParseIP(internalIp) - - fmt.Println(ip) //192.168.1.9 -} -``` - - - -### GetIps -Get all ipv4 list.
- -Signature: - -```go -func GetIps() []string -``` -Example: - -```go -package main - -import ( - "fmt" - "net" - "github.com/duke-git/lancet/netutil" -) - -func main() { - ips := netutil.GetIps() - fmt.Println(ips) //[192.168.1.9] -} -``` - - - -### GetMacAddrs -Get all mac addresses list.
- -Signature: - -```go -func GetMacAddrs() []string { -``` -Example: - -```go -package main - -import ( - "fmt" - "net" - "github.com/duke-git/lancet/netutil" -) - -func main() { - addrs := netutil.GetMacAddrs() - fmt.Println(addrs) -} -``` - - - -### GetPublicIpInfo -Get public ip information.
- -Signature: - -```go -func GetPublicIpInfo() (*PublicIpInfo, error) -type PublicIpInfo struct { - Status string `json:"status"` - Country string `json:"country"` - CountryCode string `json:"countryCode"` - Region string `json:"region"` - RegionName string `json:"regionName"` - City string `json:"city"` - Lat float64 `json:"lat"` - Lon float64 `json:"lon"` - Isp string `json:"isp"` - Org string `json:"org"` - As string `json:"as"` - Ip string `json:"query"` -} -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/netutil" -) - -func main() { - publicIpInfo, err := netutil.GetPublicIpInfo() - if err != nil { - fmt.Println(err) - } - - fmt.Println(publicIpInfo) -} -``` - - - -### IsPublicIP -Checks if a ip is public or not.
- -Signature: - -```go -func IsPublicIP(IP net.IP) bool -``` -Example: - -```go -package main - -import ( - "fmt" - "net" - "github.com/duke-git/lancet/netutil" -) - -func main() { - ip1 := net.ParseIP("192.168.0.1") - ip2 := net.ParseIP("36.112.24.10") - - fmt.Println(netutil.IsPublicIP(ip1)) //false - fmt.Println(netutil.IsPublicIP(ip2)) //true -} -``` - - - - -### HttpGet -Send http get request.
- -Signature: - -```go -// params[0] is header which type should be http.Header or map[string]string, -// params[1] is query param which type should be url.Values or map[string]interface{}, -// params[2] is post body which type should be []byte. -// params[3] is http client which type should be http.Client. -func HttpGet(url string, params ...interface{}) (*http.Response, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "io/ioutil" - "log" - "github.com/duke-git/lancet/netutil" -) - -func main() { - url := "https://jsonplaceholder.typicode.com/todos/1" - header := map[string]string{ - "Content-Type": "application/json", - } - - resp, err := netutil.HttpGet(url, header) - if err != nil { - log.Fatal(err) - } - - body, _ := ioutil.ReadAll(resp.Body) - fmt.Println(body) -} -``` - - - -### HttpPost -Send http post request.
- -Signature: - -```go -// params[0] is header which type should be http.Header or map[string]string, -// params[1] is query param which type should be url.Values or map[string]interface{}, -// params[2] is post body which type should be []byte. -// params[3] is http client which type should be http.Client. -func HttpPost(url string, params ...interface{}) (*http.Response, error) -``` -Example: - -```go -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "github.com/duke-git/lancet/netutil" -) - -func main() { - url := "https://jsonplaceholder.typicode.com/todos" - header := map[string]string{ - "Content-Type": "application/json", - } - type Todo struct { - UserId int `json:"userId"` - Title string `json:"title"` - } - todo := Todo{1, "TestAddToDo"} - bodyParams, _ := json.Marshal(todo) - - resp, err := netutil.HttpPost(url, header, nil, bodyParams) - if err != nil { - log.Fatal(err) - } - - body, _ := ioutil.ReadAll(resp.Body) - fmt.Println(body) -} -``` - - - -### HttpPut -Send http put request.
- -Signature: - -```go -// params[0] is header which type should be http.Header or map[string]string, -// params[1] is query param which type should be url.Values or map[string]interface{}, -// params[2] is post body which type should be []byte. -// params[3] is http client which type should be http.Client. -func HttpPut(url string, params ...interface{}) (*http.Response, error) -``` -Example: - -```go -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "github.com/duke-git/lancet/netutil" -) - -func main() { - url := "https://jsonplaceholder.typicode.com/todos/1" - header := map[string]string{ - "Content-Type": "application/json", - } - type Todo struct { - Id int `json:"id"` - UserId int `json:"userId"` - Title string `json:"title"` - } - todo := Todo{1, 1, "TestPutToDo"} - bodyParams, _ := json.Marshal(todo) - - resp, err := netutil.HttpPut(url, header, nil, bodyParams) - if err != nil { - log.Fatal(err) - } - - body, _ := ioutil.ReadAll(resp.Body) - fmt.Println(body) -} -``` - - - -### HttpDelete -Send http delete request.
- -Signature: - -```go -// params[0] is header which type should be http.Header or map[string]string, -// params[1] is query param which type should be url.Values or map[string]interface{}, -// params[2] is post body which type should be []byte. -// params[3] is http client which type should be http.Client. -func HttpDelete(url string, params ...interface{}) (*http.Response, error) -``` -Example: - -```go -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "github.com/duke-git/lancet/netutil" -) - -func main() { - url := "https://jsonplaceholder.typicode.com/todos/1" - resp, err := netutil.HttpDelete(url) - if err != nil { - log.Fatal(err) - } - - body, _ := ioutil.ReadAll(resp.Body) - fmt.Println(body) -} -``` - - - -### HttpPatch -Send http patch request.
- -Signature: - -```go -// params[0] is header which type should be http.Header or map[string]string, -// params[1] is query param which type should be url.Values or map[string]interface{}, -// params[2] is post body which type should be []byte. -// params[3] is http client which type should be http.Client. -func HttpPatch(url string, params ...interface{}) (*http.Response, error) -``` -Example: - -```go -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "github.com/duke-git/lancet/netutil" -) - -func main() { - url := "https://jsonplaceholder.typicode.com/todos/1" - header := map[string]string{ - "Content-Type": "application/json", - } - type Todo struct { - Id int `json:"id"` - UserId int `json:"userId"` - Title string `json:"title"` - } - todo := Todo{1, 1, "TestPatchToDo"} - bodyParams, _ := json.Marshal(todo) - - resp, err := netutil.HttpPatch(url, header, nil, bodyParams) - if err != nil { - log.Fatal(err) - } - - body, _ := ioutil.ReadAll(resp.Body) - fmt.Println(body) -} -``` - - - -### ParseHttpResponse -Decode http response to specified interface.
- -Signature: - -```go -func ParseHttpResponse(resp *http.Response, obj interface{}) error -``` -Example: - -```go -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "github.com/duke-git/lancet/netutil" -) - -func main() { - url := "https://jsonplaceholder.typicode.com/todos/1" - header := map[string]string{ - "Content-Type": "application/json", - } - - resp, err := netutil.HttpGet(url, header) - if err != nil { - log.Fatal(err) - } - - type Todo struct { - Id int `json:"id"` - UserId int `json:"userId"` - Title string `json:"title"` - Completed bool `json:"completed"` - } - - toDoResp := &Todo{} - err = netutil.ParseHttpResponse(resp, toDoResp) - if err != nil { - log.Fatal(err) - } - - fmt.Println(toDoResp) -} -``` - diff --git a/docs/netutil_zh-CN.md b/docs/netutil_zh-CN.md deleted file mode 100644 index 8cbe3f3e..00000000 --- a/docs/netutil_zh-CN.md +++ /dev/null @@ -1,510 +0,0 @@ -# Netutil -netutil网络包支持获取ip地址,发送http请求。 - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go) - -[https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go) - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/netutil" -) -``` - - - -## 目录 -- [ConvertMapToQueryString](#ConvertMapToQueryString) -- [GetInternalIp](#GetInternalIp) -- [GetIps](#GetIps) -- [GetMacAddrs](#GetMacAddrs) -- [GetPublicIpInfo](#GetPublicIpInfo) -- [IsPublicIP](#IsPublicIP) -- [HttpGet](#HttpGet) -- [HttpDelete](#HttpDelete) -- [HttpPost](#HttpPost) -- [HttpPut](#HttpPut) - -- [HttpPatch](#HttpPatch) -- [ParseHttpResponse](#ParseHttpResponse) - - - -## 文档 - - -### ConvertMapToQueryString -将map转换成http查询字符串.
- -函数签名: - -```go -func ConvertMapToQueryString(param map[string]interface{}) string -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/netutil" -) - -func main() { - var m = map[string]interface{}{ - "c": 3, - "a": 1, - "b": 2, - } - qs := netutil.ConvertMapToQueryString(m) - - fmt.Println(qs) //a=1&b=2&c=3 -} -``` - - - -### GetInternalIp -获取内部ip
- -函数签名: - -```go -func GetInternalIp() string -``` -例子: - -```go -package main - -import ( - "fmt" - "net" - "github.com/duke-git/lancet/netutil" -) - -func main() { - internalIp := netutil.GetInternalIp() - ip := net.ParseIP(internalIp) - - fmt.Println(ip) //192.168.1.9 -} -``` - - -### GetIps -获取ipv4地址列表
- -函数签名: - -```go -func GetIps() []string -``` -例子: - -```go -package main - -import ( - "fmt" - "net" - "github.com/duke-git/lancet/netutil" -) - -func main() { - ips := netutil.GetIps() - fmt.Println(ips) //[192.168.1.9] -} -``` - - - -### GetMacAddrs -获取mac地址列
- -函数签名: - -```go -func GetMacAddrs() []string { -``` -例子: - -```go -package main - -import ( - "fmt" - "net" - "github.com/duke-git/lancet/netutil" -) - -func main() { - addrs := netutil.GetMacAddrs() - fmt.Println(addrs) -} -``` - - - -### GetPublicIpInfo -获取公网ip信息
- -函数签名: - -```go -func GetPublicIpInfo() (*PublicIpInfo, error) -type PublicIpInfo struct { - Status string `json:"status"` - Country string `json:"country"` - CountryCode string `json:"countryCode"` - Region string `json:"region"` - RegionName string `json:"regionName"` - City string `json:"city"` - Lat float64 `json:"lat"` - Lon float64 `json:"lon"` - Isp string `json:"isp"` - Org string `json:"org"` - As string `json:"as"` - Ip string `json:"query"` -} -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/netutil" -) - -func main() { - publicIpInfo, err := netutil.GetPublicIpInfo() - if err != nil { - fmt.Println(err) - } - - fmt.Println(publicIpInfo) -} -``` - - - -### IsPublicIP -判断ip是否是公共ip
- -函数签名: - -```go -func IsPublicIP(IP net.IP) bool -``` -例子: - -```go -package main - -import ( - "fmt" - "net" - "github.com/duke-git/lancet/netutil" -) - -func main() { - ip1 := net.ParseIP("192.168.0.1") - ip2 := net.ParseIP("36.112.24.10") - - fmt.Println(netutil.IsPublicIP(ip1)) //false - fmt.Println(netutil.IsPublicIP(ip2)) //true -} -``` - - - - -### HttpGet -发送http get请求
- -函数签名: - -```go -// params[0] http请求header,类型必须是http.Header或者map[string]string -// params[1] http查询字符串,类型必须是url.Values或者map[string]interface{} -// params[2] post请求体,类型必须是[]byte -// params[3] http client,类型必须是http.Client -func HttpGet(url string, params ...interface{}) (*http.Response, error) -``` -例子: - -```go -package main - -import ( - "fmt" - "io/ioutil" - "log" - "github.com/duke-git/lancet/netutil" -) - -func main() { - url := "https://jsonplaceholder.typicode.com/todos/1" - header := map[string]string{ - "Content-Type": "application/json", - } - - resp, err := netutil.HttpGet(url, header) - if err != nil { - log.Fatal(err) - } - - body, _ := ioutil.ReadAll(resp.Body) - fmt.Println(body) -} -``` - - - -### HttpPost -发送http post请求
- -函数签名: - -```go -// params[0] http请求header,类型必须是http.Header或者map[string]string -// params[1] http查询字符串,类型必须是url.Values或者map[string]interface{} -// params[2] post请求体,类型必须是[]byte -// params[3] http client,类型必须是http.Client -func HttpPost(url string, params ...interface{}) (*http.Response, error) -``` -例子: - -```go -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "github.com/duke-git/lancet/netutil" -) - -func main() { - url := "https://jsonplaceholder.typicode.com/todos" - header := map[string]string{ - "Content-Type": "application/json", - } - type Todo struct { - UserId int `json:"userId"` - Title string `json:"title"` - } - todo := Todo{1, "TestAddToDo"} - bodyParams, _ := json.Marshal(todo) - - resp, err := netutil.HttpPost(url, header, nil, bodyParams) - if err != nil { - log.Fatal(err) - } - - body, _ := ioutil.ReadAll(resp.Body) - fmt.Println(body) -} -``` - - - -### HttpPut -发送http put请求
- -函数签名: - -```go -// params[0] http请求header,类型必须是http.Header或者map[string]string -// params[1] http查询字符串,类型必须是url.Values或者map[string]interface{} -// params[2] post请求体,类型必须是[]byte -// params[3] http client,类型必须是http.Client -func HttpPut(url string, params ...interface{}) (*http.Response, error) -``` -Example: - -```go -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "github.com/duke-git/lancet/netutil" -) - -func main() { - url := "https://jsonplaceholder.typicode.com/todos/1" - header := map[string]string{ - "Content-Type": "application/json", - } - type Todo struct { - Id int `json:"id"` - UserId int `json:"userId"` - Title string `json:"title"` - } - todo := Todo{1, 1, "TestPutToDo"} - bodyParams, _ := json.Marshal(todo) - - resp, err := netutil.HttpPut(url, header, nil, bodyParams) - if err != nil { - log.Fatal(err) - } - - body, _ := ioutil.ReadAll(resp.Body) - fmt.Println(body) -} -``` - - - -### HttpDelete -发送http delete请求
- -函数签名: - -```go -// params[0] http请求header,类型必须是http.Header或者map[string]string -// params[1] http查询字符串,类型必须是url.Values或者map[string]interface{} -// params[2] post请求体,类型必须是[]byte -// params[3] http client,类型必须是http.Client -func HttpDelete(url string, params ...interface{}) (*http.Response, error) -``` -例子: - -```go -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "github.com/duke-git/lancet/netutil" -) - -func main() { - url := "https://jsonplaceholder.typicode.com/todos/1" - resp, err := netutil.HttpDelete(url) - if err != nil { - log.Fatal(err) - } - - body, _ := ioutil.ReadAll(resp.Body) - fmt.Println(body) -} -``` - - - -### HttpPatch -发送http patch请求
- -函数签名: - -```go -// params[0] http请求header,类型必须是http.Header或者map[string]string -// params[1] http查询字符串,类型必须是url.Values或者map[string]interface{} -// params[2] post请求体,类型必须是[]byte -// params[3] http client,类型必须是http.Client -func HttpPatch(url string, params ...interface{}) (*http.Response, error) -``` -例子: - -```go -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "github.com/duke-git/lancet/netutil" -) - -func main() { - url := "https://jsonplaceholder.typicode.com/todos/1" - header := map[string]string{ - "Content-Type": "application/json", - } - type Todo struct { - Id int `json:"id"` - UserId int `json:"userId"` - Title string `json:"title"` - } - todo := Todo{1, 1, "TestPatchToDo"} - bodyParams, _ := json.Marshal(todo) - - resp, err := netutil.HttpPatch(url, header, nil, bodyParams) - if err != nil { - log.Fatal(err) - } - - body, _ := ioutil.ReadAll(resp.Body) - fmt.Println(body) -} -``` - - - -### ParseHttpResponse -将http请求响应解码成特定struct值
- -函数签名: - -```go -func ParseHttpResponse(resp *http.Response, obj interface{}) error -``` -例子: - -```go -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "github.com/duke-git/lancet/netutil" -) - -func main() { - url := "https://jsonplaceholder.typicode.com/todos/1" - header := map[string]string{ - "Content-Type": "application/json", - } - - resp, err := netutil.HttpGet(url, header) - if err != nil { - log.Fatal(err) - } - - type Todo struct { - Id int `json:"id"` - UserId int `json:"userId"` - Title string `json:"title"` - Completed bool `json:"completed"` - } - - toDoResp := &Todo{} - err = netutil.ParseHttpResponse(resp, toDoResp) - if err != nil { - log.Fatal(err) - } - - fmt.Println(toDoResp) -} -``` - diff --git a/docs/package-lock.json b/docs/package-lock.json new file mode 100644 index 00000000..541ab656 --- /dev/null +++ b/docs/package-lock.json @@ -0,0 +1,1628 @@ +{ + "name": "lancet-docs", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "lancet-docs", + "devDependencies": { + "vitepress": "^1.2.3" + } + }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.9.3", + "resolved": "https://registry.npmmirror.com/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", + "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", + "@algolia/autocomplete-shared": "1.9.3" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.9.3", + "resolved": "https://registry.npmmirror.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", + "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@algolia/autocomplete-preset-algolia": { + "version": "1.9.3", + "resolved": "https://registry.npmmirror.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", + "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.9.3", + "resolved": "https://registry.npmmirror.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", + "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "dev": true, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/cache-browser-local-storage": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.23.3.tgz", + "integrity": "sha512-vRHXYCpPlTDE7i6UOy2xE03zHF2C8MEFjPN2v7fRbqVpcOvAUQK81x3Kc21xyb5aSIpYCjWCZbYZuz8Glyzyyg==", + "dev": true, + "dependencies": { + "@algolia/cache-common": "4.23.3" + } + }, + "node_modules/@algolia/cache-common": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/cache-common/-/cache-common-4.23.3.tgz", + "integrity": "sha512-h9XcNI6lxYStaw32pHpB1TMm0RuxphF+Ik4o7tcQiodEdpKK+wKufY6QXtba7t3k8eseirEMVB83uFFF3Nu54A==", + "dev": true + }, + "node_modules/@algolia/cache-in-memory": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/cache-in-memory/-/cache-in-memory-4.23.3.tgz", + "integrity": "sha512-yvpbuUXg/+0rbcagxNT7un0eo3czx2Uf0y4eiR4z4SD7SiptwYTpbuS0IHxcLHG3lq22ukx1T6Kjtk/rT+mqNg==", + "dev": true, + "dependencies": { + "@algolia/cache-common": "4.23.3" + } + }, + "node_modules/@algolia/client-account": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/client-account/-/client-account-4.23.3.tgz", + "integrity": "sha512-hpa6S5d7iQmretHHF40QGq6hz0anWEHGlULcTIT9tbUssWUriN9AUXIFQ8Ei4w9azD0hc1rUok9/DeQQobhQMA==", + "dev": true, + "dependencies": { + "@algolia/client-common": "4.23.3", + "@algolia/client-search": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/client-analytics/-/client-analytics-4.23.3.tgz", + "integrity": "sha512-LBsEARGS9cj8VkTAVEZphjxTjMVCci+zIIiRhpFun9jGDUlS1XmhCW7CTrnaWeIuCQS/2iPyRqSy1nXPjcBLRA==", + "dev": true, + "dependencies": { + "@algolia/client-common": "4.23.3", + "@algolia/client-search": "4.23.3", + "@algolia/requester-common": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/@algolia/client-common": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/client-common/-/client-common-4.23.3.tgz", + "integrity": "sha512-l6EiPxdAlg8CYhroqS5ybfIczsGUIAC47slLPOMDeKSVXYG1n0qGiz4RjAHLw2aD0xzh2EXZ7aRguPfz7UKDKw==", + "dev": true, + "dependencies": { + "@algolia/requester-common": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/client-personalization/-/client-personalization-4.23.3.tgz", + "integrity": "sha512-3E3yF3Ocr1tB/xOZiuC3doHQBQ2zu2MPTYZ0d4lpfWads2WTKG7ZzmGnsHmm63RflvDeLK/UVx7j2b3QuwKQ2g==", + "dev": true, + "dependencies": { + "@algolia/client-common": "4.23.3", + "@algolia/requester-common": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/@algolia/client-search": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/client-search/-/client-search-4.23.3.tgz", + "integrity": "sha512-P4VAKFHqU0wx9O+q29Q8YVuaowaZ5EM77rxfmGnkHUJggh28useXQdopokgwMeYw2XUht49WX5RcTQ40rZIabw==", + "dev": true, + "dependencies": { + "@algolia/client-common": "4.23.3", + "@algolia/requester-common": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/@algolia/logger-common": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/logger-common/-/logger-common-4.23.3.tgz", + "integrity": "sha512-y9kBtmJwiZ9ZZ+1Ek66P0M68mHQzKRxkW5kAAXYN/rdzgDN0d2COsViEFufxJ0pb45K4FRcfC7+33YB4BLrZ+g==", + "dev": true + }, + "node_modules/@algolia/logger-console": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/logger-console/-/logger-console-4.23.3.tgz", + "integrity": "sha512-8xoiseoWDKuCVnWP8jHthgaeobDLolh00KJAdMe9XPrWPuf1by732jSpgy2BlsLTaT9m32pHI8CRfrOqQzHv3A==", + "dev": true, + "dependencies": { + "@algolia/logger-common": "4.23.3" + } + }, + "node_modules/@algolia/recommend": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/recommend/-/recommend-4.23.3.tgz", + "integrity": "sha512-9fK4nXZF0bFkdcLBRDexsnGzVmu4TSYZqxdpgBW2tEyfuSSY54D4qSRkLmNkrrz4YFvdh2GM1gA8vSsnZPR73w==", + "dev": true, + "dependencies": { + "@algolia/cache-browser-local-storage": "4.23.3", + "@algolia/cache-common": "4.23.3", + "@algolia/cache-in-memory": "4.23.3", + "@algolia/client-common": "4.23.3", + "@algolia/client-search": "4.23.3", + "@algolia/logger-common": "4.23.3", + "@algolia/logger-console": "4.23.3", + "@algolia/requester-browser-xhr": "4.23.3", + "@algolia/requester-common": "4.23.3", + "@algolia/requester-node-http": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.23.3.tgz", + "integrity": "sha512-jDWGIQ96BhXbmONAQsasIpTYWslyjkiGu0Quydjlowe+ciqySpiDUrJHERIRfELE5+wFc7hc1Q5hqjGoV7yghw==", + "dev": true, + "dependencies": { + "@algolia/requester-common": "4.23.3" + } + }, + "node_modules/@algolia/requester-common": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/requester-common/-/requester-common-4.23.3.tgz", + "integrity": "sha512-xloIdr/bedtYEGcXCiF2muajyvRhwop4cMZo+K2qzNht0CMzlRkm8YsDdj5IaBhshqfgmBb3rTg4sL4/PpvLYw==", + "dev": true + }, + "node_modules/@algolia/requester-node-http": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/requester-node-http/-/requester-node-http-4.23.3.tgz", + "integrity": "sha512-zgu++8Uj03IWDEJM3fuNl34s746JnZOWn1Uz5taV1dFyJhVM/kTNw9Ik7YJWiUNHJQXcaD8IXD1eCb0nq/aByA==", + "dev": true, + "dependencies": { + "@algolia/requester-common": "4.23.3" + } + }, + "node_modules/@algolia/transporter": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/@algolia/transporter/-/transporter-4.23.3.tgz", + "integrity": "sha512-Wjl5gttqnf/gQKJA+dafnD0Y6Yw97yvfY8R9h0dQltX1GXTgNs1zWgvtWW0tHl1EgMdhAyw189uWiZMnL3QebQ==", + "dev": true, + "dependencies": { + "@algolia/cache-common": "4.23.3", + "@algolia/logger-common": "4.23.3", + "@algolia/requester-common": "4.23.3" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@docsearch/css": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/@docsearch/css/-/css-3.6.0.tgz", + "integrity": "sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==", + "dev": true + }, + "node_modules/@docsearch/js": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/@docsearch/js/-/js-3.6.0.tgz", + "integrity": "sha512-QujhqINEElrkIfKwyyyTfbsfMAYCkylInLYMRqHy7PHc8xTBQCow73tlo/Kc7oIwBrCLf0P3YhjlOeV4v8hevQ==", + "dev": true, + "dependencies": { + "@docsearch/react": "3.6.0", + "preact": "^10.0.0" + } + }, + "node_modules/@docsearch/react": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/@docsearch/react/-/react-3.6.0.tgz", + "integrity": "sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-core": "1.9.3", + "@algolia/autocomplete-preset-algolia": "1.9.3", + "@docsearch/css": "3.6.0", + "algoliasearch": "^4.19.1" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 19.0.0", + "react": ">= 16.8.0 < 19.0.0", + "react-dom": ">= 16.8.0 < 19.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "1.6.3", + "resolved": "https://registry.npmmirror.com/@shikijs/core/-/core-1.6.3.tgz", + "integrity": "sha512-QnJKHFUW95GnlJLJGP6QLx4M69HM0KlXk+R2Y8lr/x4nAx1Yb/lsuxq4XwybuUjTxbJk+BT0g/kvn0bcsjGGHg==", + "dev": true + }, + "node_modules/@shikijs/transformers": { + "version": "1.6.3", + "resolved": "https://registry.npmmirror.com/@shikijs/transformers/-/transformers-1.6.3.tgz", + "integrity": "sha512-ptBuP/IIeqCzK3zZO/knFICZWs58uZWzbv7ND+bKOewe5NcCjZfSiMyzFwOyl23ewPJ1APjRBwLi6Asrodmmxw==", + "dev": true, + "dependencies": { + "shiki": "1.6.3" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "dev": true + }, + "node_modules/@types/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmmirror.com/@types/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-4NpsnpYl2Gt1ljyBGrKMxFYAYvpqbnnkgP/i/g+NLpjEUa3obn1XJCur9YbEXKDAkaXqsR1LbDnGEJ0MmKFxfg==", + "dev": true, + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "dev": true + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.20", + "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==", + "dev": true + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.0.5", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz", + "integrity": "sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==", + "dev": true, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.4.27", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.27.tgz", + "integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.24.4", + "@vue/shared": "3.4.27", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.4.27", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz", + "integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==", + "dev": true, + "dependencies": { + "@vue/compiler-core": "3.4.27", + "@vue/shared": "3.4.27" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.4.27", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz", + "integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.24.4", + "@vue/compiler-core": "3.4.27", + "@vue/compiler-dom": "3.4.27", + "@vue/compiler-ssr": "3.4.27", + "@vue/shared": "3.4.27", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.10", + "postcss": "^8.4.38", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.4.27", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz", + "integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.4.27", + "@vue/shared": "3.4.27" + } + }, + "node_modules/@vue/devtools-api": { + "version": "7.2.1", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-7.2.1.tgz", + "integrity": "sha512-6oNCtyFOrNdqm6GUkFujsCgFlpbsHLnZqq7edeM/+cxAbMyCWvsaCsIMUaz7AiluKLccCGEM8fhOsjaKgBvb7g==", + "dev": true, + "dependencies": { + "@vue/devtools-kit": "^7.2.1" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.2.1", + "resolved": "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-7.2.1.tgz", + "integrity": "sha512-Wak/fin1X0Q8LLIfCAHBrdaaB+R6IdpSXsDByPHbQ3BmkCP0/cIo/oEGp9i0U2+gEqD4L3V9RDjNf1S34DTzQQ==", + "dev": true, + "dependencies": { + "@vue/devtools-shared": "^7.2.1", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.2.1", + "resolved": "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-7.2.1.tgz", + "integrity": "sha512-PCJF4UknJmOal68+X9XHyVeQ+idv0LFujkTOIW30+GaMJqwFVN9LkQKX4gLqn61KkGMdJTzQ1bt7EJag3TI6AA==", + "dev": true, + "dependencies": { + "rfdc": "^1.3.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.4.27", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.27.tgz", + "integrity": "sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==", + "dev": true, + "dependencies": { + "@vue/shared": "3.4.27" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.4.27", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.27.tgz", + "integrity": "sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==", + "dev": true, + "dependencies": { + "@vue/reactivity": "3.4.27", + "@vue/shared": "3.4.27" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.4.27", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz", + "integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==", + "dev": true, + "dependencies": { + "@vue/runtime-core": "3.4.27", + "@vue/shared": "3.4.27", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.4.27", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.27.tgz", + "integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==", + "dev": true, + "dependencies": { + "@vue/compiler-ssr": "3.4.27", + "@vue/shared": "3.4.27" + }, + "peerDependencies": { + "vue": "3.4.27" + } + }, + "node_modules/@vue/shared": { + "version": "3.4.27", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.27.tgz", + "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==", + "dev": true + }, + "node_modules/@vueuse/core": { + "version": "10.10.0", + "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-10.10.0.tgz", + "integrity": "sha512-vexJ/YXYs2S42B783rI95lMt3GzEwkxzC8Hb0Ndpd8rD+p+Lk/Za4bd797Ym7yq4jXqdSyj3JLChunF/vyYjUw==", + "dev": true, + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "10.10.0", + "@vueuse/shared": "10.10.0", + "vue-demi": ">=0.14.7" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.8", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.8.tgz", + "integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==", + "dev": true, + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/integrations": { + "version": "10.10.0", + "resolved": "https://registry.npmmirror.com/@vueuse/integrations/-/integrations-10.10.0.tgz", + "integrity": "sha512-vHGeK7X6mkdkpcm1eE9t3Cpm21pNVfZRwrjwwbrEs9XftnSgszF4831G2rei8Dt9cIYJIfFV+iyx/29muimJPQ==", + "dev": true, + "dependencies": { + "@vueuse/core": "10.10.0", + "@vueuse/shared": "10.10.0", + "vue-demi": ">=0.14.7" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "async-validator": "*", + "axios": "*", + "change-case": "*", + "drauu": "*", + "focus-trap": "*", + "fuse.js": "*", + "idb-keyval": "*", + "jwt-decode": "*", + "nprogress": "*", + "qrcode": "*", + "sortablejs": "*", + "universal-cookie": "*" + }, + "peerDependenciesMeta": { + "async-validator": { + "optional": true + }, + "axios": { + "optional": true + }, + "change-case": { + "optional": true + }, + "drauu": { + "optional": true + }, + "focus-trap": { + "optional": true + }, + "fuse.js": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "jwt-decode": { + "optional": true + }, + "nprogress": { + "optional": true + }, + "qrcode": { + "optional": true + }, + "sortablejs": { + "optional": true + }, + "universal-cookie": { + "optional": true + } + } + }, + "node_modules/@vueuse/integrations/node_modules/vue-demi": { + "version": "0.14.8", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.8.tgz", + "integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==", + "dev": true, + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "10.10.0", + "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-10.10.0.tgz", + "integrity": "sha512-UNAo2sTCAW5ge6OErPEHb5z7NEAg3XcO9Cj7OK45aZXfLLH1QkexDcZD77HBi5zvEiLOm1An+p/4b5K3Worpug==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "10.10.0", + "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-10.10.0.tgz", + "integrity": "sha512-2aW33Ac0Uk0U+9yo3Ypg9s5KcR42cuehRWl7vnUHadQyFvCktseyxxEPBi1Eiq4D2yBGACOnqLZpx1eMc7g5Og==", + "dev": true, + "dependencies": { + "vue-demi": ">=0.14.7" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.8", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.8.tgz", + "integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==", + "dev": true, + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/algoliasearch": { + "version": "4.23.3", + "resolved": "https://registry.npmmirror.com/algoliasearch/-/algoliasearch-4.23.3.tgz", + "integrity": "sha512-Le/3YgNvjW9zxIQMRhUHuhiUjAlKY/zsdZpfq4dlLqg6mEm0nL6yk+7f2hDOtLpxsgE4jSzDmvHL7nXdBp5feg==", + "dev": true, + "dependencies": { + "@algolia/cache-browser-local-storage": "4.23.3", + "@algolia/cache-common": "4.23.3", + "@algolia/cache-in-memory": "4.23.3", + "@algolia/client-account": "4.23.3", + "@algolia/client-analytics": "4.23.3", + "@algolia/client-common": "4.23.3", + "@algolia/client-personalization": "4.23.3", + "@algolia/client-search": "4.23.3", + "@algolia/logger-common": "4.23.3", + "@algolia/logger-console": "4.23.3", + "@algolia/recommend": "4.23.3", + "@algolia/requester-browser-xhr": "4.23.3", + "@algolia/requester-common": "4.23.3", + "@algolia/requester-node-http": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/focus-trap": { + "version": "7.5.4", + "resolved": "https://registry.npmmirror.com/focus-trap/-/focus-trap-7.5.4.tgz", + "integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==", + "dev": true, + "dependencies": { + "tabbable": "^6.2.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "dev": true + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", + "dev": true + }, + "node_modules/minisearch": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/minisearch/-/minisearch-6.3.0.tgz", + "integrity": "sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==", + "dev": true + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/preact": { + "version": "10.22.0", + "resolved": "https://registry.npmmirror.com/preact/-/preact-10.22.0.tgz", + "integrity": "sha512-RRurnSjJPj4rp5K6XoP45Ui33ncb7e4H7WiOHVpjbkvqvA3U+N8Z6Qbo0AE6leGYBV66n8EhEaFixvIu3SkxFw==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/rfdc": { + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "dev": true + }, + "node_modules/rollup": { + "version": "4.18.0", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/search-insights": { + "version": "2.14.0", + "resolved": "https://registry.npmmirror.com/search-insights/-/search-insights-2.14.0.tgz", + "integrity": "sha512-OLN6MsPMCghDOqlCtsIsYgtsC0pnwVTyT9Mu6A3ewOj1DxvzZF6COrn2g86E/c05xbktB0XN04m/t1Z+n+fTGw==", + "dev": true, + "peer": true + }, + "node_modules/shiki": { + "version": "1.6.3", + "resolved": "https://registry.npmmirror.com/shiki/-/shiki-1.6.3.tgz", + "integrity": "sha512-lE1/YGlzFY0hQSyEfsZj18xGrTWxyhFQkaiILALqTBZPbJeYFWpbUhlmTGPOupYB/qC+H6sV4UznJzcEh3WMHQ==", + "dev": true, + "dependencies": { + "@shikijs/core": "1.6.3" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmmirror.com/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmmirror.com/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "dev": true + }, + "node_modules/vite": { + "version": "5.2.13", + "resolved": "https://registry.npmmirror.com/vite/-/vite-5.2.13.tgz", + "integrity": "sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==", + "dev": true, + "dependencies": { + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitepress": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/vitepress/-/vitepress-1.2.3.tgz", + "integrity": "sha512-GvEsrEeNLiDE1+fuwDAYJCYLNZDAna+EtnXlPajhv/MYeTjbNK6Bvyg6NoTdO1sbwuQJ0vuJR99bOlH53bo6lg==", + "dev": true, + "dependencies": { + "@docsearch/css": "^3.6.0", + "@docsearch/js": "^3.6.0", + "@shikijs/core": "^1.6.2", + "@shikijs/transformers": "^1.6.2", + "@types/markdown-it": "^14.1.1", + "@vitejs/plugin-vue": "^5.0.5", + "@vue/devtools-api": "^7.2.1", + "@vue/shared": "^3.4.27", + "@vueuse/core": "^10.10.0", + "@vueuse/integrations": "^10.10.0", + "focus-trap": "^7.5.4", + "mark.js": "8.11.1", + "minisearch": "^6.3.0", + "shiki": "^1.6.2", + "vite": "^5.2.12", + "vue": "^3.4.27" + }, + "bin": { + "vitepress": "bin/vitepress.js" + }, + "peerDependencies": { + "markdown-it-mathjax3": "^4", + "postcss": "^8" + }, + "peerDependenciesMeta": { + "markdown-it-mathjax3": { + "optional": true + }, + "postcss": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.4.27", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.27.tgz", + "integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.4.27", + "@vue/compiler-sfc": "3.4.27", + "@vue/runtime-dom": "3.4.27", + "@vue/server-renderer": "3.4.27", + "@vue/shared": "3.4.27" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + } + } +} diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 00000000..78cddb59 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,13 @@ +{ + "name": "lancet-docs", + "private": true, + "type": "module", + "scripts": { + "docs:dev": "vitepress dev", + "docs:build": "vitepress build --max_old_space_size=8192", + "docs:preview": "vitepress preview" + }, + "devDependencies": { + "vitepress": "^1.2.3" + } +} diff --git a/docs/public/lancet_logo.png b/docs/public/lancet_logo.png new file mode 100644 index 00000000..481f8906 Binary files /dev/null and b/docs/public/lancet_logo.png differ diff --git a/docs/public/lancet_logo_mini.png b/docs/public/lancet_logo_mini.png new file mode 100644 index 00000000..9c20d1d2 Binary files /dev/null and b/docs/public/lancet_logo_mini.png differ diff --git a/docs/public/sponsor_btn.png b/docs/public/sponsor_btn.png new file mode 100644 index 00000000..19d36f30 Binary files /dev/null and b/docs/public/sponsor_btn.png differ diff --git a/docs/public/wechat_pay.png b/docs/public/wechat_pay.png new file mode 100644 index 00000000..18ba504e Binary files /dev/null and b/docs/public/wechat_pay.png differ diff --git a/docs/random.md b/docs/random.md deleted file mode 100644 index 4cf260c4..00000000 --- a/docs/random.md +++ /dev/null @@ -1,138 +0,0 @@ -# Random -Package random implements some basic functions to generate random int and string. - - - -## Source: - -[https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go) - - - - -## Usage: -```go -import ( - "github.com/duke-git/lancet/random" -) -``` - - - -## Index -- [RandBytes](#RandBytes) -- [RandInt](#RandInt) -- [RandString](#RandString) -- [UUIdV4](#UUIdV4) - - - -## Documentation - - -### RandBytes -Generate random byte slice.
- -Signature: - -```go -func RandBytes(length int) []byte -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/random" -) - -func main() { - randBytes := random.RandBytes(4) - fmt.Println(randBytes) -} -``` - - -### RandInt -Generate random int between min and max, may contain min, not max.
- -Signature: - -```go -func RandInt(min, max int) int -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/random" -) - -func main() { - rInt := random.RandInt(1, 10) - fmt.Println(rInt) -} -``` - - - -### RandInt -Generate random given length string.
- -Signature: - -```go -func RandString(length int) string -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/random" -) - -func main() { - randStr := random.RandString(6) - fmt.Println(randStr) -} -``` - - - - -### UUIdV4 -Generate a random UUID of version 4 according to RFC 4122.
- -Signature: - -```go -func UUIdV4() (string, error) -``` -Example: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/random" -) - -func main() { - uuid, err := random.UUIdV4() - if err != nil { - return - } - fmt.Println(uuid) -} -``` - - diff --git a/docs/random_zh-CN.md b/docs/random_zh-CN.md deleted file mode 100644 index e3ff93ea..00000000 --- a/docs/random_zh-CN.md +++ /dev/null @@ -1,138 +0,0 @@ -# Random -random随机数生成器包,可以生成随机[]bytes, int, string。 - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go) - - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/random" -) -``` - - - -## 目录 -- [RandBytes](#RandBytes) -- [RandInt](#RandInt) -- [RandString](#RandString) -- [UUIdV4](#UUIdV4) - - - - -## 文档 - - -### RandBytes -生成随机字节切片
- -函数签名: - -```go -func RandBytes(length int) []byte -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/random" -) - -func main() { - randBytes := random.RandBytes(4) - fmt.Println(randBytes) -} -``` - - -### RandInt -生成随机int, 范围[min, max)
- -函数签名: - -```go -func RandInt(min, max int) int -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/random" -) - -func main() { - rInt := random.RandInt(1, 10) - fmt.Println(rInt) -} -``` - - - -### RandInt -生成随机给定长度的随机字符串
- -函数签名: - -```go -func RandString(length int) string -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/random" -) - -func main() { - randStr := random.RandString(6) - fmt.Println(randStr) -} -``` - - - -### UUIdV4 -生成UUID v4字符串
- -函数签名: - -```go -func UUIdV4() (string, error) -``` -例子: - -```go -package main - -import ( - "fmt" - "github.com/duke-git/lancet/random" -) - -func main() { - uuid, err := random.UUIdV4() - if err != nil { - return - } - fmt.Println(uuid) -} -``` - - diff --git a/docs/retry.md b/docs/retry.md deleted file mode 100644 index abfd8581..00000000 --- a/docs/retry.md +++ /dev/null @@ -1,236 +0,0 @@ -# Retry -Package retry is for executing a function repeatedly until it was successful or canceled by the context. - - - -## Source: - -[https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go) - - - - -## Usage: -```go -import ( - "github.com/duke-git/lancet/retry" -) -``` - - - -## Index -- [Context](#Context) -- [Retry](#Retry) -- [RetryFunc](#RetryFunc) -- [RetryDuration](#RetryDuration) -- [RetryTimes](#RetryTimes) - - - -## Documentation - - -### Context -Set retry context config, can cancel the retry with context.
- -Signature: - -```go -func Context(ctx context.Context) -``` -Example: - -```go -import ( - "context" - "errors" - "fmt" - "github.com/duke-git/lancet/retry" - "time" -) - -func main() { - ctx, cancel := context.WithCancel(context.TODO()) - var number int - increaseNumber := func() error { - number++ - if number > 3 { - cancel() - } - return errors.New("error occurs") - } - - err := retry.Retry(increaseNumber, - retry.RetryDuration(time.Microsecond*50), - retry.Context(ctx), - ) - - if err != nil { - fmt.Println(err) //retry is cancelled - } -} -``` - - - - -### RetryFunc -Function that retry executes.
- -Signature: - -```go -type RetryFunc func() error -``` -Example: - -```go -package main - -import ( - "fmt" - "errors" - "log" - "github.com/duke-git/lancet/retry" -) - -func main() { - var number int - var increaseNumber retry.RetryFunc - increaseNumber = func() error { - number++ - if number == 3 { - return nil - } - return errors.New("error occurs") - } - - err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50)) - if err != nil { - log.Fatal(err) - } - - fmt.Println(number) //3 -} -``` - - - -### RetryTimes -Set times of retry. Default times is 5.
- -Signature: - -```go -func RetryTimes(n uint) -``` -Example: - -```go -package main - -import ( - "fmt" - "errors" - "log" - "github.com/duke-git/lancet/retry" -) - -func main() { - var number int - increaseNumber := func() error { - number++ - if number == 3 { - return nil - } - return errors.New("error occurs") - } - - err := retry.Retry(increaseNumber, retry.RetryTimes(2)) - if err != nil { - log.Fatal(err) //2022/02/01 18:42:25 function main.main.func1 run failed after 2 times retry exit status 1 - } -} -``` - - - -### RetryDuration -Set duration of retries. Default duration is 3 second.
- -Signature: - -```go -func RetryDuration(d time.Duration) -``` -Example: - -```go -package main - -import ( - "fmt" - "errors" - "log" - "github.com/duke-git/lancet/retry" -) - -func main() { - var number int - increaseNumber := func() error { - number++ - if number == 3 { - return nil - } - return errors.New("error occurs") - } - - err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50)) - if err != nil { - log.Fatal(err) - } - - fmt.Println(number) //3 -} -``` - - -### Retry -Executes the retryFunc repeatedly until it was successful or canceled by the context.
- -Signature: - -```go -func Retry(retryFunc RetryFunc, opts ...Option) error -``` -Example: - -```go -package main - -import ( - "fmt" - "errors" - "log" - "github.com/duke-git/lancet/retry" -) - -func main() { - var number int - increaseNumber := func() error { - number++ - if number == 3 { - return nil - } - return errors.New("error occurs") - } - - err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50)) - if err != nil { - log.Fatal(err) - } - - fmt.Println(number) //3 -} -``` diff --git a/docs/retry_zh-CN.md b/docs/retry_zh-CN.md deleted file mode 100644 index 23f136ea..00000000 --- a/docs/retry_zh-CN.md +++ /dev/null @@ -1,238 +0,0 @@ -# Retry -retry重试执行函数直到函数运行成功或被context cancel。 - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go) - - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/retry" -) -``` - - - -## 目录 -- [Context](#Context) -- [Retry](#Retry) -- [RetryFunc](#RetryFunc) -- [RetryDuration](#RetryDuration) -- [RetryTimes](#RetryTimes) - - - - - -## Document文档 - - -### Context -设置重试context参数
- -函数签名: - -```go -func Context(ctx context.Context) -``` -例子: - -```go -import ( - "context" - "errors" - "fmt" - "lancet-demo/retry" - "time" -) - -func main() { - ctx, cancel := context.WithCancel(context.TODO()) - var number int - increaseNumber := func() error { - number++ - if number > 3 { - cancel() - } - return errors.New("error occurs") - } - - err := retry.Retry(increaseNumber, - retry.RetryDuration(time.Microsecond*50), - retry.Context(ctx), - ) - - if err != nil { - fmt.Println(err) //retry is cancelled - } -} -``` - - - - -### RetryFunc -被重试执行的函数
- -函数签名: - -```go -type RetryFunc func() error -``` -例子: - -```go -package main - -import ( - "fmt" - "errors" - "log" - "github.com/duke-git/lancet/retry" -) - -func main() { - var number int - var increaseNumber retry.RetryFunc - increaseNumber = func() error { - number++ - if number == 3 { - return nil - } - return errors.New("error occurs") - } - - err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50)) - if err != nil { - log.Fatal(err) - } - - fmt.Println(number) //3 -} -``` - - - -### RetryTimes -设置重试次数,默认5
- -函数签名: - -```go -func RetryTimes(n uint) -``` -例子: - -```go -package main - -import ( - "fmt" - "errors" - "log" - "github.com/duke-git/lancet/retry" -) - -func main() { - var number int - increaseNumber := func() error { - number++ - if number == 3 { - return nil - } - return errors.New("error occurs") - } - - err := retry.Retry(increaseNumber, retry.RetryTimes(2)) - if err != nil { - log.Fatal(err) //2022/02/01 18:42:25 function main.main.func1 run failed after 2 times retry exit status 1 - } -} -``` - - - -### RetryDuration -设置重试间隔时间,默认3秒
- -函数签名: - -```go -func RetryDuration(d time.Duration) -``` -例子: - -```go -package main - -import ( - "fmt" - "errors" - "log" - "github.com/duke-git/lancet/retry" -) - -func main() { - var number int - increaseNumber := func() error { - number++ - if number == 3 { - return nil - } - return errors.New("error occurs") - } - - err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50)) - if err != nil { - log.Fatal(err) - } - - fmt.Println(number) //3 -} -``` - - -### Retry -重试执行函数retryFunc,直到函数运行成功,或被context停止
- -函数签名: - -```go -func Retry(retryFunc RetryFunc, opts ...Option) error -``` -例子: - -```go -package main - -import ( - "fmt" - "errors" - "log" - "github.com/duke-git/lancet/retry" -) - -func main() { - var number int - increaseNumber := func() error { - number++ - if number == 3 { - return nil - } - return errors.New("error occurs") - } - - err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50)) - if err != nil { - log.Fatal(err) - } - - fmt.Println(number) //3 -} -``` diff --git a/docs/slice.md b/docs/slice.md deleted file mode 100644 index 27cac1a2..00000000 --- a/docs/slice.md +++ /dev/null @@ -1,968 +0,0 @@ -# Slice -Package slice implements some functions to manipulate slice. - - - -## Source: - -[https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go) - - - - -## Usage: -```go -import ( - "github.com/duke-git/lancet/slice" -) -``` - - - -## Index -- [Contain](#Contain) -- [ContainSubSlice](#ContainSubSlice) -- [Chunk](#Chunk) -- [Compact](#Compact) -- [Concat](#Concat) -- [Count](#Count) -- [Difference](#Difference) -- [DifferenceBy](#DifferenceBy) -- [DeleteByIndex](#DeleteByIndex) -- [Drop](#Drop) -- [Every](#Every) -- [Filter](#Filter) -- [Find](#Find) -- [FindLast](#FindLast) -- [FlattenDeep](#FlattenDeep) -- [ForEach](#ForEach) - -- [GroupBy](#GroupBy) -- [IntSlice](#IntSlice) -- [InterfaceSlice](#InterfaceSlice) -- [Intersection](#Intersection) -- [InsertByIndex](#InsertByIndex) -- [Map](#Map) -- [ReverseSlice](#ReverseSlice) -- [Reduce](#Reduce) -- [Shuffle](#Shuffle) -- [SortByField](#SortByField) -- [Some](#Some) -- [StringSlice](#StringSlice) -- [Unique](#Unique) -- [Union](#Union) -- [UpdateByIndex](#UpdateByIndex) -- [Without](#Without) - - - -## Documentation - -## Note: -1. param which type is interface{} in below functions should be slice. - -### Contain -Check if the value is in the slice or not. iterableType param can be string, map or slice.
- -Signature: - -```go -func Contain(iterableType interface{}, value interface{}) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res := slice.Contain([]string{"a", "b", "c"}, "a") - fmt.Println(res) //true -} -``` - - -### ContainSubSlice -Check if the slice contain subslice or not.
- -Signature: - -```go -func ContainSubSlice(slice interface{}, subslice interface{}) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res := slice.ContainSubSlice([]string{"a", "b", "c"}, []string{"a", "b"}) - fmt.Println(res) //true -} -``` - - - - -### Chunk -Creates an slice of elements split into groups the length of `size`.
- -Signature: - -```go -func Chunk(slice []interface{}, size int) [][]interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - arr := []string{"a", "b", "c", "d", "e"} - res := slice.Chunk(InterfaceSlice(arr), 3) - fmt.Println(res) //[][]interface{}{{"a", "b", "c"}, {"d", "e"}} -} -``` - - - -### Compact -Creates an slice with all falsey values removed. The values false, nil, 0, and "" are falsey.
- -Signature: - -```go -func Compact(slice interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res := slice.Compact([]int{0, 1, 2, 3}) - fmt.Println(res) //[]int{1, 2, 3} -} -``` - - -### Concat -Creates a new slice concatenating slice with any additional slices and/or values.
- -Signature: - -```go -func Concat(slice interface{}, values ...interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res1 := slice.Concat([]int{1, 2, 3}, 4, 5) - fmt.Println(res1) //[]int{1, 2, 3, 4, 5} - - res2 := slice.Concat([]int{1, 2, 3}, []int{4, 5}) - fmt.Println(res2) //[]int{1, 2, 3, 4, 5} -} -``` - - - -### Count -Count iterates over elements of slice, returns a count of all matched elements. The function signature should be func(index int, value interface{}) bool.
- -Signature: - -```go -func Count(slice, function interface{}) int -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 4, 5, 6} - evenFunc := func(i, num int) bool { - return (num % 2) == 0 - } - - res := slice.Count(nums, evenFunc) - fmt.Println(res) //3 -} -``` - - - - -### Difference -Creates an slice of whose element not included in the other given slice.
- -Signature: - -```go -func Difference(slice1, slice2 interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - s1 := []int{1, 2, 3, 4, 5} - s2 := []int{4, 5, 6} - - res := slice.Difference(s1, s2) - fmt.Println(res) //[]int{1, 2, 3} -} -``` - - - - -### DifferenceBy -DifferenceBy accepts iteratee func which is invoked for each element of slice and values to generate the criterion by which they're compared.
- -Signature: - -```go -func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - s1 := []int{1, 2, 3, 4, 5} - s2 := []int{4, 5, 6} - addOne := func(i int, v int) int { - return v + 1 - } - - res := slice.DifferenceBy(s1, s2, addOne) - fmt.Println(res) //[]int{1, 2} -} -``` - - - - -### DeleteByIndex -Delete the element of slice from start index to end index - 1.
- -Signature: - -```go -func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error) -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res1 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 3) - fmt.Println(res1) //[]string{"a", "b", "c", "e"} - - res2 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 0, 2) - fmt.Println(res2) //[]string{"c", "d", "e"} - -} -``` - - - - -### Drop -Creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0.
- -Signature: - -```go -func Drop(slice interface{}, n int) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res1 := slice.Drop([]int{}, 0) - fmt.Println(res1) //[]int{} - - res2 := slice.Drop([]int{1, 2, 3, 4, 5}, 1) - fmt.Println(res2) //[]int{2, 3, 4, 5} - - res3 := slice.Drop([]int{1, 2, 3, 4, 5}, -1) - fmt.Println(res3) //[]int{1, 2, 3, 4} -} -``` - - - - -### Every -Return true if all of the values in the slice pass the predicate function. The function signature should be func(index int, value interface{}) bool.
- -Signature: - -```go -func Every(slice, function interface{}) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 5} - isEven := func(i, num int) bool { - return num%2 == 0 - } - - res := slice.Every(nums, isEven) - fmt.Println(res) //false -} -``` - - - - -### Filter -Return all elements which match the function. Function signature should be func(index int, value interface{}) bool.
- -Signature: - -```go -func Filter(slice, function interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 5} - isEven := func(i, num int) bool { - return num%2 == 0 - } - - res := slice.Filter(nums, isEven) - fmt.Println(res) //[]int{2, 4} -} -``` - - - -### Find -Iterates over elements of slice, returning the first one that passes a truth test on function.function signature should be func(index int, value interface{}) bool.
- -Signature: - -```go -func Find(slice, function interface{}) (interface{}, bool) -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 5} - isEven := func(i, num int) bool { - return num%2 == 0 - } - - res, ok := slice.Find(nums, even) - fmt.Println(res) //2 - fmt.Println(ok) //true -} -``` - - - - -### FindLast -iterates over elements of slice from end to begin, returning the last one that passes a truth test on function. The function signature should be func(index int, value interface{}) bool.
- -Signature: - -```go -func FindLast(slice, function interface{}) (interface{}, bool) -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 5} - isEven := func(i, num int) bool { - return num%2 == 0 - } - - res, ok := slice.FindLast(nums, even) - fmt.Println(res) //4 - fmt.Println(ok) //true -} -``` - - - -### FlattenDeep -flattens slice recursive.
- -Signature: - -```go -func FlattenDeep(slice interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - arr := [][][]string{{{"a", "b"}}, {{"c", "d"}}} - res := slice.FlattenDeep(arr) - fmt.Println(res) //[]string{"a", "b", "c", "d"} -} -``` - - - - - -### ForEach -Iterates over elements of slice and invokes function for each element, function signature should be func(index int, value interface{}).
- -Signature: - -```go -func ForEach(slice, function interface{}) -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - numbers := []int{1, 2, 3, 4, 5} - var numbersAddTwo []int - slice.ForEach(numbers, func(index int, value int) { - numbersAddTwo = append(numbersAddTwo, value+2) - }) - fmt.Println(numbersAddTwo) //[]int{3, 4, 5, 6, 7} -} -``` - - - - -### GroupBy -Iterates over elements of the slice, each element will be group by criteria, returns two slices. The function signature should be func(index int, value interface{}) bool.
- -Signature: - -```go -func GroupBy(slice, function interface{}) (interface{}, interface{}) -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 4, 5, 6} - evenFunc := func(i, num int) bool { - return (num % 2) == 0 - } - even, odd := slice.GroupBy(nums, evenFunc) - - fmt.Println(even) //[]int{2, 4, 6} - fmt.Println(odd) //]int{1, 3, 5} -} -``` - - - - -### IntSlice -Convert interface slice to int slice.
- -Signature: - -```go -func IntSlice(slice interface{}) []int -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - var nums = []interface{}{1, 2, 3} - res := slice.IntSlice(nums) - fmt.Println(res) //[]int{1, 2, 3} -} -``` - - - - -### InterfaceSlice -Convert value to interface slice.
- -Signature: - -```go -func InterfaceSlice(slice interface{}) []interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - var nums = []int{}{1, 2, 3} - res := slice.InterfaceSlice(nums) - fmt.Println(res) //[]interface{}{1, 2, 3} -} -``` - - - - -### Intersection -Creates a slice of unique values that included by all slices.
- -Signature: - -```go -func Intersection(slices ...interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - s1 := []int{1, 2, 2, 3} - s2 := []int{1, 2, 3, 4} - res := slice.Intersection(s1, s2), - - fmt.Println(res) //[]int{1, 2, 3} -} -``` - - - - -### InsertByIndex -insert the element into slice at index.
- -Signature: - -```go -func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error) -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - s := []string{"a", "b", "c"} - - res1, _ := slice.InsertByIndex(s, 0, "1") - fmt.Println(res1) //[]string{"1", "a", "b", "c"} - - res2, _ := slice.InsertByIndex(s, 3, []string{"1", "2", "3"}) - fmt.Println(res2) //[]string{"a", "b", "c", "1", "2", "3"} -} -``` - - - - -### Map -Creates an slice of values by running each element in slice thru function, function signature should be func(index int, value interface{}) interface{}.
- -Signature: - -```go -func Map(slice, function interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 4} - multiplyTwo := func(i, num int) int { - return num * 2 - } - res := slice.Map(nums, multiplyTwo) - fmt.Println(res) //[]int{2, 4, 6, 8} -} -``` - - - - -### ReverseSlice -Reverse the elements order in slice.
- -Signature: - -```go -func ReverseSlice(slice interface{}) -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 4} - slice.ReverseSlice(nums) - fmt.Println(res) //[]int{4, 3, 2, 1} -} -``` - - - -### Reduce -Reduce slice, function signature should be func(index int, value1, value2 interface{}) interface{}.
- -Signature: - -```go -func Reduce(slice, function, zero interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 4} - reduceFunc := func(i, v1, v2 int) int { - return v1 + v2 - } - res := slice.Reduce(nums, reduceFunc, 0) - fmt.Println(res) //10 -} -``` - - - - -### Shuffle -Creates an slice of shuffled values.
- -Signature: - -```go -func Shuffle(slice interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 4, 5} - res := slice.Shuffle(nums) - fmt.Println(res) //3,1,5,4,2 -} -``` - - - -### SortByField -Sort struct slice by field. Slice element should be struct, field type should be int, uint, string, or bool. Default sort type is ascending (asc), if descending order, set sortType to desc
- -Signature: - -```go -func SortByField(slice interface{}, field string, sortType ...string) error -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - type student struct { - name string - age int - } - students := []student{ - {"a", 10}, - {"b", 15}, - {"c", 5}, - {"d", 6}, - } - err := slice.SortByField(students, "age", "desc") - if err != nil { - fmt.Println(err) - } - fmt.Println(students) - // []students{ - // {"b", 15}, - // {"a", 10}, - // {"d", 6}, - // {"c", 5}, - // } -} -``` - - - -### Some -Return true if any of the values in the list pass the predicate function, function signature should be func(index int, value interface{}) bool.
- -Signature: - -```go -func Some(slice, function interface{}) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 5} - isEven := func(i, num int) bool { - return num%2 == 0 - } - - res := slice.Some(nums, isEven) - fmt.Println(res) //true -} -``` - - - -### StringSlice -Convert interface slice to string slice.
- -Signature: - -```go -func StringSlice(slice interface{}) []string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - var s = []interface{}{"a", "b", "c"} - res := slice.StringSlice(s) - fmt.Println(res) //[]string{"a", "b", "c"} -} -``` - - - - -### Unique -Remove duplicate elements in slice.
- -Signature: - -```go -func Unique(slice interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res := slice.Unique([]int{1, 2, 2, 3}) - fmt.Println(res) //[]int{1, 2, 3} -} -``` - - - -### Unique -Creates a slice of unique values, in order, from all given slices. using == for equality comparisons.
- -Signature: - -```go -func Union(slices ...interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - s1 := []int{1, 3, 4, 6} - s2 := []int{1, 2, 5, 6} - res := slice.Union(s1, s2) - - fmt.Println(res) //[]int{1, 3, 4, 6, 2, 5} -} -``` - - - -### UpdateByIndex -Update the slice element at index. if param index < 0 or index >= len(slice), will return error.
- -Signature: - -```go -func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - s := []string{"a", "b", "c"} - - res1, _ := slice.UpdateByIndex(s, 0, "1") - fmt.Println(res1) //[]string{"1", "b", "c"} -} -``` - - - - -### Without -Creates a slice excluding all given values.
- -Signature: - -```go -func Without(slice interface{}, values ...interface{}) interface{} -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res := slice.Without([]int{1, 2, 3, 4, 5}, 1, 2) - fmt.Println(res) //[]int{3, 4, 5} -} -``` - - - - - - - - - - - diff --git a/docs/slice_zh-CN.md b/docs/slice_zh-CN.md deleted file mode 100644 index 18bab8d1..00000000 --- a/docs/slice_zh-CN.md +++ /dev/null @@ -1,965 +0,0 @@ -# Slice -slice包包含操作切片的方法集合。 - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go) - - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/slice" -) -``` - - - -## 目录 -- [Contain](#Contain) -- [ContainSubSlice](#ContainSubSlice) -- [Chunk](#Chunk) -- [Compact](#Compact) -- [Concat](#Concat) -- [Count](#Count) -- [Difference](#Difference) -- [DifferenceBy](#DifferenceBy) -- [DeleteByIndex](#DeleteByIndex) -- [Drop](#Drop) -- [Every](#Every) -- [Filter](#Filter) -- [Find](#Find) -- [FindLast](#FindLast) -- [FlattenDeep](#FlattenDeep) -- [ForEach](#ForEach) - -- [GroupBy](#GroupBy) -- [IntSlice](#IntSlice) -- [InterfaceSlice](#InterfaceSlice) -- [Intersection](#Intersection) -- [InsertByIndex](#InsertByIndex) -- [Map](#Map) -- [ReverseSlice](#ReverseSlice) -- [Reduce](#Reduce) -- [Shuffle](#Shuffle) -- [SortByField](#SortByField) -- [Some](#Some) -- [StringSlice](#StringSlice) -- [Unique](#Unique) -- [Union](#Union) -- [UpdateByIndex](#UpdateByIndex) -- [Without](#Without) - - - -## 文档 - -### Contain -判断slice是否包含value
- -函数签名: - -```go -func Contain(iterableType interface{}, value interface{}) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res := slice.Contain([]string{"a", "b", "c"}, "a") - fmt.Println(res) //true -} -``` - - -### ContainSubSlice -判断slice是否包含subslice
- -函数签名: - -```go -func ContainSubSlice(slice interface{}, subslice interface{}) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res := slice.ContainSubSlice([]string{"a", "b", "c"}, []string{"a", "b"}) - fmt.Println(res) //true -} -``` - - - - -### Chunk -按照size参数均分slice
- -函数签名: - -```go -func Chunk(slice []interface{}, size int) [][]interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - arr := []string{"a", "b", "c", "d", "e"} - res := slice.Chunk(InterfaceSlice(arr), 3) - fmt.Println(res) //[][]interface{}{{"a", "b", "c"}, {"d", "e"}} -} -``` - - - -### Compact -去除slice中的假值(false values are false, nil, 0, "")
- -函数签名: - -```go -func Compact(slice interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res := slice.Compact([]int{0, 1, 2, 3}) - fmt.Println(res) //[]int{1, 2, 3} -} -``` - - -### Concat -连接values到slice中,values类型可以是切片或多个值
- -函数签名: - -```go -func Concat(slice interface{}, values ...interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res1 := slice.Concat([]int{1, 2, 3}, 4, 5) - fmt.Println(res1) //[]int{1, 2, 3, 4, 5} - - res2 := slice.Concat([]int{1, 2, 3}, []int{4, 5}) - fmt.Println(res2) //[]int{1, 2, 3, 4, 5} -} -``` - - - -### Count -遍历切片,对每个元素执行函数function. 返回符合函数返回值为true的元素的个数,函数签名必须是func(index int, value interface{}) bool
- -函数签名: - -```go -func Count(slice, function interface{}) int -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 4, 5, 6} - evenFunc := func(i, num int) bool { - return (num % 2) == 0 - } - - res := slice.Count(nums, evenFunc) - fmt.Println(res) //3 -} -``` - - - - -### Difference -创建一个切片,其元素不包含在另一个给定切片中
- -函数签名: - -```go -func Difference(slice1, slice2 interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - s1 := []int{1, 2, 3, 4, 5} - s2 := []int{4, 5, 6} - - res := slice.Difference(s1, s2) - fmt.Println(res) //[]int{1, 2, 3} -} -``` - - - - -### DifferenceBy -在slice和comparedSlice中的每个元素调用iteratee函数,并比较它们的返回值,如果不想等返回在slice中对应的值
- -函数签名: - -```go -func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - s1 := []int{1, 2, 3, 4, 5} - s2 := []int{4, 5, 6} - addOne := func(i int, v int) int { - return v + 1 - } - - res := slice.DifferenceBy(s1, s2, addOne) - fmt.Println(res) //[]int{1, 2} -} -``` - - - - -### DeleteByIndex -删除切片中从开始索引到结束索引-1的元素
- -函数签名: - -```go -func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error) -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res1 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 3) - fmt.Println(res1) //[]string{"a", "b", "c", "e"} - - res2 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 0, 2) - fmt.Println(res2) //[]string{"c", "d", "e"} - -} -``` - - - - -### Drop -创建一个切片,当 n > 0 时从开头删除 n 个元素,或者当 n < 0 时从结尾删除 n 个元素
- -函数签名: - -```go -func Drop(slice interface{}, n int) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res1 := slice.Drop([]int{}, 0) - fmt.Println(res1) //[]int{} - - res2 := slice.Drop([]int{1, 2, 3, 4, 5}, 1) - fmt.Println(res2) //[]int{2, 3, 4, 5} - - res3 := slice.Drop([]int{1, 2, 3, 4, 5}, -1) - fmt.Println(res3) //[]int{1, 2, 3, 4} -} -``` - - - - -### Every -如果切片中的所有值都通过谓词函数,则返回true。 函数签名应该是func(index int, value interface{}) bool
- -函数签名: - -```go -func Every(slice, function interface{}) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 5} - isEven := func(i, num int) bool { - return num%2 == 0 - } - - res := slice.Every(nums, isEven) - fmt.Println(res) //false -} -``` - - - - -### Filter -返回与函数匹配的所有元素。 函数签名应该是 func(index int, value interface{}) bool
- -函数签名: - -```go -func Filter(slice, function interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 5} - isEven := func(i, num int) bool { - return num%2 == 0 - } - - res := slice.Filter(nums, isEven) - fmt.Println(res) //[]int{2, 4} -} -``` - - - -### Find -遍历slice的元素,返回第一个通过function真值测试的元素。函数签名应该是 func(index int, value interface{}) bool
- -函数签名: - -```go -func Find(slice, function interface{}) (interface{}, bool) -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 5} - isEven := func(i, num int) bool { - return num%2 == 0 - } - - res, ok := slice.Find(nums, even) - fmt.Println(res) //2 - fmt.Println(ok) //true -} -``` - - - - -### FindLast -从头到尾遍历 slice 的元素,返回最后一个通过函数真值测试的元素。 函数签名应该是 func(index int, value interface{}) bool。
- -函数签名: - -```go -func FindLast(slice, function interface{}) (interface{}, bool) -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 5} - isEven := func(i, num int) bool { - return num%2 == 0 - } - - res, ok := slice.FindLast(nums, even) - fmt.Println(res) //4 - fmt.Println(ok) //true -} -``` - - - -### FlattenDeep -flattens slice recursive.
- -函数签名: - -```go -func FlattenDeep(slice interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - arr := [][][]string{{{"a", "b"}}, {{"c", "d"}}} - res := slice.FlattenDeep(arr) - fmt.Println(res) //[]string{"a", "b", "c", "d"} -} -``` - - - - - -### ForEach -遍历slice的元素并为每个元素调用函数,函数签名应该是func(index int, value interface{})
- -函数签名: - -```go -func ForEach(slice, function interface{}) -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - numbers := []int{1, 2, 3, 4, 5} - var numbersAddTwo []int - slice.ForEach(numbers, func(index int, value int) { - numbersAddTwo = append(numbersAddTwo, value+2) - }) - fmt.Println(numbersAddTwo) //[]int{3, 4, 5, 6, 7} -} -``` - - - - -### GroupBy -迭代切片的元素,每个元素将按条件分组,返回两个切片。 函数签名应该是func(index int, value interface{}) bool
- -函数签名: - -```go -func GroupBy(slice, function interface{}) (interface{}, interface{}) -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 4, 5, 6} - evenFunc := func(i, num int) bool { - return (num % 2) == 0 - } - even, odd := slice.GroupBy(nums, evenFunc) - - fmt.Println(even) //[]int{2, 4, 6} - fmt.Println(odd) //]int{1, 3, 5} -} -``` - - - - -### IntSlice -将接口切片转换为int切片
- -函数签名: - -```go -func IntSlice(slice interface{}) []int -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - var nums = []interface{}{1, 2, 3} - res := slice.IntSlice(nums) - fmt.Println(res) //[]int{1, 2, 3} -} -``` - - - - -### InterfaceSlice -将值转换为接口切片
- -函数签名: - -```go -func InterfaceSlice(slice interface{}) []interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - var nums = []int{}{1, 2, 3} - res := slice.InterfaceSlice(nums) - fmt.Println(res) //[]interface{}{1, 2, 3} -} -``` - - - - -### Intersection -多个切片的交集
- -函数签名: - -```go -func Intersection(slices ...interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - s1 := []int{1, 2, 2, 3} - s2 := []int{1, 2, 3, 4} - res := slice.Intersection(s1, s2), - - fmt.Println(res) //[]int{1, 2, 3} -} -``` - - - - -### InsertByIndex -将元素插入到索引处的切片中
- -函数签名: - -```go -func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error) -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - s := []string{"a", "b", "c"} - - res1, _ := slice.InsertByIndex(s, 0, "1") - fmt.Println(res1) //[]string{"1", "a", "b", "c"} - - res2, _ := slice.InsertByIndex(s, 3, []string{"1", "2", "3"}) - fmt.Println(res2) //[]string{"a", "b", "c", "1", "2", "3"} -} -``` - - - - -### Map -通过运行函数slice中的每个元素来创建一个值切片,函数签名应该是func(index int, value interface{}) interface{}。
- -函数签名: - -```go -func Map(slice, function interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 4} - multiplyTwo := func(i, num int) int { - return num * 2 - } - res := slice.Map(nums, multiplyTwo) - fmt.Println(res) //[]int{2, 4, 6, 8} -} -``` - - - - -### ReverseSlice -反转切片中的元素顺序
- -函数签名: - -```go -func ReverseSlice(slice interface{}) -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 4} - slice.ReverseSlice(nums) - fmt.Println(res) //[]int{4, 3, 2, 1} -} -``` - - - -### Reduce -将slice中的元素运行函数,返回运行结果。函数签名应该是func(index int, value1, value2 interface{}) interface{}。
- -函数签名: - -```go -func Reduce(slice, function, zero interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 4} - reduceFunc := func(i, v1, v2 int) int { - return v1 + v2 - } - res := slice.Reduce(nums, reduceFunc, 0) - fmt.Println(res) //10 -} -``` - - - - -### Shuffle -随机打乱切片中的元素顺序
- -函数签名: - -```go -func Shuffle(slice interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 4, 5} - res := slice.Shuffle(nums) - fmt.Println(res) //3,1,5,4,2 -} -``` - - - -### SortByField -按字段对结构切片进行排序。slice元素应为struct,字段类型应为int、uint、string或bool。 默认排序类型是升序(asc),如果是降序,设置 sortType 为 desc
- -函数签名: - -```go -func SortByField(slice interface{}, field string, sortType ...string) error -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - type student struct { - name string - age int - } - students := []student{ - {"a", 10}, - {"b", 15}, - {"c", 5}, - {"d", 6}, - } - err := slice.SortByField(students, "age", "desc") - if err != nil { - fmt.Println(err) - } - fmt.Println(students) - // []students{ - // {"b", 15}, - // {"a", 10}, - // {"d", 6}, - // {"c", 5}, - // } -} -``` - - - -### Some -如果列表中的任何值通过谓词函数,则返回true,函数签名应该是func(index int, value interface{}) bool .
- -函数签名: - -```go -func Some(slice, function interface{}) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - nums := []int{1, 2, 3, 5} - isEven := func(i, num int) bool { - return num%2 == 0 - } - - res := slice.Some(nums, isEven) - fmt.Println(res) //true -} -``` - - - -### StringSlice -将接口切片转换为字符串切片
- -函数签名: - -```go -func StringSlice(slice interface{}) []string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - var s = []interface{}{"a", "b", "c"} - res := slice.StringSlice(s) - fmt.Println(res) //[]string{"a", "b", "c"} -} -``` - - - - -### Unique -删除切片中的重复元素
- -函数签名: - -```go -func Unique(slice interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res := slice.Unique([]int{1, 2, 2, 3}) - fmt.Println(res) //[]int{1, 2, 3} -} -``` - - - -### Unique -从所有给定的切片按顺序创建一个唯一值切片。 使用 == 进行相等比较。
- -函数签名: - -```go -func Union(slices ...interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - s1 := []int{1, 3, 4, 6} - s2 := []int{1, 2, 5, 6} - res := slice.Union(s1, s2) - - fmt.Println(res) //[]int{1, 3, 4, 6, 2, 5} -} -``` - - - -### UpdateByIndex -更新索引处的切片元素。 如果 param index < 0 或 index >= len(slice),将返回错误
- -函数签名: - -```go -func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - s := []string{"a", "b", "c"} - - res1, _ := slice.UpdateByIndex(s, 0, "1") - fmt.Println(res1) //[]string{"1", "b", "c"} -} -``` - - - - -### Without -创建一个不包括所有给定值的切片
- -函数签名: - -```go -func Without(slice interface{}, values ...interface{}) interface{} -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/slice" -) - -func main() { - res := slice.Without([]int{1, 2, 3, 4, 5}, 1, 2) - fmt.Println(res) //[]int{3, 4, 5} -} -``` - - - - - - - - - - - diff --git a/docs/sponsor/sponsor.md b/docs/sponsor/sponsor.md new file mode 100644 index 00000000..b13d4342 --- /dev/null +++ b/docs/sponsor/sponsor.md @@ -0,0 +1,38 @@ +### 赞助 + +您好,我是一名软件开发者,从事开发工作15年。热爱软件开源。并愿意为此付出精力。是开源项目[lancet](https://github.com/duke-git/lancet)的作者。Lancet自2021年前开源发布以来,已有超过1700个内外部项目使用。lancet一直会对所有用户免费。您的支持是对我继续奋斗的有力鼓励。谢谢! 微信扫描以下二维码或点击以下赞助按钮发起赞助。 + + +Creates substring in source string after position when char first appear.
- -Signature: - -```go -func After(s, char string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.After("lancet", "") - fmt.Println(s1) //lancet - - s2 := strutil.After("github.com/test/lancet", "/") - fmt.Println(s2) //test/lancet - - s3 := strutil.After("github.com/test/lancet", "test") - fmt.Println(s3) // /lancet -} -``` - - - -### AfterLast -Creates substring in source string after position when char last appear.
- -Signature: - -```go -func AfterLast(s, char string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.AfterLast("lancet", "") - fmt.Println(s1) //lancet - - s2 := strutil.AfterLast("github.com/test/lancet", "/") - fmt.Println(s2) //lancet - - s3 := strutil.AfterLast("github.com/test/test/lancet", "test") - fmt.Println(s3) // /test/lancet -} -``` - - - - -### Before -Creates substring in source string before position when char first appear.
- -Signature: - -```go -func Before(s, char string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.Before("lancet", "") - fmt.Println(s1) //lancet - - s2 := strutil.Before("github.com/test/lancet", "/") - fmt.Println(s2) //github.com - - s3 := strutil.Before("github.com/test/lancet", "test") - fmt.Println(s3) // github.com/ -} -``` - - - - -### BeforeLast -Creates substring in source string before position when char first appear.
- -Signature: - -```go -func BeforeLast(s, char string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.BeforeLast("lancet", "") - fmt.Println(s1) //lancet - - s2 := strutil.BeforeLast("github.com/test/lancet", "/") - fmt.Println(s2) //github.com/test - - s3 := strutil.BeforeLast("github.com/test/test/lancet", "test") - fmt.Println(s3) //github.com/test/ -} -``` - - - - -### CamelCase -Covert string to camelCase string.
- -Signature: - -```go -func CamelCase(s string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.CamelCase("foo_bar") - fmt.Println(s1) //fooBar - - s2 := strutil.CamelCase("Foo-Bar") - fmt.Println(s2) //fooBar - - s3 := strutil.CamelCase("Foo&bar") - fmt.Println(s3) //fooBar - - s4 := strutil.CamelCase("foo bar") - fmt.Println(s4) //fooBar -} -``` - - - - -### Capitalize -Convert the first character of a string to upper case.
- -Signature: - -```go -func Capitalize(s string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.Capitalize("foo") - fmt.Println(s1) //foo - - s2 := strutil.Capitalize("Foo") - fmt.Println(s2) //foo - - s3 := strutil.Capitalize("FOo" - fmt.Println(s3) //fOo -} -``` - - - -### IsString -Check if the value's data type is string.
- -Signature: - -```go -func IsString(v interface{}) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - fmt.Println(strutil.IsString("lancet")) //true - fmt.Println(strutil.IsString("")) //true - - fmt.Println(strutil.IsString(1)) //false - fmt.Println(strutil.IsString("")) //false - fmt.Println(strutil.IsString([]string{})) //false -} -``` - - - -### KebabCase -Covert string to kebab-case.
- -Signature: - -```go -func KebabCase(s string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.KebabCase("Foo Bar-") - fmt.Println(s1) //foo-bar - - s2 := strutil.KebabCase("foo_Bar") - fmt.Println(s2) //foo-bar - - s3 := strutil.KebabCase("fooBar") - fmt.Println(s3) //foo-bar - - s4 := strutil.KebabCase("__FOO_BAR__") - fmt.Println(s4) //f-o-o-b-a-r -} -``` - - - - -### LowerFirst -Convert the first character of string to lower case.
- -Signature: - -```go -func LowerFirst(s string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.LowerFirst("foo") - fmt.Println(s1) //foo - - s2 := strutil.LowerFirst("BAR") - fmt.Println(s2) //bAR - - s3 := strutil.LowerFirst("FOo") - fmt.Println(s3) //fOo - - s4 := strutil.LowerFirst("fOo大") - fmt.Println(s4) //fOo大 -} -``` - - - - -### UpperFirst -Convert the first character of string to upper case.
- -Signature: - -```go -func UpperFirst(s string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.UpperFirst("foo") - fmt.Println(s1) //Foo - - s2 := strutil.UpperFirst("bAR") - fmt.Println(s2) //BAR - - s3 := strutil.UpperFirst("FOo") - fmt.Println(s3) //FOo - - s4 := strutil.UpperFirst("fOo大") - fmt.Println(s4) //FOo大 -} -``` - - - - -### PadEnd -Pads string on the right side if it's shorter than size.
- -Signature: - -```go -func PadEnd(source string, size int, padStr string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.PadEnd("a", 1, "b") - fmt.Println(s1) //a - - s2 := strutil.PadEnd("a", 2, "b") - fmt.Println(s2) //ab - - s3 := strutil.PadEnd("abcd", 6, "mno") - fmt.Println(s3) //abcdmn - - s4 := strutil.PadEnd("abc", 6, "ab") - fmt.Println(s4) //abcaba -} -``` - - - - -### PadStart -Pads string on the left side if it's shorter than size.
- -Signature: - -```go -func PadStart(source string, size int, padStr string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.PadStart("a", 1, "b") - fmt.Println(s1) //a - - s2 := strutil.PadStart("a", 2, "b") - fmt.Println(s2) //ba - - s3 := strutil.PadStart("abcd", 6, "mno") - fmt.Println(s3) //mnabcd - - s4 := strutil.PadStart("abc", 6, "ab") - fmt.Println(s4) //abaabc -} -``` - - - - -### ReverseStr -Return string whose char order is reversed to the given string.
- -Signature: - -```go -func ReverseStr(s string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.ReverseStr("abc") - fmt.Println(s1) //cba - - s2 := strutil.ReverseStr("12345") - fmt.Println(s2) //54321 -} -``` - - - -### SnakeCase -Covert string to snake_case.
- -Signature: - -```go -func SnakeCase(s string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.SnakeCase("Foo Bar-") - fmt.Println(s1) //foo_bar - - s2 := strutil.SnakeCase("foo_Bar") - fmt.Println(s2) //foo_bar - - s3 := strutil.SnakeCase("fooBar") - fmt.Println(s3) //foo_bar - - s4 := strutil.SnakeCase("__FOO_BAR__") - fmt.Println(s4) //f_o_o_b_a_r - - s5 := strutil.SnakeCase("aBbc-s$@a&%_B.B^C") - fmt.Println(s5) //a_bbc_s_a_b_b_c -} -``` - - - - -### Wrap -Wrap a string with another string.
- -Signature: - -```go -func Wrap(str string, wrapWith string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.Wrap("ab", "") - fmt.Println(s1) //ab - - s2 := strutil.Wrap("", "*") - fmt.Println(s2) //"" - - s3 := strutil.Wrap("ab", "*") - fmt.Println(s3) //*ab* - - s4 := strutil.Wrap("ab", "\"") - fmt.Println(s4) //\"ab\" - - s5 := strutil.Wrap("ab", "'") - fmt.Println(s5) //'ab' -} -``` - - - - -### Wrap -Unwrap a given string from anther string. will change str value.
- -Signature: - -```go -func Unwrap(str string, wrapToken string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.Unwrap("ab", "") - fmt.Println(s1) //ab - - s2 := strutil.Unwrap("ab", "*") - fmt.Println(s2) //ab - - s3 := strutil.Unwrap("**ab**", "*") - fmt.Println(s3) //*ab* - - s4 := strutil.Unwrap("*ab", "*") - fmt.Println(s4) //*ab - - s5 := strutil.Unwrap("***", "**") - fmt.Println(s5) //*** -} -``` - - - - - - - - - diff --git a/docs/strutil_zh-CN.md b/docs/strutil_zh-CN.md deleted file mode 100644 index 35d3ef32..00000000 --- a/docs/strutil_zh-CN.md +++ /dev/null @@ -1,575 +0,0 @@ -# Strutil -strutil包含处理字符串的相关函数。 - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/strutil/string.go) - - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/strutil" -) -``` - - - -## 目录 -- [After](#After) -- [AfterLast](#AfterLast) -- [Before](#Before) -- [BeforeLast](#BeforeLast) -- [CamelCase](#CamelCase) -- [Capitalize](#Capitalize) -- [IsString](#IsString) -- [KebabCase](#KebabCase) -- [LowerFirst](#LowerFirst) -- [UpperFirst](#UpperFirst) -- [PadEnd](#PadEnd) -- [PadStart](#PadStart) -- [ReverseStr](#ReverseStr) -- [SnakeCase](#SnakeCase) -- [Wrap](#Wrap) - -- [Unwrap](#Unwrap) - - - - - -## Documentation文档 - - -### After -截取源字符串中char首次出现时的位置之后的子字符串
- -函数签名: - -```go -func After(s, char string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.After("lancet", "") - fmt.Println(s1) //lancet - - s2 := strutil.After("github.com/test/lancet", "/") - fmt.Println(s2) //test/lancet - - s3 := strutil.After("github.com/test/lancet", "test") - fmt.Println(s3) // /lancet -} -``` - - - -### AfterLast -截取源字符串中char最后一次出现时的位置之后的子字符串
- -函数签名: - -```go -func AfterLast(s, char string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.AfterLast("lancet", "") - fmt.Println(s1) //lancet - - s2 := strutil.AfterLast("github.com/test/lancet", "/") - fmt.Println(s2) //lancet - - s3 := strutil.AfterLast("github.com/test/test/lancet", "test") - fmt.Println(s3) // /lancet -} -``` - - - - -### Before -截取源字符串中char首次出现时的位置之前的子字符串
- -函数签名: - -```go -func Before(s, char string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.Before("lancet", "") - fmt.Println(s1) //lancet - - s2 := strutil.Before("github.com/test/lancet", "/") - fmt.Println(s2) //github.com - - s3 := strutil.Before("github.com/test/lancet", "test") - fmt.Println(s3) // github.com/ -} -``` - - - - -### BeforeLast -截取源字符串中char最后一次出现时的位置之前的子字符串
- -函数签名: - -```go -func BeforeLast(s, char string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.BeforeLast("lancet", "") - fmt.Println(s1) //lancet - - s2 := strutil.BeforeLast("github.com/test/lancet", "/") - fmt.Println(s2) //github.com/test - - s3 := strutil.BeforeLast("github.com/test/test/lancet", "test") - fmt.Println(s3) //github.com/test/ -} -``` - - - - -### CamelCase -将字符串转换为驼峰式字符串
- -函数签名: - -```go -func CamelCase(s string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.CamelCase("foo_bar") - fmt.Println(s1) //fooBar - - s2 := strutil.CamelCase("Foo-Bar") - fmt.Println(s2) //fooBar - - s3 := strutil.CamelCase("Foo&bar") - fmt.Println(s3) //fooBar - - s4 := strutil.CamelCase("foo bar") - fmt.Println(s4) //fooBar -} -``` - - - - -### Capitalize -将字符串的第一个字符转换为大写
- -函数签名: - -```go -func Capitalize(s string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.Capitalize("foo") - fmt.Println(s1) //foo - - s2 := strutil.Capitalize("Foo") - fmt.Println(s2) //foo - - s3 := strutil.Capitalize("FOo" - fmt.Println(s3) //fOo -} -``` - - - -### IsString -检查值的数据类型是否为字符串
- -函数签名: - -```go -func IsString(v interface{}) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - fmt.Println(strutil.IsString("lancet")) //true - fmt.Println(strutil.IsString("")) //true - - fmt.Println(strutil.IsString(1)) //false - fmt.Println(strutil.IsString("")) //false - fmt.Println(strutil.IsString([]string{})) //false -} -``` - - - -### KebabCase -将字符串转换为kebab-case
- -函数签名: - -```go -func KebabCase(s string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.KebabCase("Foo Bar-") - fmt.Println(s1) //foo-bar - - s2 := strutil.KebabCase("foo_Bar") - fmt.Println(s2) //foo-bar - - s3 := strutil.KebabCase("fooBar") - fmt.Println(s3) //foo-bar - - s4 := strutil.KebabCase("__FOO_BAR__") - fmt.Println(s4) //f-o-o-b-a-r -} -``` - - - - -### LowerFirst -将字符串的第一个字符转换为小写
- -函数签名: - -```go -func LowerFirst(s string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.LowerFirst("foo") - fmt.Println(s1) //foo - - s2 := strutil.LowerFirst("BAR") - fmt.Println(s2) //bAR - - s3 := strutil.LowerFirst("FOo") - fmt.Println(s3) //fOo - - s4 := strutil.LowerFirst("fOo大") - fmt.Println(s4) //fOo大 -} -``` - - - - -### UpperFirst -将字符串的第一个字符转换为大写
- -函数签名: - -```go -func UpperFirst(s string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.UpperFirst("foo") - fmt.Println(s1) //Foo - - s2 := strutil.UpperFirst("bAR") - fmt.Println(s2) //BAR - - s3 := strutil.UpperFirst("FOo") - fmt.Println(s3) //FOo - - s4 := strutil.UpperFirst("fOo大") - fmt.Println(s4) //FOo大 -} -``` - - - - -### PadEnd -如果字符串长度短于size,则在右侧填充字符串
- -函数签名: - -```go -func PadEnd(source string, size int, padStr string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.PadEnd("a", 1, "b") - fmt.Println(s1) //a - - s2 := strutil.PadEnd("a", 2, "b") - fmt.Println(s2) //ab - - s3 := strutil.PadEnd("abcd", 6, "mno") - fmt.Println(s3) //abcdmn - - s4 := strutil.PadEnd("abc", 6, "ab") - fmt.Println(s4) //abcaba -} -``` - - - - -### PadStart -如果字符串长度短于size,则在左侧填充字符串
- -函数签名: - -```go -func PadStart(source string, size int, padStr string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.PadStart("a", 1, "b") - fmt.Println(s1) //a - - s2 := strutil.PadStart("a", 2, "b") - fmt.Println(s2) //ba - - s3 := strutil.PadStart("abcd", 6, "mno") - fmt.Println(s3) //mnabcd - - s4 := strutil.PadStart("abc", 6, "ab") - fmt.Println(s4) //abaabc -} -``` - - - - -### ReverseStr -返回字符顺序与给定字符串相反的字符串
- -函数签名: - -```go -func ReverseStr(s string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.ReverseStr("abc") - fmt.Println(s1) //cba - - s2 := strutil.ReverseStr("12345") - fmt.Println(s2) //54321 -} -``` - - - -### SnakeCase -将字符串转换为snake_case形式
- -函数签名: - -```go -func SnakeCase(s string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.SnakeCase("Foo Bar-") - fmt.Println(s1) //foo_bar - - s2 := strutil.SnakeCase("foo_Bar") - fmt.Println(s2) //foo_bar - - s3 := strutil.SnakeCase("fooBar") - fmt.Println(s3) //foo_bar - - s4 := strutil.SnakeCase("__FOO_BAR__") - fmt.Println(s4) //f_o_o_b_a_r - - s5 := strutil.SnakeCase("aBbc-s$@a&%_B.B^C") - fmt.Println(s5) //a_bbc_s_a_b_b_c -} -``` - - - - -### Wrap -用另一个字符串包裹一个字符串
- -函数签名: - -```go -func Wrap(str string, wrapWith string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.Wrap("ab", "") - fmt.Println(s1) //ab - - s2 := strutil.Wrap("", "*") - fmt.Println(s2) //"" - - s3 := strutil.Wrap("ab", "*") - fmt.Println(s3) //*ab* - - s4 := strutil.Wrap("ab", "\"") - fmt.Println(s4) //\"ab\" - - s5 := strutil.Wrap("ab", "'") - fmt.Println(s5) //'ab' -} -``` - - - - -### Unwrap -用另一个字符串解开包裹一个字符串
- -函数签名: - -```go -func Unwrap(str string, wrapToken string) string -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/strutil" -) - -func main() { - s1 := strutil.Unwrap("ab", "") - fmt.Println(s1) //ab - - s2 := strutil.Unwrap("ab", "*") - fmt.Println(s2) //ab - - s3 := strutil.Unwrap("**ab**", "*") - fmt.Println(s3) //*ab* - - s4 := strutil.Unwrap("*ab", "*") - fmt.Println(s4) //*ab - - s5 := strutil.Unwrap("***", "**") - fmt.Println(s5) //*** -} -``` - - - - - - - - - diff --git a/docs/system.md b/docs/system.md deleted file mode 100644 index 6e2adaee..00000000 --- a/docs/system.md +++ /dev/null @@ -1,242 +0,0 @@ -# System -Package system contains some functions about os, runtime, shell command. - - - -## Source: - -[https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go) - - - - -## Usage: -```go -import ( - "github.com/duke-git/lancet/system" -) -``` - - - -## Index -- [IsWindows](#IsWindows) -- [IsLinux](#IsLinux) -- [IsMac](#IsMac) -- [GetOsEnv](#GetOsEnv) -- [SetOsEnv](#SetOsEnv) -- [RemoveOsEnv](#RemoveOsEnv) -- [CompareOsEnv](#CompareOsEnv) -- [ExecCommand](#ExecCommand) - - - - -## Documentation - - -### IsWindows -Check if current os is windows.
- -Signature: - -```go -func IsWindows() bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - isOsWindows := system.IsWindows() - fmt.Println(isOsWindows) -} -``` - - - - -### IsLinux -Check if current os is linux.
- -Signature: - -```go -func IsLinux() bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - isOsLinux := system.IsLinux() - fmt.Println(isOsLinux) -} -``` - - - -### IsMac -Check if current os is macos.
- -Signature: - -```go -func IsMac() bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - isOsMac := system.IsMac - fmt.Println(isOsMac) -} -``` - - - -### GetOsEnv -Gets the value of the environment variable named by the key.
- -Signature: - -```go -func GetOsEnv(key string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - fooEnv := system.GetOsEnv("foo") - fmt.Println(fooEnv) -} -``` - - - -### SetOsEnv -Sets the value of the environment variable named by the key.
- -Signature: - -```go -func SetOsEnv(key, value string) error -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - err := system.SetOsEnv("foo", "foo_value") - fmt.Println(err) -} -``` - - - - -### RemoveOsEnv -Remove a single environment variable.
- -Signature: - -```go -func RemoveOsEnv(key string) error -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - err := system.RemoveOsEnv("foo") - if err != nil { - fmt.Println(err) - } -} -``` - - - -### CompareOsEnv -Get env named by the key and compare it with comparedEnv.
- -Signature: - -```go -func CompareOsEnv(key, comparedEnv string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - system.SetOsEnv("foo", "foo_value") - res := system.CompareOsEnv("foo", "foo_value") - fmt.Println(res) //true -} -``` - - - - -### CompareOsEnv -use shell /bin/bash -c(linux) or cmd (windows) to execute command.
- -Signature: - -```go -func ExecCommand(command string) (stdout, stderr string, err error) -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - out, errout, err := system.ExecCommand("ls") - fmt.Println(out) - fmt.Println(errout) - fmt.Println(err) -} -``` - - - - - - - - diff --git a/docs/system_zh-CN.md b/docs/system_zh-CN.md deleted file mode 100644 index 166d892b..00000000 --- a/docs/system_zh-CN.md +++ /dev/null @@ -1,242 +0,0 @@ -# System -system包含os, runtime, shell command相关函数。 - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go) - - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/system" -) -``` - - - -## 目录 -- [IsWindows](#IsWindows) -- [IsLinux](#IsLinux) -- [IsMac](#IsMac) -- [GetOsEnv](#GetOsEnv) -- [SetOsEnv](#SetOsEnv) -- [RemoveOsEnv](#RemoveOsEnv) -- [CompareOsEnv](#CompareOsEnv) -- [ExecCommand](#ExecCommand) - - - - -## Documentation文档 - - -### IsWindows -检查当前操作系统是否是windows
- -Signature: - -```go -func IsWindows() bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - isOsWindows := system.IsWindows() - fmt.Println(isOsWindows) -} -``` - - - - -### IsLinux -检查当前操作系统是否是linux
- -Signature: - -```go -func IsLinux() bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - isOsLinux := system.IsLinux() - fmt.Println(isOsLinux) -} -``` - - - -### IsMac -检查当前操作系统是否是macos
- -Signature: - -```go -func IsMac() bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - isOsMac := system.IsMac - fmt.Println(isOsMac) -} -``` - - - -### GetOsEnv -获取key命名的环境变量的值
- -Signature: - -```go -func GetOsEnv(key string) string -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - fooEnv := system.GetOsEnv("foo") - fmt.Println(fooEnv) -} -``` - - - -### SetOsEnv -设置由key命名的环境变量的值
- -Signature: - -```go -func SetOsEnv(key, value string) error -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - err := system.SetOsEnv("foo", "foo_value") - fmt.Println(err) -} -``` - - - - -### RemoveOsEnv -删除单个环境变量
- -Signature: - -```go -func RemoveOsEnv(key string) error -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - err := system.RemoveOsEnv("foo") - if err != nil { - fmt.Println(err) - } -} -``` - - - -### CompareOsEnv -获取key命名的环境变量值并与compareEnv进行比较
- -Signature: - -```go -func CompareOsEnv(key, comparedEnv string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - system.SetOsEnv("foo", "foo_value") - res := system.CompareOsEnv("foo", "foo_value") - fmt.Println(res) //true -} -``` - - - - -### CompareOsEnv -使用shell /bin/bash -c(linux) 或 cmd (windows) 执行shell命令
- -Signature: - -```go -func ExecCommand(command string) (stdout, stderr string, err error) -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/system" -) - -func main() { - out, errout, err := system.ExecCommand("ls") - fmt.Println(out) - fmt.Println(errout) - fmt.Println(err) -} -``` - - - - - - - - diff --git a/docs/validator.md b/docs/validator.md deleted file mode 100644 index f4275f10..00000000 --- a/docs/validator.md +++ /dev/null @@ -1,799 +0,0 @@ -# Validator -Package validator contains some functions for data validation. - - - -## Source: - -[https://github.com/duke-git/lancet/blob/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/validator/validator.go) - - - - -## Usage: -```go -import ( - "github.com/duke-git/lancet/validator" -) -``` - - - -## Index -- [ContainChinese](#ContainChinese) -- [ContainLetter](#ContainLetter) -- [ContainLower](#ContainLower) -- [ContainUpper](#ContainUpper) -- [IsAlpha](#IsAlpha) -- [IsAllUpper](#IsAllUpper) -- [IsAllLower](#IsAllLower) -- [IsBase64](#IsBase64) -- [IsChineseMobile](#IsChineseMobile) -- [IsChineseIdNum](#IsChineseIdNum) -- [IsChinesePhone](#IsChinesePhone) -- [IsCreditCard](#IsCreditCard) -- [IsDns](#IsDns) -- [IsEmail](#IsEmail) - -- [IsEmptyString](#IsEmptyString) -- [IsFloatStr](#IsFloatStr) -- [IsNumberStr](#IsNumberStr) -- [IsJSON](#IsJSON) -- [IsRegexMatch](#IsRegexMatch) -- [IsIntStr](#IsIntStr) -- [IsIp](#IsIp) -- [IsIpV4](#IsIpV4) -- [IsIpV6](#IsIpV6) -- [IsStrongPassword](#IsStrongPassword) -- [IsUrl](#IsUrl) -- [IsWeakPassword](#IsWeakPassword) - - - - -## Documentation - - -### ContainChinese -Check if the string contain mandarin chinese.
- -Signature: - -```go -func ContainChinese(s string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.ContainChinese("你好") - fmt.Println(res1) //true - - res2 := validator.ContainChinese("你好hello") - fmt.Println(res2) //true - - res3 := validator.ContainChinese("hello") - fmt.Println(res3) //false -} -``` - - - -### ContainLetter -Check if the string contain at least one letter.
- -Signature: - -```go -func ContainLetter(str string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.ContainLetter("1bc") - fmt.Println(res1) //true - - res2 := validator.ContainLetter("123") - fmt.Println(res2) //false - - res3 := validator.ContainLetter("&@#$%^&*") - fmt.Println(res3) //false -} -``` - - - - -### ContainLower -Check if the string contain at least one lower case letter a-z.
- -Signature: - -```go -func ContainLower(str string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.ContainLower("1bc") - fmt.Println(res1) //true - - res2 := validator.ContainLower("123") - fmt.Println(res2) //false - - res3 := validator.ContainLower("1BC") - fmt.Println(res3) //false -} -``` - - - - -### ContainUpper -Check if the string contain at least one upper case letter A-Z.
- -Signature: - -```go -func ContainUpper(str string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.ContainUpper("1bc") - fmt.Println(res1) //false - - res2 := validator.ContainUpper("123") - fmt.Println(res2) //false - - res3 := validator.ContainUpper("1BC") - fmt.Println(res3) //true -} -``` - - - - -### IsAlpha -Check if the string contains only letters (a-zA-Z).
- -Signature: - -```go -func IsAlpha(s string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsAlpha("abc") - fmt.Println(res1) //true - - res2 := validator.IsAlpha("1bc") - fmt.Println(res2) //false - - res3 := validator.IsAlpha("") - fmt.Println(res3) //false -} -``` - -### IsAllUpper -Check if string is all upper case letters A-Z.
- -Signature: - -```go -func IsAllUpper(str string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsAllUpper("ABC") - fmt.Println(res1) //true - - res2 := validator.IsAllUpper("aBC") - fmt.Println(res2) //false -} -``` - - - - -### IsAllLower -Check if string is all lower case letters a-z.
- -Signature: - -```go -func IsAllLower(str string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsAllLower("abc") - fmt.Println(res1) //true - - res2 := validator.IsAllLower("abC") - fmt.Println(res2) //false -} -``` - - - - -### IsBase64 -Check if the string is base64 string.
- -Signature: - -```go -func IsBase64(base64 string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsBase64("aGVsbG8=") - fmt.Println(res1) //true - - res2 := validator.IsBase64("123456") - fmt.Println(res2) //false -} -``` - - - - -### IsChineseMobile -Check if the string is valid chinese mobile number.
- -Signature: - -```go -func IsChineseMobile(mobileNum string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsChineseMobile("13263527980") - fmt.Println(res1) //true - - res2 := validator.IsChineseMobile("434324324") - fmt.Println(res2) //false -} -``` - - - -### IsChineseIdNum -Check if the string is chinese id number.
- -Signature: - -```go -func IsChineseIdNum(id string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsChineseIdNum("210911192105130715") - fmt.Println(res1) //true - - res2 := validator.IsChineseIdNum("123456") - fmt.Println(res2) //false -} -``` - - - - -### IsChinesePhone -Check if the string is chinese phone number.
- -Signature: - -```go -func IsChinesePhone(phone string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsChinesePhone("010-32116675") - fmt.Println(res1) //true - - res2 := validator.IsChinesePhone("123-87562") - fmt.Println(res2) //false -} -``` - - - - -### IsCreditCard -Check if the string is credit card.
- -Signature: - -```go -func IsCreditCard(creditCart string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsCreditCard("4111111111111111") - fmt.Println(res1) //true - - res2 := validator.IsCreditCard("123456") - fmt.Println(res2) //false -} -``` - - - - -### IsDns -Check if the string is valid dns.
- -Signature: - -```go -func IsDns(dns string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsDns("abc.com") - fmt.Println(res1) //true - - res2 := validator.IsDns("a.b.com") - fmt.Println(res2) //false - - res3 := validator.IsDns("http://abc.com") - fmt.Println(res3) //false -} -``` - - - - -### IsEmail -Check if the string is email address.
- -Signature: - -```go -func IsEmail(email string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsEmail("abc@xyz.com") - fmt.Println(res1) //true - - res2 := validator.IsEmail("a.b@@com") - fmt.Println(res2) //false -} -``` - - - - - -### IsEmptyString -Check if the string is empty or not.
- -Signature: - -```go -func IsEmptyString(s string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsEmptyString("") - fmt.Println(res1) //true - - res2 := validator.IsEmptyString("abc") - fmt.Println(res2) //false -} -``` - - - - -### IsFloatStr -Check if the string can convert to a float.
- -Signature: - -```go -func IsFloatStr(s string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsFloatStr("")) //false - fmt.Println(validator.IsFloatStr("12a")) //false - fmt.Println(validator.IsFloatStr("3.")) //true - fmt.Println(validator.IsFloatStr("+3.")) //true - fmt.Println(validator.IsFloatStr("-3.")) //true - fmt.Println(validator.IsFloatStr("12")) //true -} -``` - - - - -### IsNumberStr -Check if the string can convert to a number.
- -Signature: - -```go -func IsNumberStr(s string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsNumberStr("")) //false - fmt.Println(validator.IsNumberStr("12a")) //false - fmt.Println(validator.IsNumberStr("3.")) //true - fmt.Println(validator.IsNumberStr("+3.")) //true - fmt.Println(validator.IsNumberStr("-3.")) //true - fmt.Println(validator.IsNumberStr("+3e2")) //true -} -``` - - - - -### IsJSON -Check if the string is valid JSON.
- -Signature: - -```go -func IsJSON(str string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsJSON("")) //false - fmt.Println(validator.IsJSON("abc")) //false - fmt.Println(validator.IsJSON("{}")) //true - fmt.Println(validator.IsJSON("[]")) //true - fmt.Println(validator.IsJSON("123")) //true - fmt.Println(validator.IsJSON("{\"name\": \"test\"}")) //true -} -``` - - - - -### IsRegexMatch -Check if the string match the regexp.
- -Signature: - -```go -func IsRegexMatch(s, regex string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsRegexMatch("abc", `^[a-zA-Z]+$`)) //true - fmt.Println(validator.IsRegexMatch("1ab", `^[a-zA-Z]+$`)) //false - fmt.Println(validator.IsRegexMatch("", `^[a-zA-Z]+$`)) //false -} -``` - - - - -### IsIntStr -Check if the string can convert to a integer.
- -Signature: - -```go -func IsIntStr(s string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsIntStr("+3")) //true - fmt.Println(validator.IsIntStr("-3")) //true - fmt.Println(validator.IsIntStr("3.")) //false - fmt.Println(validator.IsIntStr("abc")) //false -} -``` - - - - -### IsIp -Check if the string is a ip address.
- -Signature: - -```go -func IsIp(ipstr string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsIp("127.0.0.1")) //true - fmt.Println(validator.IsIp("::0:0:0:0:0:0:1")) //true - fmt.Println(validator.IsIp("127.0.0")) //false - fmt.Println(validator.IsIp("127")) //false -} -``` - - - - -### IsIpV4 -Check if the string is a ipv4 address.
- -Signature: - -```go -func IsIpV4(ipstr string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsIpV4("127.0.0.1")) //true - fmt.Println(validator.IsIpV4("::0:0:0:0:0:0:1")) //false - fmt.Println(validator.IsIpV4("127.0.0")) //false - fmt.Println(validator.IsIpV4("127")) //false -} -``` - - - - -### IsIpV6 -Check if the string is a ipv6 address.
- -Signature: - -```go -func IsIpV6(ipstr string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsIpV6("127.0.0.1")) //false - fmt.Println(validator.IsIpV6("::0:0:0:0:0:0:1")) //true - fmt.Println(validator.IsIpV6("127.0.0")) //false - fmt.Println(validator.IsIpV6("127")) //false -} -``` - - - - -### IsStrongPassword -Check if the string is strong password (alpha(lower+upper) + number + special chars(!@#$%^&*()?><)).
- -Signature: - -```go -func IsStrongPassword(password string, length int) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsStrongPassword("abc", 3)) //false - fmt.Println(validator.IsStrongPassword("abc123", 6)) //false - fmt.Println(validator.IsStrongPassword("abcABC", 6)) //false - fmt.Println(validator.IsStrongPassword("abcABC123@#$", 16)) //false - fmt.Println(validator.IsStrongPassword("abcABC123@#$", 12)) //true -} -``` - - - - -### IsUrl -Check if the string is url.
- -Signature: - -```go -func IsUrl(str string) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsUrl("http://abc.com")) //true - fmt.Println(validator.IsUrl("abc.com")) //true - fmt.Println(validator.IsUrl("a.b.com")) //true - fmt.Println(validator.IsUrl("abc")) //false -} -``` - - - - -### IsWeakPassword -Check if the string is weak password(only letter or only number or letter + number) -.
- -Signature: - -```go -func IsWeakPassword(password string, length int) bool -``` -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsWeakPassword("abc")) //true - fmt.Println(validator.IsWeakPassword("123")) //true - fmt.Println(validator.IsWeakPassword("abc123")) //true - fmt.Println(validator.IsWeakPassword("abc123@#$")) //false -} -``` - - - - - - - - - diff --git a/docs/validator_zh-CN.md b/docs/validator_zh-CN.md deleted file mode 100644 index 00c5e103..00000000 --- a/docs/validator_zh-CN.md +++ /dev/null @@ -1,799 +0,0 @@ -# Validator -validator验证器包,包含常用字符串格式验证函数。 - - - -## 源码: - -[https://github.com/duke-git/lancet/blob/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/validator/validator.go) - - - - -## 用法: -```go -import ( - "github.com/duke-git/lancet/validator" -) -``` - - - -## 目录: -- [ContainChinese](#ContainChinese) -- [ContainLetter](#ContainLetter) -- [ContainLower](#ContainLower) -- [ContainUpper](#ContainUpper) -- [IsAlpha](#IsAlpha) -- [IsAllUpper](#IsAllUpper) -- [IsAllLower](#IsAllLower) -- [IsBase64](#IsBase64) -- [IsChineseMobile](#IsChineseMobile) -- [IsChineseIdNum](#IsChineseIdNum) -- [IsChinesePhone](#IsChinesePhone) -- [IsCreditCard](#IsCreditCard) -- [IsDns](#IsDns) -- [IsEmail](#IsEmail) - -- [IsEmptyString](#IsEmptyString) -- [IsFloatStr](#IsFloatStr) -- [IsNumberStr](#IsNumberStr) -- [IsJSON](#IsJSON) -- [IsRegexMatch](#IsRegexMatch) -- [IsIntStr](#IsIntStr) -- [IsIp](#IsIp) -- [IsIpV4](#IsIpV4) -- [IsIpV6](#IsIpV6) -- [IsStrongPassword](#IsStrongPassword) -- [IsUrl](#IsUrl) -- [IsWeakPassword](#IsWeakPassword) - - - - -## 文档 - - -### ContainChinese -验证字符串是否包含中文字符
- -函数签名: - -```go -func ContainChinese(s string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.ContainChinese("你好") - fmt.Println(res1) //true - - res2 := validator.ContainChinese("你好hello") - fmt.Println(res2) //true - - res3 := validator.ContainChinese("hello") - fmt.Println(res3) //false -} -``` - - - -### ContainLetter -验证字符串是否包含至少一个英文字母
- -函数签名: - -```go -func ContainLetter(str string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.ContainLetter("1bc") - fmt.Println(res1) //true - - res2 := validator.ContainLetter("123") - fmt.Println(res2) //false - - res3 := validator.ContainLetter("&@#$%^&*") - fmt.Println(res3) //false -} -``` - - - - -### ContainLower -验证字符串是否包含至少一个英文小写字母
- -函数签名: - -```go -func ContainLower(str string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.ContainLower("1bc") - fmt.Println(res1) //true - - res2 := validator.ContainLower("123") - fmt.Println(res2) //false - - res3 := validator.ContainLower("1BC") - fmt.Println(res3) //false -} -``` - - - - -### ContainUpper -验证字符串是否包含至少一个英文大写字母.
- -函数签名: - -```go -func ContainUpper(str string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.ContainUpper("1bc") - fmt.Println(res1) //false - - res2 := validator.ContainUpper("123") - fmt.Println(res2) //false - - res3 := validator.ContainUpper("1BC") - fmt.Println(res3) //true -} -``` - - - - -### IsAlpha -验证字符串是否只包含英文字母
- -函数签名: - -```go -func IsAlpha(s string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsAlpha("abc") - fmt.Println(res1) //true - - res2 := validator.IsAlpha("1bc") - fmt.Println(res2) //false - - res3 := validator.IsAlpha("") - fmt.Println(res3) //false -} -``` - -### IsAllUpper -验证字符串是否全是大写英文字母
- -函数签名: - -```go -func IsAllUpper(str string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsAllUpper("ABC") - fmt.Println(res1) //true - - res2 := validator.IsAllUpper("aBC") - fmt.Println(res2) //false -} -``` - - - - -### IsAllLower -验证字符串是否全是小写英文字母
- -函数签名: - -```go -func IsAllLower(str string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsAllLower("abc") - fmt.Println(res1) //true - - res2 := validator.IsAllLower("abC") - fmt.Println(res2) //false -} -``` - - - - -### IsBase64 -验证字符串是否是base64编码
- -函数签名: - -```go -func IsBase64(base64 string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsBase64("aGVsbG8=") - fmt.Println(res1) //true - - res2 := validator.IsBase64("123456") - fmt.Println(res2) //false -} -``` - - - - -### IsChineseMobile -验证字符串是否是中国手机号码
- -函数签名: - -```go -func IsChineseMobile(mobileNum string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsChineseMobile("13263527980") - fmt.Println(res1) //true - - res2 := validator.IsChineseMobile("434324324") - fmt.Println(res2) //false -} -``` - - - -### IsChineseIdNum -验证字符串是否是中国身份证号码
- -函数签名: - -```go -func IsChineseIdNum(id string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsChineseIdNum("210911192105130715") - fmt.Println(res1) //true - - res2 := validator.IsChineseIdNum("123456") - fmt.Println(res2) //false -} -``` - - - - -### IsChinesePhone -验证字符串是否是中国电话座机号码
- -函数签名: - -```go -func IsChinesePhone(phone string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsChinesePhone("010-32116675") - fmt.Println(res1) //true - - res2 := validator.IsChinesePhone("123-87562") - fmt.Println(res2) //false -} -``` - - - - -### IsCreditCard -验证字符串是否是信用卡号码
- -函数签名: - -```go -func IsCreditCard(creditCart string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsCreditCard("4111111111111111") - fmt.Println(res1) //true - - res2 := validator.IsCreditCard("123456") - fmt.Println(res2) //false -} -``` - - - - -### IsDns -验证字符串是否是有效dns
- -函数签名: - -```go -func IsDns(dns string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsDns("abc.com") - fmt.Println(res1) //true - - res2 := validator.IsDns("a.b.com") - fmt.Println(res2) //false - - res3 := validator.IsDns("http://abc.com") - fmt.Println(res3) //false -} -``` - - - - -### IsEmail -验证字符串是否是有效电子邮件地址
- -函数签名: - -```go -func IsEmail(email string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsEmail("abc@xyz.com") - fmt.Println(res1) //true - - res2 := validator.IsEmail("a.b@@com") - fmt.Println(res2) //false -} -``` - - - - - -### IsEmptyString -验证字符串是否是空字符串
- -函数签名: - -```go -func IsEmptyString(s string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - res1 := validator.IsEmptyString("") - fmt.Println(res1) //true - - res2 := validator.IsEmptyString("abc") - fmt.Println(res2) //false -} -``` - - - - -### IsFloatStr -验证字符串是否是可以转换为浮点数
- -函数签名: - -```go -func IsFloatStr(s string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsFloatStr("")) //false - fmt.Println(validator.IsFloatStr("12a")) //false - fmt.Println(validator.IsFloatStr("3.")) //true - fmt.Println(validator.IsFloatStr("+3.")) //true - fmt.Println(validator.IsFloatStr("-3.")) //true - fmt.Println(validator.IsFloatStr("12")) //true -} -``` - - - - -### IsNumberStr -验证字符串是否是可以转换为数字
- -函数签名: - -```go -func IsNumberStr(s string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsNumberStr("")) //false - fmt.Println(validator.IsNumberStr("12a")) //false - fmt.Println(validator.IsNumberStr("3.")) //true - fmt.Println(validator.IsNumberStr("+3.")) //true - fmt.Println(validator.IsNumberStr("-3.")) //true - fmt.Println(validator.IsNumberStr("+3e2")) //true -} -``` - - - - -### IsJSON -验证字符串是否是有效json
- -函数签名: - -```go -func IsJSON(str string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsJSON("")) //false - fmt.Println(validator.IsJSON("abc")) //false - fmt.Println(validator.IsJSON("{}")) //true - fmt.Println(validator.IsJSON("[]")) //true - fmt.Println(validator.IsJSON("123")) //true - fmt.Println(validator.IsJSON("{\"name\": \"test\"}")) //true -} -``` - - - - -### IsRegexMatch -验证字符串是否可以匹配正则表达式
- -函数签名: - -```go -func IsRegexMatch(s, regex string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsRegexMatch("abc", `^[a-zA-Z]+$`)) //true - fmt.Println(validator.IsRegexMatch("1ab", `^[a-zA-Z]+$`)) //false - fmt.Println(validator.IsRegexMatch("", `^[a-zA-Z]+$`)) //false -} -``` - - - - -### IsIntStr -验证字符串是否是可以转换为整数
- -函数签名: - -```go -func IsIntStr(s string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsIntStr("+3")) //true - fmt.Println(validator.IsIntStr("-3")) //true - fmt.Println(validator.IsIntStr("3.")) //false - fmt.Println(validator.IsIntStr("abc")) //false -} -``` - - - - -### IsIp -验证字符串是否是ip地址
- -函数签名: - -```go -func IsIp(ipstr string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsIp("127.0.0.1")) //true - fmt.Println(validator.IsIp("::0:0:0:0:0:0:1")) //true - fmt.Println(validator.IsIp("127.0.0")) //false - fmt.Println(validator.IsIp("127")) //false -} -``` - - - - -### IsIpV4 -验证字符串是否是ipv4地址
- -函数签名: - -```go -func IsIpV4(ipstr string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsIpV4("127.0.0.1")) //true - fmt.Println(validator.IsIpV4("::0:0:0:0:0:0:1")) //false - fmt.Println(validator.IsIpV4("127.0.0")) //false - fmt.Println(validator.IsIpV4("127")) //false -} -``` - - - - -### IsIpV6 -验证字符串是否是ipv6地址
- -函数签名: - -```go -func IsIpV6(ipstr string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsIpV6("127.0.0.1")) //false - fmt.Println(validator.IsIpV6("::0:0:0:0:0:0:1")) //true - fmt.Println(validator.IsIpV6("127.0.0")) //false - fmt.Println(validator.IsIpV6("127")) //false -} -``` - - - - -### IsStrongPassword -验证字符串是否是强密码:(alpha(lower+upper) + number + special chars(!@#$%^&*()?><))
- -函数签名: - -```go -func IsStrongPassword(password string, length int) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsStrongPassword("abc", 3)) //false - fmt.Println(validator.IsStrongPassword("abc123", 6)) //false - fmt.Println(validator.IsStrongPassword("abcABC", 6)) //false - fmt.Println(validator.IsStrongPassword("abcABC123@#$", 16)) //false - fmt.Println(validator.IsStrongPassword("abcABC123@#$", 12)) //true -} -``` - - - - -### IsUrl -验证字符串是否是url
- -函数签名: - -```go -func IsUrl(str string) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsUrl("http://abc.com")) //true - fmt.Println(validator.IsUrl("abc.com")) //true - fmt.Println(validator.IsUrl("a.b.com")) //true - fmt.Println(validator.IsUrl("abc")) //false -} -``` - - - - -### IsWeakPassword -验证字符串是否是弱密码:(only letter or only number or letter + number) -.
- -函数签名: - -```go -func IsWeakPassword(password string, length int) bool -``` -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsWeakPassword("abc")) //true - fmt.Println(validator.IsWeakPassword("123")) //true - fmt.Println(validator.IsWeakPassword("abc123")) //true - fmt.Println(validator.IsWeakPassword("abc123@#$")) //false -} -``` - - - - - - - - - diff --git a/eventbus/eventbus.go b/eventbus/eventbus.go new file mode 100644 index 00000000..8fe9b25d --- /dev/null +++ b/eventbus/eventbus.go @@ -0,0 +1,195 @@ +// Copyright 2025 dudaodong@gmail.com. All rights reserved. +// Use of this source code is governed by MIT license + +// Package eventbus implements a simple event bus. +package eventbus + +import ( + "fmt" + "sort" + "sync" +) + +// Event is the struct that is passed to the event listener, now it directly uses the generic Payload type. +type Event[T any] struct { + Topic string + Payload T +} + +// EventBus is the struct that holds the listeners and the error handler. +type EventBus[T any] struct { + // listeners map[string][]*EventListener[T] + listeners sync.Map + mu sync.RWMutex + errorHandler func(err error) +} + +// EventListener is the struct that holds the listener function and its priority. +type EventListener[T any] struct { + priority int + listener func(eventData T) + async bool + filter func(eventData T) bool +} + +// NewEventBus creates a new EventBus. +// Play: https://go.dev/play/p/gHbOPV_NUOJ +func NewEventBus[T any]() *EventBus[T] { + return &EventBus[T]{ + listeners: sync.Map{}, + } +} + +// Subscribe subscribes to an event with a specific event topic and listener function. +// Play: https://go.dev/play/p/EYGf_8cHei- +func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async bool, priority int, filter func(eventData T) bool) { + eb.mu.Lock() + defer eb.mu.Unlock() + + el := &EventListener[T]{ + priority: priority, + listener: listener, + async: async, + filter: filter, + } + + listenersInterface, _ := eb.listeners.LoadOrStore(topic, []*EventListener[T]{}) + listeners := listenersInterface.([]*EventListener[T]) + + listeners = append(listeners, el) + sort.Slice(listeners, func(i, j int) bool { + return listeners[i].priority > listeners[j].priority + }) + + eb.listeners.Store(topic, listeners) +} + +// Unsubscribe unsubscribes from an event with a specific event topic and listener function. +// Play: https://go.dev/play/p/Tmh7Ttfvprf +func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T)) { + eb.mu.Lock() + defer eb.mu.Unlock() + + listenersInterface, ok := eb.listeners.Load(topic) + if !ok { + return + } + + listeners := listenersInterface.([]*EventListener[T]) + listenerPtr := fmt.Sprintf("%p", listener) + + var updatedListeners []*EventListener[T] + for _, l := range listeners { + if fmt.Sprintf("%p", l.listener) != listenerPtr { + updatedListeners = append(updatedListeners, l) + } + } + + eb.listeners.Store(topic, updatedListeners) +} + +// Publish publishes an event with a specific event topic and data payload. +// Play: https://go.dev/play/p/gHTtVexFSH9 +func (eb *EventBus[T]) Publish(event Event[T]) { + eb.mu.RLock() + defer eb.mu.RUnlock() + + listenersInterface, exists := eb.listeners.Load(event.Topic) + if !exists { + return + } + + listeners := listenersInterface.([]*EventListener[T]) + + for _, listener := range listeners { + if listener.filter != nil && !listener.filter(event.Payload) { + continue + } + + if listener.async { + go eb.publishToListener(listener, event) + } else { + eb.publishToListener(listener, event) + } + } +} + +func (eb *EventBus[T]) publishToListener(listener *EventListener[T], event Event[T]) { + defer func() { + if r := recover(); r != nil && eb.errorHandler != nil { + eb.errorHandler(fmt.Errorf("%v", r)) + } + }() + + listener.listener(event.Payload) +} + +// SetErrorHandler sets the error handler function. +// Play: https://go.dev/play/p/gmB0gnFe5mc +func (eb *EventBus[T]) SetErrorHandler(handler func(err error)) { + eb.errorHandler = handler +} + +// ClearListeners clears all the listeners. +// Play: https://go.dev/play/p/KBfBYlKPgqD +func (eb *EventBus[T]) ClearListeners() { + eb.mu.Lock() + defer eb.mu.Unlock() + + eb.listeners = sync.Map{} +} + +// ClearListenersByTopic clears all the listeners by topic. +// Play: https://go.dev/play/p/gvMljmJOZmU +func (eb *EventBus[T]) ClearListenersByTopic(topic string) { + eb.mu.Lock() + defer eb.mu.Unlock() + + eb.listeners.Delete(topic) +} + +// GetListenersCount returns the number of listeners for a specific event topic. +// Play: https://go.dev/play/p/8VPJsMQgStM +func (eb *EventBus[T]) GetListenersCount(topic string) int { + eb.mu.RLock() + defer eb.mu.RUnlock() + + listenersInterface, ok := eb.listeners.Load(topic) + if !ok { + return 0 + } + + listeners := listenersInterface.([]*EventListener[T]) + return len(listeners) +} + +// GetAllListenersCount returns the total number of listeners. +// Play: https://go.dev/play/p/PUlr0xcpEOz +func (eb *EventBus[T]) GetAllListenersCount() int { + eb.mu.RLock() + defer eb.mu.RUnlock() + + count := 0 + eb.listeners.Range(func(key, value interface{}) bool { + count += len(value.([]*EventListener[T])) + return true + }) + + return count +} + +// GetEvents returns all the events topics. +// Play: https://go.dev/play/p/etgjjcOtAjX +func (eb *EventBus[T]) GetEvents() []string { + eb.mu.RLock() + defer eb.mu.RUnlock() + + var events []string + + eb.listeners.Range(func(key, value interface{}) bool { + events = append(events, key.(string)) + return true + }) + + return events +} diff --git a/eventbus/eventbus_example_test.go b/eventbus/eventbus_example_test.go new file mode 100644 index 00000000..cac6d8c2 --- /dev/null +++ b/eventbus/eventbus_example_test.go @@ -0,0 +1,237 @@ +package eventbus + +import ( + "fmt" + "sort" + "sync" + "time" +) + +func ExampleEventBus_Subscribe() { + eb := NewEventBus[string]() + eb.Subscribe("event1", func(eventData string) { + fmt.Println(eventData) + }, false, 0, nil) + + eb.Publish(Event[string]{Topic: "event1", Payload: "hello"}) + + // Output: + // hello +} + +func ExampleEventBus_Unsubscribe() { + eb := NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Unsubscribe("event1", listener) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 0 +} + +func ExampleEventBus_Subscribe_withFilter() { + eb := NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + filter := func(eventData int) bool { + return eventData == 1 + } + + eb.Subscribe("event1", listener, false, 0, filter) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(Event[int]{Topic: "event1", Payload: 2}) + + fmt.Println(receivedData) + + // Output: + // 1 +} + +func ExampleEventBus_Subscribe_withPriority() { + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) { + fmt.Println(eventData) + }, false, 0, nil) + + eb.Subscribe("event1", func(eventData int) { + fmt.Println(eventData) + }, false, 1, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // 1 + // 1 +} + +func ExampleEventBus_Subscribe_async() { + eb := NewEventBus[int]() + + var wg sync.WaitGroup + wg.Add(1) + + eb.Subscribe("event1", func(eventData int) { + time.Sleep(100 * time.Millisecond) + fmt.Println(eventData) + wg.Done() + }, true, 1, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + wg.Wait() + + // Output: + // 1 +} + +func ExampleEventBus_Publish() { + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) { + fmt.Println(eventData) + }, false, 0, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // 1 +} + +func ExampleEventBus() { + eb := NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 1 +} + +func ExampleEventBus_ClearListeners() { + eb := NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Subscribe("event2", listener, false, 0, nil) + + eb.ClearListeners() + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(Event[int]{Topic: "event2", Payload: 2}) + + fmt.Println(receivedData) + + // Output: + // 0 +} + +func ExampleEventBus_ClearListenersByTopic() { + eb := NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Subscribe("event2", listener, false, 0, nil) + + eb.ClearListenersByTopic("event1") + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(Event[int]{Topic: "event2", Payload: 2}) + + fmt.Println(receivedData) + + // Output: + // 2 +} + +func ExampleEventBus_GetListenersCount() { + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + count := eb.GetListenersCount("event1") + + fmt.Println(count) + + // Output: + // 1 +} + +func ExampleEventBus_SetErrorHandler() { + eb := NewEventBus[int]() + + eb.SetErrorHandler(func(err error) { + fmt.Println(err) + }) + + eb.Subscribe("event1", func(eventData int) { + panic("error") + }, false, 0, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // error +} + +func ExampleEventBus_GetAllListenersCount() { + + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + count := eb.GetAllListenersCount() + + fmt.Println(count) + + // Output: + // 2 +} + +func ExampleEventBus_GetEvents() { + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + events := eb.GetEvents() + sort.Strings(events) + + for _, event := range events { + fmt.Println(event) + } + + // Output: + // event1 + // event2 +} diff --git a/eventbus/eventbus_test.go b/eventbus/eventbus_test.go new file mode 100644 index 00000000..dc90ca4f --- /dev/null +++ b/eventbus/eventbus_test.go @@ -0,0 +1,221 @@ +package eventbus + +import ( + "sort" + "sync" + "testing" + "time" + + "github.com/duke-git/lancet/v2/internal" +) + +func TestEventBus_Subscribe(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestEventBus_Subscribe") + + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) { + assert.Equal(1, eventData) + }, false, 0, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) +} + +func TestEventBus_Unsubscribe(t *testing.T) { + + t.Parallel() + assert := internal.NewAssert(t, "TestEventBus_Unsubscribe") + + eb := NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Unsubscribe("event1", listener) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + assert.Equal(0, receivedData) +} + +func TestEventBus_Subscribe_withFilter(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestEventBus_Subscribe_withFilter") + + eb := NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + filter := func(eventData int) bool { + return eventData == 1 + } + + eb.Subscribe("event1", listener, false, 0, filter) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(Event[int]{Topic: "event1", Payload: 2}) + + assert.Equal(1, receivedData) +} + +func TestEventBus_Subscribe_withPriority(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestEventBus_Subscribe_withPriority") + + eb := NewEventBus[int]() + + var receivedData []int + listener1 := func(eventData int) { + receivedData = append(receivedData, 1) + } + + listener2 := func(eventData int) { + receivedData = append(receivedData, 2) + } + + eb.Subscribe("event1", listener1, false, 1, nil) + eb.Subscribe("event1", listener2, false, 2, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + assert.Equal([]int{2, 1}, receivedData) +} + +func TestEventBus_Subscribe_async(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestEventBus_Subscribe_async") + + eb := NewEventBus[string]() + + var wg sync.WaitGroup + wg.Add(1) + + eb.Subscribe("event1", func(eventData string) { + time.Sleep(100 * time.Millisecond) + assert.Equal("hello", eventData) + wg.Done() + }, true, 1, nil) + + eb.Publish(Event[string]{Topic: "event1", Payload: "hello"}) + + wg.Wait() +} + +func TestEventBus_ErrorHandler(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestEventBus_ErrorHandler") + + eb := NewEventBus[string]() + + eb.SetErrorHandler(func(err error) { + assert.Equal("error", err.Error()) + }) + + eb.Subscribe("event1", func(eventData string) { + panic("error") + }, false, 0, nil) + + eb.Publish(Event[string]{Topic: "event1", Payload: "hello"}) +} + +func TestEventBus_ClearListeners(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestEventBus_ClearListeners") + + eb := NewEventBus[int]() + + receivedData1 := 0 + receivedData2 := 0 + + eb.Subscribe("event1", func(eventData int) { + receivedData1 = eventData + }, false, 0, nil) + + eb.Subscribe("event2", func(eventData int) { + receivedData2 = eventData + }, false, 0, nil) + + eb.ClearListeners() + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(Event[int]{Topic: "event1", Payload: 2}) + + assert.Equal(0, receivedData1) + assert.Equal(0, receivedData2) +} + +func TestEventBus_ClearListenersByTopic(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestEventBus_ClearListenersByTopic") + + eb := NewEventBus[int]() + + receivedData1 := 0 + receivedData2 := 0 + + eb.Subscribe("event1", func(eventData int) { + receivedData1 = eventData + }, false, 0, nil) + + eb.Subscribe("event2", func(eventData int) { + receivedData2 = eventData + }, false, 0, nil) + + eb.ClearListenersByTopic("event1") + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(Event[int]{Topic: "event2", Payload: 2}) + + assert.Equal(0, receivedData1) + assert.Equal(2, receivedData2) +} + +func TestEventBus_GetListenersCount(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestEventBus_GetListenersCount") + + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + assert.Equal(2, eb.GetListenersCount("event1")) + assert.Equal(1, eb.GetListenersCount("event2")) +} + +func TestEventBus_GetAllListenersCount(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestEventBus_GetAllListenersCount") + + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + assert.Equal(3, eb.GetAllListenersCount()) +} + +func TestEventBus_GetEvents(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestEventBus_GetEvents") + + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + events := eb.GetEvents() + sort.Strings(events) + + assert.Equal(2, len(events)) + assert.Equal([]string{"event1", "event2"}, events) +} diff --git a/fileutil/file.go b/fileutil/file.go index 11812a4b..a050fa72 100644 --- a/fileutil/file.go +++ b/fileutil/file.go @@ -7,17 +7,85 @@ package fileutil import ( "archive/zip" "bufio" + "bytes" + "crypto/sha1" + "crypto/sha256" + "crypto/sha512" + "encoding/csv" "errors" + "fmt" "io" "io/fs" - "io/ioutil" "net/http" "os" "path/filepath" + "runtime" + "sort" "strings" + "sync" + + "github.com/duke-git/lancet/v2/validator" + "golang.org/x/text/encoding/simplifiedchinese" + "golang.org/x/text/transform" ) -// IsExist checks if a file or directory exists +// FileReader is a reader supporting offset seeking and reading one +// line at a time, this is especially useful for large files +type FileReader struct { + *bufio.Reader + file *os.File + offset int64 +} + +// NewFileReader creates the FileReader struct for reading +func NewFileReader(path string) (*FileReader, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + return &FileReader{ + file: f, + Reader: bufio.NewReader(f), + offset: 0, + }, nil +} + +// ReadLine reads and returns one line at a time excluding the trailing '\r' and '\n' +func (f *FileReader) ReadLine() (string, error) { + data, err := f.Reader.ReadBytes('\n') + f.offset += int64(len(data)) + if err == nil || err == io.EOF { + for len(data) > 0 && (data[len(data)-1] == '\r' || data[len(data)-1] == '\n') { + data = data[:len(data)-1] + } + return string(data), err + } + return "", err +} + +// Offset returns the current offset of the file +func (f *FileReader) Offset() int64 { + return f.offset +} + +// SeekOffset sets the current offset of the reading +func (f *FileReader) SeekOffset(offset int64) error { + _, err := f.file.Seek(offset, 0) + if err != nil { + return err + } + f.Reader = bufio.NewReader(f.file) + f.offset = offset + return nil +} + +// Close takes care of the opened file +func (f *FileReader) Close() error { + return f.file.Close() +} + +// IsExist checks if a file or directory exists. +// Play: https://go.dev/play/p/nKKXt8ZQbmh func IsExist(path string) bool { _, err := os.Stat(path) if err == nil { @@ -29,7 +97,8 @@ func IsExist(path string) bool { return false } -// CreateFile create a file in path +// CreateFile create a file in path. +// Play: https://go.dev/play/p/lDt8PEsTNKI func CreateFile(path string) bool { file, err := os.Create(path) if err != nil { @@ -40,7 +109,59 @@ func CreateFile(path string) bool { return true } -// IsDir checks if the path is directory or not +// CreateDir create directory in absolute path. param `absPath` like /a/, /a/b/. +// Play: https://go.dev/play/p/qUuCe1OGQnM +func CreateDir(absPath string) error { + // return os.MkdirAll(path.Dir(absPath), os.ModePerm) + return os.MkdirAll(absPath, os.ModePerm) +} + +// CopyDir copy src directory to dst directory, it will copy all files and directories recursively. +// the access permission will be the same as the source directory. +// if dstPath exists, it will return an error. +// Play: https://go.dev/play/p/YAyFTA_UuPb +func CopyDir(srcPath string, dstPath string) error { + srcInfo, err := os.Stat(srcPath) + if err != nil { + return fmt.Errorf("failed to get source directory info: %w", err) + } + + if !srcInfo.IsDir() { + return fmt.Errorf("source path is not a directory: %s", srcPath) + } + + err = os.MkdirAll(dstPath, 0755) + if err != nil { + return fmt.Errorf("failed to create destination directory: %w", err) + } + + entries, err := os.ReadDir(srcPath) + if err != nil { + return fmt.Errorf("failed to read source directory: %w", err) + } + + for _, entry := range entries { + srcDir := filepath.Join(srcPath, entry.Name()) + dstDir := filepath.Join(dstPath, entry.Name()) + + if entry.IsDir() { + err := CopyDir(srcDir, dstDir) + if err != nil { + return err + } + } else { + err := CopyFile(srcDir, dstDir) + if err != nil { + return err + } + } + } + + return nil +} + +// IsDir checks if the path is directory or not. +// Play: https://go.dev/play/p/WkVwEKqtOWk func IsDir(path string) bool { file, err := os.Stat(path) if err != nil { @@ -49,20 +170,66 @@ func IsDir(path string) bool { return file.IsDir() } -// RemoveFile remove the path file -func RemoveFile(path string) error { +// RemoveFile remove the path file. +// Play: https://go.dev/play/p/P2y0XW8a1SH +func RemoveFile(path string, onDelete ...func(path string)) error { + info, err := os.Stat(path) + if err != nil { + return err + } + + if info.IsDir() { + return fmt.Errorf("%s is a directory", path) + } + + if len(onDelete) > 0 && onDelete[0] != nil { + onDelete[0](path) + } + return os.Remove(path) } -// CopyFile copy src file to dest file -func CopyFile(srcFilePath string, dstFilePath string) error { - srcFile, err := os.Open(srcFilePath) +// RemoveDir remove the path directory. +// Play: https://go.dev/play/p/Oa6KnPek2uy +func RemoveDir(path string, onDelete ...func(path string)) error { + info, err := os.Stat(path) + if err != nil { + return err + } + + if !info.IsDir() { + return fmt.Errorf("%s is not a directory", path) + } + + var callback func(string) + if len(onDelete) > 0 { + callback = onDelete[0] + } + + err = filepath.Walk(path, func(p string, info os.FileInfo, err error) error { + if err == nil && callback != nil { + callback(p) + } + return nil + }) + + if err != nil { + return err + } + + return os.RemoveAll(path) +} + +// CopyFile copy src file to dest file. +// Play: https://go.dev/play/p/Jg9AMJMLrJi +func CopyFile(srcPath string, dstPath string) error { + srcFile, err := os.Open(srcPath) if err != nil { return err } defer srcFile.Close() - distFile, err := os.Create(dstFilePath) + distFile, err := os.Create(dstPath) if err != nil { return err } @@ -71,17 +238,21 @@ func CopyFile(srcFilePath string, dstFilePath string) error { var tmp = make([]byte, 1024*4) for { n, err := srcFile.Read(tmp) - distFile.Write(tmp[:n]) if err != nil { if err == io.EOF { return nil } return err } + _, err = distFile.Write(tmp[:n]) + if err != nil { + return err + } } } -//ClearFile write empty string to path file +// ClearFile write empty string to path file. +// Play: https://go.dev/play/p/NRZ0ZT-G94H func ClearFile(path string) error { f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) if err != nil { @@ -93,16 +264,18 @@ func ClearFile(path string) error { return err } -//ReadFileToString return string of file content +// ReadFileToString return string of file content. +// Play: https://go.dev/play/p/cmfwp_5SQTp func ReadFileToString(path string) (string, error) { - bytes, err := ioutil.ReadFile(path) + bytes, err := os.ReadFile(path) if err != nil { return "", err } return string(bytes), nil } -// ReadFileByLine read file line by line +// ReadFileByLine read file line by line. +// Play: https://go.dev/play/p/svJP_7ZrBrD func ReadFileByLine(path string) ([]string, error) { f, err := os.Open(path) if err != nil { @@ -110,7 +283,7 @@ func ReadFileByLine(path string) ([]string, error) { } defer f.Close() - res := make([]string, 0) + result := make([]string, 0) buf := bufio.NewReader(f) for { @@ -122,19 +295,20 @@ func ReadFileByLine(path string) ([]string, error) { if err != nil { continue } - res = append(res, l) + result = append(result, l) } - return res, nil + return result, nil } -// ListFileNames return all file names in the path +// ListFileNames return all file names in the path. +// Play: https://go.dev/play/p/Tjd7Y07rejl func ListFileNames(path string) ([]string, error) { if !IsExist(path) { return []string{}, nil } - fs, err := ioutil.ReadDir(path) + fs, err := os.ReadDir(path) if err != nil { return []string{}, err } @@ -144,18 +318,44 @@ func ListFileNames(path string) ([]string, error) { return []string{}, nil } - res := []string{} + result := []string{} for i := 0; i < sz; i++ { if !fs[i].IsDir() { - res = append(res, fs[i].Name()) + result = append(result, fs[i].Name()) } } - return res, nil + return result, nil } -// Zip create zip file, fpath could be a single file or a directory -func Zip(fpath string, destPath string) error { +// IsZipFile checks if file is zip or not. +// Play: https://go.dev/play/p/9M0g2j_uF_e +func IsZipFile(filepath string) bool { + f, err := os.Open(filepath) + if err != nil { + return false + } + defer f.Close() + + buf := make([]byte, 4) + if n, err := f.Read(buf); err != nil || n < 4 { + return false + } + + return bytes.Equal(buf, []byte("PK\x03\x04")) +} + +// Zip create zip file, fpath could be a single file or a directory. +// Play: https://go.dev/play/p/j-3sWBp8ik_P +func Zip(path string, destPath string) error { + if IsDir(path) { + return zipFolder(path, destPath) + } + + return zipFile(path, destPath) +} + +func zipFile(filePath string, destPath string) error { zipFile, err := os.Create(destPath) if err != nil { return err @@ -165,7 +365,33 @@ func Zip(fpath string, destPath string) error { archive := zip.NewWriter(zipFile) defer archive.Close() - filepath.Walk(fpath, func(path string, info os.FileInfo, err error) error { + return addFileToArchive1(filePath, archive) +} + +func zipFolder(folderPath string, destPath string) error { + outFile, err := os.Create(destPath) + if err != nil { + return err + } + defer outFile.Close() + + w := zip.NewWriter(outFile) + + err = addFileToArchive2(w, folderPath, "") + if err != nil { + return err + } + + err = w.Close() + if err != nil { + return err + } + + return nil +} + +func addFileToArchive1(fpath string, archive *zip.Writer) error { + err := filepath.Walk(fpath, func(path string, info os.FileInfo, err error) error { if err != nil { return err } @@ -181,31 +407,59 @@ func Zip(fpath string, destPath string) error { header.Name += "/" } else { header.Method = zip.Deflate - } - - writer, err := archive.CreateHeader(header) - if err != nil { - return err - } - - if !info.IsDir() { + writer, err := archive.CreateHeader(header) + if err != nil { + return err + } file, err := os.Open(path) if err != nil { return err } defer file.Close() - _, err = io.Copy(writer, file) - if err != nil { + if _, err := io.Copy(writer, file); err != nil { return err } } return nil }) + return err +} + +func addFileToArchive2(w *zip.Writer, basePath, baseInZip string) error { + files, err := os.ReadDir(basePath) + if err != nil { + return err + } + if !strings.HasSuffix(basePath, "/") { + basePath = basePath + "/" + } + + for _, file := range files { + if !file.IsDir() { + dat, err := os.ReadFile(basePath + file.Name()) + if err != nil { + return err + } + + f, err := w.Create(baseInZip + file.Name()) + if err != nil { + return err + } + _, err = f.Write(dat) + if err != nil { + return err + } + } else if file.IsDir() { + newBase := basePath + file.Name() + "/" + addFileToArchive2(w, newBase, baseInZip+file.Name()+"/") + } + } return nil } -// UnZip unzip the file and save it to destPath +// UnZip unzip the file and save it to destPath. +// Play: https://go.dev/play/p/g0w34kS7B8m func UnZip(zipFile string, destPath string) error { zipReader, err := zip.OpenReader(zipFile) if err != nil { @@ -214,11 +468,27 @@ func UnZip(zipFile string, destPath string) error { defer zipReader.Close() for _, f := range zipReader.File { - path := filepath.Join(destPath, f.Name) + decodeName := f.Name + if f.Flags == 0 { + i := bytes.NewReader([]byte(f.Name)) + decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder()) + content, _ := io.ReadAll(decoder) + decodeName = string(content) + } + // issue#62: fix ZipSlip bug + path, err := safeFilepathJoin(destPath, decodeName) + if err != nil { + return err + } + if f.FileInfo().IsDir() { - os.MkdirAll(path, os.ModePerm) + err = os.MkdirAll(path, os.ModePerm) + if err != nil { + return err + } } else { - if err = os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil { + err = os.MkdirAll(filepath.Dir(path), os.ModePerm) + if err != nil { return err } @@ -240,10 +510,81 @@ func UnZip(zipFile string, destPath string) error { } } } + return nil } -// IsLink checks if a file is symbol link or not +// ZipAppendEntry append a single file or directory by fpath to an existing zip file. +// Play: https://go.dev/play/p/cxvaT8TRNQp +func ZipAppendEntry(fpath string, destPath string) error { + tempFile, err := os.CreateTemp("", "temp.zip") + if err != nil { + return err + } + defer os.Remove(tempFile.Name()) + + zipReader, err := zip.OpenReader(destPath) + if err != nil { + return err + } + + archive := zip.NewWriter(tempFile) + + for _, zipItem := range zipReader.File { + zipItemReader, err := zipItem.Open() + if err != nil { + return err + } + header, err := zip.FileInfoHeader(zipItem.FileInfo()) + if err != nil { + return err + } + header.Name = zipItem.Name + targetItem, err := archive.CreateHeader(header) + if err != nil { + return err + } + _, err = io.Copy(targetItem, zipItemReader) + if err != nil { + return err + } + } + + err = addFileToArchive1(fpath, archive) + + if err != nil { + return err + } + + err = zipReader.Close() + if err != nil { + return err + } + err = archive.Close() + if err != nil { + return err + } + err = tempFile.Close() + if err != nil { + return err + } + + return CopyFile(tempFile.Name(), destPath) +} + +func safeFilepathJoin(path1, path2 string) (string, error) { + relPath, err := filepath.Rel(".", path2) + if err != nil || strings.HasPrefix(relPath, "..") { + return "", fmt.Errorf("(zipslip) filepath is unsafe %q: %v", path2, err) + } + if path1 == "" { + path1 = "." + } + return filepath.Join(path1, filepath.Join("/", relPath)), nil +} + +// IsLink checks if a file is symbol link or not. +// Play: https://go.dev/play/p/TL-b-Kzvf44 func IsLink(path string) bool { fi, err := os.Lstat(path) if err != nil { @@ -252,7 +593,8 @@ func IsLink(path string) bool { return fi.Mode()&os.ModeSymlink != 0 } -// FileMode return file's mode and permission +// FileMode return file's mode and permission. +// Play: https://go.dev/play/p/2l2hI42fA3p func FileMode(path string) (fs.FileMode, error) { fi, err := os.Lstat(path) if err != nil { @@ -262,8 +604,9 @@ func FileMode(path string) (fs.FileMode, error) { } // MiMeType return file mime type -// param `file` should be string(file path) or *os.File -func MiMeType(file interface{}) string { +// param `file` should be string(file path) or *os.File. +// Play: https://go.dev/play/p/bd5sevSUZNu +func MiMeType(file any) string { var mediatype string readBuffer := func(f *os.File) ([]byte, error) { @@ -296,3 +639,365 @@ func MiMeType(file interface{}) string { } return mediatype } + +// CurrentPath return current absolute path. +// Play: https://go.dev/play/p/s74a9iBGcSw +func CurrentPath() string { + var absPath string + _, filename, _, ok := runtime.Caller(1) + if ok { + absPath = filepath.Dir(filename) + } + + return absPath +} + +// FileSize returns file size in bytes. +// Play: https://go.dev/play/p/H9Z05uD-Jjc +func FileSize(path string) (int64, error) { + f, err := os.Stat(path) + if err != nil { + return 0, err + } + return f.Size(), nil +} + +// DirSize walks the folder recursively and returns folder size in bytes. +func DirSize(path string) (int64, error) { + var size int64 + err := filepath.WalkDir(path, func(_ string, d os.DirEntry, err error) error { + if err != nil { + return err + } + if !d.IsDir() { + info, err := d.Info() + if err != nil { + return err + } + size += info.Size() + } + return err + }) + return size, err +} + +// MTime returns file modified time. +// Play: https://go.dev/play/p/s_Tl7lZoAaY +func MTime(filepath string) (int64, error) { + f, err := os.Stat(filepath) + if err != nil { + return 0, err + } + return f.ModTime().Unix(), nil +} + +// Sha returns file sha value, param `shaType` should be 1, 256 or 512. +// Play: https://go.dev/play/p/VfEEcO2MJYf +func Sha(filepath string, shaType ...int) (string, error) { + file, err := os.Open(filepath) + if err != nil { + return "", err + } + defer file.Close() + + h := sha1.New() + if len(shaType) > 0 { + if shaType[0] == 1 { + h = sha1.New() + } else if shaType[0] == 256 { + h = sha256.New() + } else if shaType[0] == 512 { + h = sha512.New() + } else { + return "", errors.New("param `shaType` should be 1, 256 or 512") + } + } + + _, err = io.Copy(h, file) + + if err != nil { + return "", err + } + + sha := fmt.Sprintf("%x", h.Sum(nil)) + + return sha, nil + +} + +// ReadCsvFile read file content into slice. +// Play: https://go.dev/play/p/OExTkhGEd3_u +func ReadCsvFile(filepath string, delimiter ...rune) ([][]string, error) { + f, err := os.Open(filepath) + if err != nil { + return nil, err + } + defer f.Close() + + reader := csv.NewReader(f) + if len(delimiter) > 0 { + reader.Comma = delimiter[0] + } + + records, err := reader.ReadAll() + if err != nil { + return nil, err + } + + return records, nil +} + +// WriteCsvFile write content to target csv file. +// append: append to existing csv file +// delimiter: specifies csv delimiter +// Play: https://go.dev/play/p/dAXm58Q5U1o +func WriteCsvFile(filepath string, records [][]string, append bool, delimiter ...rune) error { + flag := os.O_RDWR | os.O_CREATE + + if append { + flag = flag | os.O_APPEND + } + + f, err := os.OpenFile(filepath, flag, 0644) + if err != nil { + return err + } + + defer f.Close() + + writer := csv.NewWriter(f) + // 设置默认分隔符为逗号,除非另外指定 + if len(delimiter) > 0 { + writer.Comma = delimiter[0] + } else { + writer.Comma = ',' + } + + // 遍历所有记录并处理包含分隔符或双引号的单元格 + for i := range records { + for j := range records[i] { + records[i][j] = escapeCSVField(records[i][j], writer.Comma) + } + } + + return writer.WriteAll(records) +} + +// WriteStringToFile write string to target file. +// Play: https://go.dev/play/p/GhLS6d8lH_g +func WriteStringToFile(filepath string, content string, append bool) error { + var flag int + if append { + flag = os.O_RDWR | os.O_CREATE | os.O_APPEND + } else { + flag = os.O_RDWR | os.O_CREATE | os.O_TRUNC + } + + f, err := os.OpenFile(filepath, flag, 0644) + if err != nil { + return err + } + defer f.Close() + + _, err = f.WriteString(content) + return err +} + +// WriteBytesToFile write bytes to target file. +// Play: https://go.dev/play/p/s7QlDxMj3P8 +func WriteBytesToFile(filepath string, content []byte) error { + f, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return err + } + + defer f.Close() + + _, err = f.Write(content) + return err +} + +// ReadFile get file reader by a url or a local file +// Play: https://go.dev/play/p/uNep3Tr8fqF +func ReadFile(path string) (reader io.ReadCloser, closeFn func(), err error) { + switch { + case validator.IsUrl(path): + resp, err := http.Get(path) + if err != nil { + return nil, func() {}, err + } + return resp.Body, func() { resp.Body.Close() }, nil + case IsExist(path): + reader, err := os.Open(path) + if err != nil { + return nil, func() {}, err + } + return reader, func() { reader.Close() }, nil + default: + return nil, func() {}, errors.New("unknown file type") + } +} + +// escapeCSVField 处理单元格内容,如果包含分隔符,则用双引号包裹 +func escapeCSVField(field string, delimiter rune) string { + // 替换所有的双引号为两个双引号 + escapedField := strings.ReplaceAll(field, "\"", "\"\"") + + // 如果字段包含分隔符、双引号或换行符,用双引号包裹整个字段 + if strings.ContainsAny(escapedField, string(delimiter)+"\"\n") { + escapedField = fmt.Sprintf("\"%s\"", escapedField) + } + + return escapedField +} + +// WriteMapsToCsv write slice of map to csv file. +// Play: https://go.dev/play/p/umAIomZFV1c +// filepath: Path to the CSV file. +// records: Slice of maps to be written. the value of map should be basic type. +// the maps will be sorted by key in alphabeta order, then be written into csv file. +// appendToExistingFile: If true, data will be appended to the file if it exists. +// delimiter: Delimiter to use in the CSV file. +// headers: order of the csv column headers, needs to be consistent with the key of the map. +func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune, + headers ...[]string) error { + for _, record := range records { + for _, value := range record { + if !isCsvSupportedType(value) { + return errors.New("unsupported value type detected; only basic types are supported: \nbool, rune, string, int, int64, float32, float64, uint, byte, complex128, complex64, uintptr") + } + } + } + + var columnHeaders []string + if len(headers) > 0 { + columnHeaders = headers[0] + } else { + columnHeaders = make([]string, 0, len(records[0])) + for key := range records[0] { + columnHeaders = append(columnHeaders, key) + } + // sort keys in alphabeta order + sort.Strings(columnHeaders) + } + + var datasToWrite [][]string + if !appendToExistingFile { + datasToWrite = append(datasToWrite, columnHeaders) + } + + for _, record := range records { + row := make([]string, 0, len(columnHeaders)) + for _, h := range columnHeaders { + row = append(row, fmt.Sprintf("%v", record[h])) + } + datasToWrite = append(datasToWrite, row) + } + + return WriteCsvFile(filepath, datasToWrite, appendToExistingFile, delimiter) +} + +// check if the value of map which to be written into csv is basic type. +func isCsvSupportedType(v interface{}) bool { + switch v.(type) { + case bool, rune, string, int, int64, float32, float64, uint, byte, complex128, complex64, uintptr: + return true + default: + return false + } +} + +// ChunkRead reads a block from the file at the specified offset and returns all lines within the block +// Play: https://go.dev/play/p/r0hPmKWhsgf +func ChunkRead(file *os.File, offset int64, size int, bufPool *sync.Pool) ([]string, error) { + buf := bufPool.Get().([]byte)[:size] // 从Pool获取缓冲区并调整大小 + n, err := file.ReadAt(buf, offset) // 从指定偏移读取数据到缓冲区 + if err != nil && err != io.EOF { + return nil, err + } + buf = buf[:n] // 调整切片以匹配实际读取的字节数 + + var lines []string + var lineStart int + for i, b := range buf { + if b == '\n' { + line := string(buf[lineStart:i]) // 不包括换行符 + lines = append(lines, line) + lineStart = i + 1 // 设置下一行的开始 + } + } + + if lineStart < len(buf) { // 处理块末尾的行 + line := string(buf[lineStart:]) + lines = append(lines, line) + } + bufPool.Put(buf) // 读取完成后,将缓冲区放回Pool + return lines, nil +} + +// ParallelChunkRead reads the file in parallel and send each chunk of lines to the specified channel. +// filePath 文件路径 +// chunkSizeMB 分块的大小(单位MB,设置为0时使用默认100MB),设置过大反而不利,视情调整 +// maxGoroutine 并发读取分块的数量,设置为0时使用CPU核心数 +// linesCh用于接收返回结果的通道。 +// Play: https://go.dev/play/p/teMXnCsdSEw +func ParallelChunkRead(filePath string, linesCh chan<- []string, chunkSizeMB, maxGoroutine int) error { + if chunkSizeMB == 0 { + chunkSizeMB = 100 + } + chunkSize := chunkSizeMB * 1024 * 1024 + // 内存复用 + bufPool := sync.Pool{ + New: func() interface{} { + return make([]byte, 0, chunkSize) + }, + } + + if maxGoroutine == 0 { + maxGoroutine = runtime.NumCPU() // 设置为0时使用CPU核心数 + } + + f, err := os.Open(filePath) + if err != nil { + return err + } + + defer f.Close() + + info, err := f.Stat() + if err != nil { + return err + } + + wg := sync.WaitGroup{} + chunkOffsetCh := make(chan int64, maxGoroutine) + + // 分配工作 + go func() { + for i := int64(0); i < info.Size(); i += int64(chunkSize) { + chunkOffsetCh <- i + } + close(chunkOffsetCh) + }() + + // 启动工作协程 + for i := 0; i < maxGoroutine; i++ { + wg.Add(1) + go func() { + for chunkOffset := range chunkOffsetCh { + chunk, err := ChunkRead(f, chunkOffset, chunkSize, &bufPool) + if err == nil { + linesCh <- chunk + } + + } + wg.Done() + }() + } + + // 等待所有解析完成后关闭行通道 + wg.Wait() + close(linesCh) + + return nil +} diff --git a/fileutil/file_example_test.go b/fileutil/file_example_test.go new file mode 100644 index 00000000..1d53a4c3 --- /dev/null +++ b/fileutil/file_example_test.go @@ -0,0 +1,508 @@ +package fileutil + +import ( + "fmt" + "io" + "log" + "os" + "runtime" + "sync" +) + +func ExampleIsExist() { + + result1 := IsExist("./") + result2 := IsExist("./xxx.go") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} + +func ExampleCreateFile() { + fname := "./a.txt" + + result1 := IsExist(fname) + + CreateFile(fname) + + result2 := IsExist(fname) + + os.Remove(fname) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // false + // true +} + +func ExampleCreateDir() { + pwd, _ := os.Getwd() + dirPath := pwd + "/createdir/a/b" + + result1 := IsExist(dirPath) + + err := CreateDir(dirPath) + if err != nil { + return + } + + result2 := IsExist(pwd + "/createdir/") + result3 := IsExist(pwd + "/createdir/a") + result4 := IsExist(pwd + "/createdir/a/b") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + os.RemoveAll(pwd + "/createdir/") + + // Output: + // false + // true + // true + // true +} + +func ExampleIsDir() { + + result1 := IsDir("./") + result2 := IsDir("./xxx.go") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} + +func ExampleRemoveFile() { + srcFile := "./text.txt" + CreateFile(srcFile) + + copyFile := "./text_copy.txt" + err := CopyFile(srcFile, copyFile) + if err != nil { + return + } + file, err := os.Open(copyFile) + if err != nil { + return + } + result1 := IsExist(copyFile) + result2 := file.Name() + + os.Remove(srcFile) + os.Remove(copyFile) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // ./text_copy.txt +} + +func ExampleReadFileToString() { + fname := "./test.txt" + CreateFile(fname) + + f, _ := os.OpenFile(fname, os.O_WRONLY|os.O_TRUNC, 0777) + defer f.Close() + + _, err := f.WriteString("hello world") + if err != nil { + return + } + + content, _ := ReadFileToString(fname) + + os.Remove(fname) + + fmt.Println(content) + + // Output: + // hello world +} + +func ExampleClearFile() { + fname := "./test.txt" + CreateFile(fname) + + f, _ := os.OpenFile(fname, os.O_WRONLY|os.O_TRUNC, 0777) + defer f.Close() + + _, err := f.WriteString("hello world") + if err != nil { + return + } + + content1, _ := ReadFileToString(fname) + + err = ClearFile(fname) + if err != nil { + return + } + content2, _ := ReadFileToString(fname) + + os.Remove(fname) + + fmt.Println(content1) + fmt.Println(content2) + + // Output: + // hello world + // +} + +func ExampleReadFileByLine() { + fname := "./test.txt" + CreateFile(fname) + + f, _ := os.OpenFile(fname, os.O_WRONLY|os.O_TRUNC, 0777) + defer f.Close() + + _, err := f.WriteString("hello\nworld") + if err != nil { + return + } + + content, _ := ReadFileByLine(fname) + + os.Remove(fname) + + fmt.Println(content) + + // Output: + // [hello world] +} + +func ExampleListFileNames() { + fileList, _ := ListFileNames("../internal") + fmt.Println(fileList) + + // Output: + // [assert.go assert_test.go error_join.go] +} + +func ExampleMiMeType() { + fname := "./test.txt" + file, _ := os.Create(fname) + + _, err := file.WriteString("hello\nworld") + if err != nil { + return + } + + f, _ := os.Open(fname) + defer f.Close() + + mimeType := MiMeType(f) + fmt.Println(mimeType) + + os.Remove(fname) + + // Output: + // application/octet-stream +} + +func ExampleZip() { + srcFile := "./test.txt" + CreateFile(srcFile) + + zipFile := "./test.zip" + err := Zip(srcFile, zipFile) + if err != nil { + return + } + + result := IsExist(zipFile) + + os.Remove(srcFile) + os.Remove(zipFile) + + fmt.Println(result) + + // Output: + // true +} + +func ExampleUnZip() { + zipFile := "./testdata/file.go.zip" + + err := UnZip(zipFile, "./testdata") + if err != nil { + return + } + + exist := IsExist("./testdata/file.go") + fmt.Println(exist) + + os.Remove("./testdata/file.go") + + // Output: + // true +} + +func ExampleZipAppendEntry() { + zipFile := "./test.zip" + CopyFile("./testdata/file.go.zip", zipFile) + + ZipAppendEntry("./testdata", zipFile) + + unZipPath := "./unzip" + UnZip(zipFile, unZipPath) + + fmt.Println(IsExist("./unzip/file.go")) + fmt.Println(IsExist("./unzip/testdata/file.go.zip")) + fmt.Println(IsExist("./unzip/testdata/test.txt")) + + os.Remove(zipFile) + os.RemoveAll(unZipPath) + + // Output: + // true + // true + // true +} + +func ExampleIsZipFile() { + result1 := IsZipFile("./file.go") + result2 := IsZipFile("./testdata/file.go.zip") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // false + // true +} + +func ExampleFileSize() { + size, err := FileSize("./testdata/test.txt") + + fmt.Println(size) + fmt.Println(err) + + // Output: + // 20 + //