1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-05 05:12:26 +08:00

Compare commits

..

37 Commits

Author SHA1 Message Date
dudaodong
9cd9d1aeb5 release v2.1.14 2023-02-06 17:42:13 +08:00
dudaodong
71b27c0aa9 feat: add ForEach, Reduce for stream 2023-02-06 17:40:54 +08:00
dudaodong
09a379ec6d feat: add ForEach, Reduce for stream 2023-02-06 17:38:33 +08:00
dudaodong
b4b9b03835 feat: add NoneMatch, AllMatch, AnyMatch for stream 2023-02-06 17:24:17 +08:00
dudaodong
48c7794b01 feat: add Limit method of stream 2023-02-06 17:08:36 +08:00
dudaodong
8e3911833d doc: normalize documents 2023-02-06 11:42:03 +08:00
dudaodong
ebe494051b doc: add doc for some new methods of list 2023-02-06 11:35:32 +08:00
dudaodong
c35bda6a65 feat: add ListToMap for list 2023-02-06 11:06:46 +08:00
dudaodong
1fe4cdc429 feat: add Difference and SymmetricDifference for list 2023-02-06 10:55:42 +08:00
dudaodong
6a79e322e3 Merge branch 'main' into v2 2023-02-06 10:00:02 +08:00
Cai Zhijiang
17e8d2bb6d 部分城市有4位区号+8位号码 (#69) 2023-02-06 09:47:21 +08:00
燕归来
325be0d6a1 feat: add func Iterator, ForEach, RetainAll and DeleteAll for List structure (#71) 2023-02-06 09:46:25 +08:00
dudaodong
ea0f96a8c0 feat: add Skip for stream 2023-01-30 16:56:33 +08:00
dudaodong
82cbb54787 feat: add FromChannel for create stream 2023-01-17 16:47:20 +08:00
dudaodong
585d33cafa feat: add Generate for create stream 2023-01-17 16:31:44 +08:00
dudaodong
bc4cf35e15 feat: add Filter, Map, Count for stream 2023-01-17 14:59:47 +08:00
dudaodong
a3bc20af1d feat: add Distinct 2023-01-17 11:39:05 +08:00
dudaodong
61338b6b46 feat: add Stream package 2023-01-17 11:25:15 +08:00
dudaodong
bc3c080ac3 doc: normalize document 2023-01-15 12:43:00 +08:00
dudaodong
d3fab15af3 refactor: clean structure for netutil package 2023-01-14 14:39:06 +08:00
dudaodong
6e3e411d46 doc: normalize document 2023-01-14 12:48:39 +08:00
dudaodong
f976941e36 doc: normalize document 2023-01-14 12:32:27 +08:00
dudaodong
4c5524354c doc: normalize documents 2023-01-13 14:36:33 +08:00
dudaodong
2c6e9a3fb9 doc: format document 2023-01-13 11:01:22 +08:00
dudaodong
5f2c3edff4 doc: format document 2023-01-13 10:57:40 +08:00
dudaodong
b422d98702 doc: format document 2023-01-13 10:48:21 +08:00
dudaodong
6f27e0bfbf doc: format document 2023-01-13 10:47:47 +08:00
dudaodong
ce3b6b461e doc: format document 2023-01-13 10:43:16 +08:00
dudaodong
0d6ad4f0d2 doc: format document 2023-01-13 10:41:47 +08:00
dudaodong
c875a7f8b8 doc: format document 2023-01-13 10:39:39 +08:00
dudaodong
0c62d117a1 doc: format document 2023-01-13 10:12:37 +08:00
dudaodong
c260ce493d doc: normalize documents 2023-01-12 15:44:34 +08:00
dudaodong
9ffe96d3ef update readme file 2023-01-12 11:32:43 +08:00
dudaodong
d4bba76dc8 fix: fix ExampleSchedule failed 2023-01-09 11:25:14 +08:00
dudaodong
adaa3ebc43 Merge branch 'main' into v2 2023-01-09 11:16:13 +08:00
dudaodong
61d38ae3b8 doc: update doc for algorithm package 2023-01-09 11:15:25 +08:00
dudaodong
c85d910044 add playground demo 2023-01-09 11:02:41 +08:00
70 changed files with 9920 additions and 6657 deletions

View File

@@ -1,10 +1,10 @@
<div align=center>
<a href="https://uvdream.github.io/lancet-docs/en/"><img src="./logo.png" width="200" height="200"/></a>
<img src="./logo.png" width="200" height="200"/>
<br/>
![Go version](https://img.shields.io/badge/go-%3E%3Dv1.18-9cf)
[![Release](https://img.shields.io/badge/release-2.1.13-green.svg)](https://github.com/duke-git/lancet/releases)
[![Release](https://img.shields.io/badge/release-2.1.14-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet/v2)](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -113,6 +113,7 @@ import "github.com/duke-git/lancet/v2/algorithm"
[[play](https://go.dev/play/p/Anozfr8ZLH3)]
- **<big>LinearSearch</big>** : returns the index of target in slice base on equal function.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#LinearSearch)]
[[play](https://go.dev/play/p/IsS7rgn5s3x)]
- **<big>LRUCache</big>** : implements memory cache with lru algorithm.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#LRUCache)]
[[play](https://go.dev/play/p/-EZjgOURufP)]
@@ -127,24 +128,34 @@ import "github.com/duke-git/lancet/v2/concurrency"
- **<big>NewChannel</big>** : create a Channel pointer instance.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#NewChannel)]
[[play](https://go.dev/play/p/7aB4KyMMp9A)]
- **<big>Bridge</big>** : link multiply channels into one channel.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/Bridge.md#NewChannel)]
[[play](https://go.dev/play/p/qmWSy1NVF-Y)]
- **<big>FanIn</big>** : merge multiple channels into one channel.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#FanIn)]
[[play](https://go.dev/play/p/2VYFMexEvTm)]
- **<big>Generate</big>** : creates a channel, then put values into the channel.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Generate)]
[[play](https://go.dev/play/p/7aB4KyMMp9A)]
- **<big>Or</big>** : read one or more channels into one channel, will close when any readin channel is closed.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Or)]
[[play](https://go.dev/play/p/Wqz9rwioPww)]
- **<big>OrDone</big>** : read a channel into another channel, will close until cancel context.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#OrDone)]
[[play](https://go.dev/play/p/lm_GoS6aDjo)]
- **<big>Repeat</big>** : create channel, put values into the channel repeatly until cancel the context.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Repeat)]
[[play](https://go.dev/play/p/k5N_ALVmYjE)]
- **<big>RepeatFn</big>** : create a channel, excutes fn repeatly, and put the result into the channel, until close context.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#RepeatFn)]
[[play](https://go.dev/play/p/4J1zAWttP85)]
- **<big>Take</big>** : create a channel whose values are taken from another channel with limit number.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Take)]
[[play](https://go.dev/play/p/9Utt-1pDr2J)]
- **<big>Tee</big>** : split one chanel into two channels, until cancel the context.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Tee)]
[[play](https://go.dev/play/p/3TQPKnCirrP)]
### 3. Condition package contains some functions for conditional judgment. eg. And, Or, TernaryOperator...
@@ -556,8 +567,10 @@ import "github.com/duke-git/lancet/v2/function"
[[play](https://go.dev/play/p/0HqUDIFZ3IL)]
- **<big>CurryFn</big>** : make a curry function.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function.md#CurryFn)]
[[play](https://go.dev/play/p/5HopfDwANKX)]
- **<big>Compose</big>** : compose the functions from right to left.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function.md#Compose)]
[[play](https://go.dev/play/p/KKfugD4PKYF)]
- **<big>Delay</big>** : call the function after delayed time.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function.md#Delay)]
[[play](https://go.dev/play/p/Ivtc2ZE-Tye)]
@@ -572,6 +585,8 @@ import "github.com/duke-git/lancet/v2/function"
[[play](https://go.dev/play/p/mPdUVvj6HD6)]
- **<big>Watcher</big>** : Watcher is used for record code excution time. can start/stop/reset the watch timer. get the elapsed time of function execution.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function.md#Watcher)]
[[play](https://go.dev/play/p/l2yrOpCLd1I)]
### 11. Maputil package includes some functions to manipulate map.
@@ -640,6 +655,7 @@ import "github.com/duke-git/lancet/v2/mathutil"
[[play](https://go.dev/play/p/N9qgYg_Ho6f)]
- **<big>Percent</big>** : calculate the percentage of value to total.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Percent)]
[[play](https://go.dev/play/p/QQM9B13coSP)]
- **<big>RoundToFloat</big>** : round up to n decimal places for float64.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RoundToFloat)]
[[play](https://go.dev/play/p/ghyb528JRJL)]
@@ -1000,6 +1016,7 @@ import "github.com/duke-git/lancet/v2/strutil"
[[play](https://go.dev/play/p/Us-ySSbWh-3)]
- **<big>Substring</big>** : returns a substring of the specific length starting at the specific offset position.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Substring)]
[[play](https://go.dev/play/p/q3sM6ehnPDp)]
- **<big>Wrap</big>** : wrap a string with given string.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Wrap)]
[[play](https://go.dev/play/p/KoZOlZDDt9y)]

View File

@@ -1,10 +1,10 @@
<div align=center>
<a href="https://uvdream.github.io/lancet-docs/"><img src="./logo.png" width="200" height="200"/><a/>
<img src="./logo.png" width="200" height="200"/>
<br/>
![Go version](https://img.shields.io/badge/go-%3E%3Dv1.18-9cf)
[![Release](https://img.shields.io/badge/release-2.1.13-green.svg)](https://github.com/duke-git/lancet/releases)
[![Release](https://img.shields.io/badge/release-2.1.14-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet/v2)](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -51,7 +51,7 @@ lancet 是以包的结构组织代码的,使用时需要导入相应的包名
import "github.com/duke-git/lancet/v2/strutil"
```
## 例
##
此处以字符串工具函数 Reverse逆序字符串为例需要导入 strutil 包:
@@ -112,6 +112,7 @@ import "github.com/duke-git/lancet/v2/algorithm"
[[play](https://go.dev/play/p/Anozfr8ZLH3)]
- **<big>LinearSearch</big>** : 基于传入的相等函数返回切片中目标值的索引。(线性查找)
[[doc](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#LinearSearch)]
[[play](https://go.dev/play/p/IsS7rgn5s3x)]
- **<big>LRUCache</big>** : 应用 lru 算法实现内存缓存.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#LRUCache)]
[[play](https://go.dev/play/p/-EZjgOURufP)]
@@ -126,24 +127,34 @@ import "github.com/duke-git/lancet/v2/concurrency"
- **<big>NewChannel</big>** : 返回一个 Channel 指针实例。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#NewChannel)]
[[play](https://go.dev/play/p/7aB4KyMMp9A)]
- **<big>Bridge</big>** : 将多个 channel 链接到一个 channel直到取消上下文。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/Bridge.md#NewChannel)]
[[play](https://go.dev/play/p/qmWSy1NVF-Y)]
- **<big>FanIn</big>** : 将多个 channel 合并为一个 channel直到取消上下文。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#FanIn)]
[[play](https://go.dev/play/p/2VYFMexEvTm)]
- **<big>Generate</big>** : 根据传入的值,生成 channel。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Generate)]
[[play](https://go.dev/play/p/7aB4KyMMp9A)]
- **<big>Or</big>** : 将一个或多个 channel 读取到一个 channel 中,当任何读取 channel 关闭时将结束读取。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Or)]
[[play](https://go.dev/play/p/Wqz9rwioPww)]
- **<big>OrDone</big>** : 将一个 channel 读入另一个 channel直到取消上下文。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#OrDone)]
[[play](https://go.dev/play/p/lm_GoS6aDjo)]
- **<big>Repeat</big>** : 返回一个 channel将参数`values`重复放入 channel直到取消上下文。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Repeat)]
[[play](https://go.dev/play/p/k5N_ALVmYjE)]
- **<big>RepeatFn</big>** : 返回一个 channel重复执行函数 fn并将结果放入返回的 channel直到取消上下文。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#RepeatFn)]
[[play](https://go.dev/play/p/4J1zAWttP85)]
- **<big>Take</big>** : 返回一个 channel其值从另一个 channel 获取,直到取消上下文。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Take)]
[[play](https://go.dev/play/p/9Utt-1pDr2J)]
- **<big>Tee</big>** : 将一个 channel 分成两个 channel直到取消上下文。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Tee)]
[[play](https://go.dev/play/p/3TQPKnCirrP)]
### 3. condition 包含一些用于条件判断的函数。
@@ -559,8 +570,10 @@ import "github.com/duke-git/lancet/v2/function"
[[play](https://go.dev/play/p/0HqUDIFZ3IL)]
- **<big>CurryFn</big>** : 创建柯里化函数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#CurryFn)]
[[play](https://go.dev/play/p/5HopfDwANKX)]
- **<big>Compose</big>** : 从右至左组合函数列表fnList返回组合后的函数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Compose)]
[[play](https://go.dev/play/p/KKfugD4PKYF)]
- **<big>Delay</big>** : 延迟delay时间后调用函数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Delay)]
[[play](https://go.dev/play/p/Ivtc2ZE-Tye)]
@@ -575,6 +588,7 @@ import "github.com/duke-git/lancet/v2/function"
[[play](https://go.dev/play/p/mPdUVvj6HD6)]
- **<big>Watcher</big>** : Watcher用于记录代码执行时间。可以启动/停止/重置手表定时器。获取函数执行的时间。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Watcher)]
[[play](https://go.dev/play/p/l2yrOpCLd1I)]
### 11. maputil 包括一些操作 map 的函数.
@@ -644,6 +658,7 @@ import "github.com/duke-git/lancet/v2/mathutil"
[[play](https://go.dev/play/p/N9qgYg_Ho6f)]
- **<big>Percent</big>** : 计算百分比,可以指定保留 n 位小数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Percent)]
[[play](https://go.dev/play/p/QQM9B13coSP)]
- **<big>RoundToFloat</big>** : 四舍五入,保留 n 位小数,返回 float64。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToFloat)]
[[play](https://go.dev/play/p/ghyb528JRJL)]
@@ -1010,6 +1025,7 @@ import "github.com/duke-git/lancet/v2/strutil"
[[play](https://go.dev/play/p/Us-ySSbWh-3)]
- **<big>Substring</big>** : 根据指定的位置和长度截取子字符串。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Substring)]
[[play](https://go.dev/play/p/q3sM6ehnPDp)]
- **<big>Wrap</big>** : 用给定字符包裹传入的字符串
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Wrap)]
[[play](https://go.dev/play/p/KoZOlZDDt9y)]
@@ -1160,7 +1176,6 @@ import "github.com/duke-git/lancet/v2/xerror"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)]
[[play](https://go.dev/play/p/w84d7Mb3Afk)]
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)
## 如何贡献代码

View File

@@ -10,7 +10,7 @@ import "github.com/duke-git/lancet/v2/lancetconstraints"
// LinearSearch return the index of target in slice base on equal function.
// If not found return -1
// Play: Todo
// Play: https://go.dev/play/p/IsS7rgn5s3x
func LinearSearch[T any](slice []T, target T, equal func(a, b T) bool) int {
for i, v := range slice {
if equal(v, target) {

View File

@@ -20,7 +20,7 @@ func NewChannel[T any]() *Channel[T] {
}
// Generate creates channel, then put values into the channel.
// Play: Todo
// Play: https://go.dev/play/p/7aB4KyMMp9A
func (c *Channel[T]) Generate(ctx context.Context, values ...T) <-chan T {
dataStream := make(chan T)
@@ -40,7 +40,7 @@ func (c *Channel[T]) Generate(ctx context.Context, values ...T) <-chan T {
}
// Repeat create channel, put values into the channel repeatly until cancel the context.
// Play: Todo
// Play: https://go.dev/play/p/k5N_ALVmYjE
func (c *Channel[T]) Repeat(ctx context.Context, values ...T) <-chan T {
dataStream := make(chan T)
@@ -61,7 +61,7 @@ func (c *Channel[T]) Repeat(ctx context.Context, values ...T) <-chan T {
// RepeatFn create a channel, excutes fn repeatly, and put the result into the channel
// until close context.
// Play: Todo
// Play: https://go.dev/play/p/4J1zAWttP85
func (c *Channel[T]) RepeatFn(ctx context.Context, fn func() T) <-chan T {
dataStream := make(chan T)
@@ -79,7 +79,7 @@ func (c *Channel[T]) RepeatFn(ctx context.Context, fn func() T) <-chan T {
}
// Take create a channel whose values are taken from another channel with limit number.
// Play: Todo
// Play: https://go.dev/play/p/9Utt-1pDr2J
func (c *Channel[T]) Take(ctx context.Context, valueStream <-chan T, number int) <-chan T {
takeStream := make(chan T)
@@ -99,7 +99,7 @@ func (c *Channel[T]) Take(ctx context.Context, valueStream <-chan T, number int)
}
// FanIn merge multiple channels into one channel.
// Play: Todo
// Play: https://go.dev/play/p/2VYFMexEvTm
func (c *Channel[T]) FanIn(ctx context.Context, channels ...<-chan T) <-chan T {
out := make(chan T)
@@ -127,7 +127,7 @@ func (c *Channel[T]) FanIn(ctx context.Context, channels ...<-chan T) <-chan T {
}
// Tee split one chanel into two channels, until cancel the context.
// Play: Todo
// Play: https://go.dev/play/p/3TQPKnCirrP
func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T) {
out1 := make(chan T)
out2 := make(chan T)
@@ -154,7 +154,7 @@ func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T)
}
// Bridge link multiply channels into one channel.
// Play: Todo
// Play: https://go.dev/play/p/qmWSy1NVF-Y
func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-chan T {
valStream := make(chan T)
@@ -186,7 +186,7 @@ func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-c
}
// Or read one or more channels into one channel, will close when any readin channel is closed.
// Play: Todo
// Play: https://go.dev/play/p/Wqz9rwioPww
func (c *Channel[T]) Or(channels ...<-chan T) <-chan T {
switch len(channels) {
case 0:
@@ -220,7 +220,7 @@ func (c *Channel[T]) Or(channels ...<-chan T) <-chan T {
}
// OrDone read a channel into another channel, will close until cancel context.
// Play: Todo
// Play: https://go.dev/play/p/lm_GoS6aDjo
func (c *Channel[T]) OrDone(ctx context.Context, channel <-chan T) <-chan T {
valStream := make(chan T)

View File

@@ -6,6 +6,8 @@ package datastructure
import (
"reflect"
"github.com/duke-git/lancet/v2/iterator"
)
// List is a linear table, implemented with slice.
@@ -316,6 +318,43 @@ func (l *List[T]) Intersection(other *List[T]) *List[T] {
return result
}
// Difference returns the difference between two collections.
// return a list whose element in the original list, not in the given list.
func (l *List[T]) Difference(other *List[T]) *List[T] {
result := NewList(make([]T, 0))
intersectList := l.Intersection(other)
for _, v := range l.data {
if !intersectList.Contain(v) {
result.data = append(result.data, v)
}
}
return result
}
// SymmetricDifference oppoiste operation of intersection function.
func (l *List[T]) SymmetricDifference(other *List[T]) *List[T] {
result := NewList(make([]T, 0))
intersectList := l.Intersection(other)
for _, v := range l.data {
if !intersectList.Contain(v) {
result.data = append(result.data, v)
}
}
for _, v := range other.data {
if !intersectList.Contain(v) {
result.data = append(result.data, v)
}
}
return result
}
// SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T] {
data := l.data[fromIndex:toIndex]
@@ -323,3 +362,57 @@ func (l *List[T]) SubList(fromIndex, toIndex int) *List[T] {
copy(subList, data)
return NewList(subList)
}
// ForEach performs the given action for each element of the list.
func (l *List[T]) ForEach(consumer func(T)) {
for _, it := range l.data {
consumer(it)
}
}
// RetainAll retains only the elements in this list that are contained in the given list.
func (l *List[T]) RetainAll(list *List[T]) bool {
return l.batchRemove(list, true)
}
// DeleteAll removes from this list all of its elements that are contained in the given list.
func (l *List[T]) DeleteAll(list *List[T]) bool {
return l.batchRemove(list, false)
}
func (l *List[T]) batchRemove(list *List[T], complement bool) bool {
var (
w = 0
data = l.data
size = len(data)
)
for i := 0; i < size; i++ {
if list.Contain(data[i]) == complement {
data[w] = data[i]
w++
}
}
if w != size {
l.data = data[:w]
return true
}
return false
}
// Iterator returns an iterator over the elements in this list in proper sequence.
func (l *List[T]) Iterator() iterator.Iterator[T] {
return iterator.FromSlice(l.data)
}
// ListToMap convert a list to a map based on iteratee function.
func ListToMap[T any, K comparable, V any](list *List[T], iteratee func(T) (K, V)) map[K]V {
result := make(map[K]V, list.Size())
for _, item := range list.data {
k, v := iteratee(item)
result[k] = v
}
return result
}

View File

@@ -328,6 +328,28 @@ func TestIntersection(t *testing.T) {
assert.Equal(true, expected.Equal(list3))
}
func TestDifference(t *testing.T) {
assert := internal.NewAssert(t, "TestDifference")
list1 := NewList([]int{1, 2, 3})
list2 := NewList([]int{1, 2, 4})
expected := NewList([]int{3})
list3 := list1.Difference(list2)
assert.Equal(true, expected.Equal(list3))
}
func TestSymmetricDifference(t *testing.T) {
assert := internal.NewAssert(t, "TestSymmetricDifference")
list1 := NewList([]int{1, 2, 3})
list2 := NewList([]int{1, 2, 4})
expected := NewList([]int{3, 4})
list3 := list1.SymmetricDifference(list2)
assert.Equal(true, expected.Equal(list3))
}
func TestSubSlice(t *testing.T) {
assert := internal.NewAssert(t, "TestSubSlice")
@@ -357,3 +379,84 @@ func TestDeleteIf(t *testing.T) {
assert.Equal([]int{2, 3, 4}, list.Data())
assert.Equal(0, count)
}
func TestForEach(t *testing.T) {
assert := internal.NewAssert(t, "TestForEach")
list := NewList([]int{1, 2, 3, 4})
rs := make([]int, 0)
list.ForEach(func(i int) {
rs = append(rs, i)
})
assert.Equal([]int{1, 2, 3, 4}, rs)
}
func TestRetainAll(t *testing.T) {
assert := internal.NewAssert(t, "TestRetainAll")
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)
assert.Equal([]int{1, 2}, list.Data())
assert.Equal([]int{2, 3}, list1.Data())
assert.Equal([]int{1, 2}, list2.Data())
}
func TestDeleteAll(t *testing.T) {
assert := internal.NewAssert(t, "TestDeleteAll")
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)
assert.Equal([]int{2, 3, 4}, list.Data())
assert.Equal([]int{1, 4}, list1.Data())
assert.Equal([]int{3, 4}, list2.Data())
}
func TestIterator(t *testing.T) {
assert := internal.NewAssert(t, "TestIterator")
list := NewList([]int{1, 2, 3, 4})
iterator := list.Iterator()
rs := make([]int, 0)
for iterator.HasNext() {
item, _ := iterator.Next()
rs = append(rs, item)
}
assert.Equal([]int{1, 2, 3, 4}, rs)
}
func TestListToMap(t *testing.T) {
assert := internal.NewAssert(t, "ListToMap")
list := NewList([]int{1, 2, 3, 4})
result := ListToMap(list, func(n int) (int, bool) {
return n, n > 1
})
expected := map[int]bool{1: false, 2: true, 3: true, 4: true}
assert.Equal(expected, result)
}

View File

@@ -1,17 +1,19 @@
# Algorithm
Package algorithm implements some basic algorithm. eg. sort, search.
<div STYLE="page-break-after: always;"></div>
## Source
- [https://github.com/duke-git/lancet/blob/main/algorithm/sort.go](https://github.com/duke-git/lancet/blob/main/algorithm/sort.go)
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
- [https://github.com/duke-git/lancet/blob/main/algorithm/sort.go](https://github.com/duke-git/lancet/blob/main/algorithm/sort.go)
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
<div STYLE="page-break-after: always;"></div>
## Usage
```go
import (
"github.com/duke-git/lancet/v2/algorithm"
@@ -22,27 +24,25 @@ import (
## Index
- [BubbleSort](#BubbleSort)
- [InsertionSort](#InsertionSort)
- [SelectionSort](#SelectionSort)
- [ShellSort](#ShellSort)
- [QuickSort](#QuickSort)
- [HeapSort](#HeapSort)
- [MergeSort](#MergeSort)
- [CountSort](#CountSort)
- [BinarySearch](#BinarySearch)
- [BinaryIterativeSearch](#BinaryIterativeSearch)
- [LinearSearch](#LinearSearch)
- [LRUCache](#LRUCache)
- [BubbleSort](#BubbleSort)
- [InsertionSort](#InsertionSort)
- [SelectionSort](#SelectionSort)
- [ShellSort](#ShellSort)
- [QuickSort](#QuickSort)
- [HeapSort](#HeapSort)
- [MergeSort](#MergeSort)
- [CountSort](#CountSort)
- [BinarySearch](#BinarySearch)
- [BinaryIterativeSearch](#BinaryIterativeSearch)
- [LinearSearch](#LinearSearch)
- [LRUCache](#LRUCache)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="BubbleSort">BubbleSort</span>
<p>Sort slice with bubble sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
<b>Signature:</b>
@@ -50,6 +50,7 @@ import (
```go
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator)
```
<b>Example:</b>
```go
@@ -60,34 +61,36 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
algorithm.BubbleSort(intSlice, comparator)
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
algorithm.BubbleSort(numbers, comparator)
fmt.Println(numbers)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="InsertionSort">InsertionSort</span>
<p>Sort slice with insertion sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
<b>Signature:</b>
@@ -95,6 +98,7 @@ func main() {
```go
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator)
```
<b>Example:</b>
```go
@@ -105,54 +109,51 @@ import (
"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/lancetconstraints/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() {
type people struct {
Name string
Age int
}
// PeopleAageComparator sort people slice by age field
type peopleAgeComparator struct{}
// Compare implements github.com/duke-git/lancet/lancetconstraints/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
//decending order
// if p1.Age > p2.Age {
// return -1
// } else if p1.Age < p2.Age {
// return 1
// }
}
var peoples = []people{
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) //[{d 8} {b 10} {c 17} {a 20} {e 28}]
fmt.Println(peoples)
// Output:
// [{d 8} {b 10} {c 17} {a 20} {e 28}]
}
```
### <span id="SelectionSort">SelectionSort</span>
<p>Sort slice with selection sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
<b>Signature:</b>
@@ -160,6 +161,7 @@ func main() {
```go
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator)
```
<b>Example:</b>
```go
@@ -170,34 +172,36 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
algorithm.SelectionSort(intSlice, comparator)
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
algorithm.SelectionSort(numbers, comparator)
fmt.Println(numbers)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="ShellSort">ShellSort</span>
<p>Sort slice with shell sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
<b>Signature:</b>
@@ -205,6 +209,7 @@ func main() {
```go
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator)
```
<b>Example:</b>
```go
@@ -215,34 +220,36 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
algorithm.ShellSort(intSlice, comparator)
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
algorithm.ShellSort(numbers, comparator)
fmt.Println(numbers)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="QuickSort">QuickSort</span>
<p>Sort slice with quick sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
<b>Signature:</b>
@@ -250,6 +257,7 @@ func main() {
```go
func QuickSort[T any](slice []T comparator lancetconstraints.Comparator)
```
<b>Example:</b>
```go
@@ -260,34 +268,36 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
algorithm.QuickSort(intSlice, comparator)
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
algorithm.QuickSort(numbers, comparator)
fmt.Println(numbers)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="HeapSort">HeapSort</span>
<p>Sort slice with heap sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
<b>Signature:</b>
@@ -295,6 +305,7 @@ func main() {
```go
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator)
```
<b>Example:</b>
```go
@@ -305,34 +316,36 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
algorithm.HeapSort(intSlice, comparator)
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
algorithm.HeapSort(numbers, comparator)
fmt.Println(numbers)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="MergeSort">MergeSort</span>
<p>Sort slice with merge sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
<b>Signature:</b>
@@ -340,6 +353,7 @@ func main() {
```go
func MergeSort[T any](slice []T, comparator lancetconstraints.Comparator)
```
<b>Example:</b>
```go
@@ -350,33 +364,36 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
algorithm.MergeSort(intSlice, comparator)
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
algorithm.MergeSort(numbers, comparator)
fmt.Println(numbers)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="CountSort">CountSort</span>
<p>Sort slice with count sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
<b>Signature:</b>
@@ -384,6 +401,7 @@ func main() {
```go
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
@@ -394,34 +412,37 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
type intComparator struct{}
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
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
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.CountSort(intSlice, comparator)
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
sortedNums := algorithm.CountSort(numbers, comparator)
fmt.Println(sortedNums)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="BinarySearch">BinarySearch</span>
<p>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.</p>
<b>Signature:</b>
@@ -429,6 +450,7 @@ func main() {
```go
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
```
<b>Example:</b>
```go
@@ -439,35 +461,39 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
func main() {
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8}
comparator := &intComparator{}
foundIndex := algorithm.BinarySearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator)
fmt.Println(foundIndex) //4
notFoundIndex := algorithm.BinarySearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator)
fmt.Println(notFoundIndex) //-1
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
}
```
### <span id="BinaryIterativeSearch">BinaryIterativeSearch</span>
<p>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.</p>
<b>Signature:</b>
@@ -475,6 +501,7 @@ func main() {
```go
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
```
<b>Example:</b>
```go
@@ -485,43 +512,47 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
func main() {
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8}
comparator := &intComparator{}
foundIndex := algorithm.BinaryIterativeSearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator)
fmt.Println(foundIndex) //4
notFoundIndex := algorithm.BinaryIterativeSearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator)
fmt.Println(notFoundIndex) //-1
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
}
```
### <span id="LinearSearch">LinearSearch</span>
<p>LinearSearch Simple linear search algorithm that iterates over all elements of an slice. If a target is found, the index of the target is returned. Else the function return -1.</p>
<p>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.</p>
<b>Signature:</b>
```go
func LinearSearch[T any](slice []T, target T, comparator lancetconstraints.Comparator) int
func LinearSearch[T any](slice []T, target T, equal func(a, b T) bool) int
```
<b>Example:</b>
```go
@@ -533,35 +564,26 @@ import (
)
func main() {
type intComparator struct{}
numbers := []int{3, 4, 5, 3, 2, 1}
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
equalFunc := func(a, b int) bool {
return a == b
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
foundIndex := algorithm.LinearSearch(intSlice, 5, comparator)
fmt.Println(foundIndex) //2
result1 := algorithm.LinearSearch(numbers, 3, equalFunc)
result2 := algorithm.LinearSearch(numbers, 6, equalFunc)
notFoundIndex := algorithm.LinearSearch(sortedNumbers, 0, comparator)
fmt.Println(notFoundIndex) //-1
fmt.Println(result1)
fmt.Println(result2)
// Output:
// 0
// -1
}
```
### <span id="LRUCache">LRUCache</span>
<p>LRUCache implements mem cache with lru.</p>
<b>Signature:</b>
@@ -573,6 +595,7 @@ 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
```
<b>Example:</b>
```go
@@ -588,14 +611,26 @@ func main() {
cache.Put(1, 1)
cache.Put(2, 2)
cache.Put(3, 3)
fmt.Println(cache.Len()) // 3
result1, ok1 := cache.Get(1)
result2, ok2 := cache.Get(2)
result3, ok3 := cache.Get(3)
v, ok := cache.Get(1)
fmt.Println(v, ok) // 1 true
fmt.Println(result1, ok1)
fmt.Println(result2, ok2)
fmt.Println(result3, ok3)
ok = cache.Delete(1)
fmt.Println(ok) // true
fmt.Println(cache.Len())
ok := cache.Delete(2)
fmt.Println(ok)
// Output:
// 1 true
// 2 true
// 0 false
// 2
// true
}
```
```

View File

@@ -1,17 +1,19 @@
# Algorithm
algorithm算法包实现一些基本算法sortsearchlrucache。
algorithm 算法包实现一些基本算法sortsearchlrucache。
<div STYLE="page-break-after: always;"></div>
## 源码
- [https://github.com/duke-git/lancet/blob/main/algorithm/sort.go](https://github.com/duke-git/lancet/blob/main/algorithm/sort.go)
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
- [https://github.com/duke-git/lancet/blob/main/algorithm/sort.go](https://github.com/duke-git/lancet/blob/main/algorithm/sort.go)
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
<div STYLE="page-break-after: always;"></div>
## 用法
```go
import (
"github.com/duke-git/lancet/v2/algorithm"
@@ -22,35 +24,34 @@ import (
## 目录
- [BubbleSort](#BubbleSort)
- [InsertionSort](#InsertionSort)
- [SelectionSort](#SelectionSort)
- [ShellSort](#ShellSort)
- [QuickSort](#QuickSort)
- [HeapSort](#HeapSort)
- [MergeSort](#MergeSort)
- [CountSort](#CountSort)
- [BinarySearch](#BinarySearch)
- [BinaryIterativeSearch](#BinaryIterativeSearch)
- [LinearSearch](#LinearSearch)
- [LRUCache](#LRUCache)
- [BubbleSort](#BubbleSort)
- [InsertionSort](#InsertionSort)
- [SelectionSort](#SelectionSort)
- [ShellSort](#ShellSort)
- [QuickSort](#QuickSort)
- [HeapSort](#HeapSort)
- [MergeSort](#MergeSort)
- [CountSort](#CountSort)
- [BinarySearch](#BinarySearch)
- [BinaryIterativeSearch](#BinaryIterativeSearch)
- [LinearSearch](#LinearSearch)
- [LRUCache](#LRUCache)
<div STYLE="page-break-after: always;"></div>
## 文档
### <span id="BubbleSort">BubbleSort</span>
<p>冒泡排序参数comparator需要实现包lancetconstraints.Comparator</p>
<p>冒泡排序参数comparator需要实现包lancetconstraints.Comparator。</p>
<b>函数签名:</b>
```go
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator)
```
<b>Example:</b>
<b>示例:</b>
```go
package main
@@ -60,42 +61,45 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
algorithm.BubbleSort(intSlice, comparator)
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
algorithm.BubbleSort(numbers, comparator)
fmt.Println(numbers)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="InsertionSort">InsertionSort</span>
<p>插入排序参数comparator需要实现包lancetconstraints.Comparator</p>
<p>插入排序参数comparator需要实现包lancetconstraints.Comparator。</p>
<b>函数签名:</b>
```go
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator)
```
<b>Example:</b>
<b>示例:</b>
```go
package main
@@ -105,62 +109,60 @@ import (
"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/lancetconstraints/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() {
type people struct {
Name string
Age int
}
// PeopleAageComparator sort people slice by age field
type peopleAgeComparator struct{}
// Compare implements github.com/duke-git/lancet/lancetconstraints/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
//decending order
// if p1.Age > p2.Age {
// return -1
// } else if p1.Age < p2.Age {
// return 1
// }
}
var peoples = []people{
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(intSlice) //[{d 8} {b 10} {c 17} {a 20} {e 28}]
fmt.Println(peoples)
// Output:
// [{d 8} {b 10} {c 17} {a 20} {e 28}]
}
```
### <span id="SelectionSort">SelectionSort</span>
<p>选择排序参数comparator需要实现包lancetconstraints.Comparator</p>
<p>选择排序参数comparator需要实现包lancetconstraints.Comparator。</p>
<b>函数签名:</b>
```go
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator)
```
<b>Example:</b>
<b>示例:</b>
```go
package main
@@ -170,42 +172,45 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
algorithm.SelectionSort(intSlice, comparator)
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
algorithm.SelectionSort(numbers, comparator)
fmt.Println(numbers)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="ShellSort">ShellSort</span>
<p>希尔排序参数comparator需要实现包lancetconstraints.Comparator</p>
<p>希尔排序参数comparator需要实现包lancetconstraints.Comparator。</p>
<b>函数签名:</b>
```go
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator)
```
<b>Example:</b>
<b>示例:</b>
```go
package main
@@ -215,42 +220,45 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
algorithm.ShellSort(intSlice, comparator)
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
algorithm.ShellSort(numbers, comparator)
fmt.Println(numbers)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="QuickSort">QuickSort</span>
<p>快速排序参数comparator需要实现包lancetconstraints.Comparator</p>
<p>快速排序参数comparator需要实现包lancetconstraints.Comparator。</p>
<b>函数签名:</b>
```go
func QuickSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
func QuickSort[T any](slice []T comparator lancetconstraints.Comparator)
```
<b>Example:</b>
<b>示例:</b>
```go
package main
@@ -260,42 +268,45 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
algorithm.QuickSort(intSlice, comparator)
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
algorithm.QuickSort(numbers, comparator)
fmt.Println(numbers)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="HeapSort">HeapSort</span>
<p>堆排序参数comparator需要实现包lancetconstraints.Comparator</p>
<p>堆排序参数comparator需要实现包lancetconstraints.Comparator。</p>
<b>函数签名:</b>
```go
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator)
```
<b>Example:</b>
<b>示例:</b>
```go
package main
@@ -305,42 +316,45 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
algorithm.HeapSort(intSlice, comparator)
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
algorithm.HeapSort(numbers, comparator)
fmt.Println(numbers)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="MergeSort">MergeSort</span>
<p>归并排序参数comparator需要实现包lancetconstraints.Comparator</p>
<p>归并排序参数comparator需要实现包lancetconstraints.Comparator。</p>
<b>函数签名:</b>
```go
func MergeSort[T any](slice []T, comparator lancetconstraints.Comparator)
```
<b>Example:</b>
<b>示例:</b>
```go
package main
@@ -350,41 +364,45 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
algorithm.MergeSort(intSlice, comparator)
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
algorithm.MergeSort(numbers, comparator)
fmt.Println(numbers)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="CountSort">CountSort</span>
<p>计数排序参数comparator需要实现包lancetconstraints.Comparator</p>
<p>计数排序参数comparator需要实现包lancetconstraints.Comparator。</p>
<b>函数签名:</b>
```go
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
<b>示例:</b>
```go
package main
@@ -394,42 +412,46 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
type intComparator struct{}
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
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
}
intSlice := []int{2, 1, 5, 3, 6, 4}
func main() {
numbers := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.CountSort(intSlice, comparator)
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
sortedNums := algorithm.CountSort(numbers, comparator)
fmt.Println(sortedNums)
// Output:
// [1 2 3 4 5 6]
}
```
### <span id="BinarySearch">BinarySearch</span>
<p>二分递归查找,返回元素索引,未找到元素返回-1参数comparator需要实现包lancetconstraints.Comparator</p>
<p>二分递归查找,返回元素索引,未找到元素返回-1参数comparator需要实现包lancetconstraints.Comparator。</p>
<b>函数签名:</b>
```go
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
```
<b>Example:</b>
<b>示例:</b>
```go
package main
@@ -439,43 +461,48 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
func main() {
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8}
comparator := &intComparator{}
foundIndex := algorithm.BinarySearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator)
fmt.Println(foundIndex) //4
notFoundIndex := algorithm.BinarySearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator)
fmt.Println(notFoundIndex) //-1
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
}
```
### <span id="BinaryIterativeSearch">BinaryIterativeSearch</span>
<p>二分迭代查找,返回元素索引,未找到元素返回-1参数comparator需要实现包lancetconstraints.Comparator</p>
<p>二分迭代查找,返回元素索引,未找到元素返回-1参数comparator需要实现包lancetconstraints.Comparator。</p>
<b>函数签名:</b>
```go
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
```
<b>Example:</b>
<b>示例:</b>
```go
package main
@@ -485,44 +512,48 @@ import (
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
type intComparator struct{}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
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
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
func main() {
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8}
comparator := &intComparator{}
foundIndex := algorithm.BinaryIterativeSearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator)
fmt.Println(foundIndex) //4
notFoundIndex := algorithm.BinaryIterativeSearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator)
fmt.Println(notFoundIndex) //-1
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
}
```
### <span id="LinearSearch">LinearSearch</span>
<p>线性查找,返回元素索引,未找到元素返回-1参数comparator需要实现包lancetconstraints.Comparator</p>
<p>基于传入的相等函数线性查找元素,返回元素索引,未找到元素返回-1。</p>
<b>函数签名:</b>
```go
func LinearSearch[T any](slice []T, target T, comparator lancetconstraints.Comparator) int
func LinearSearch[T any](slice []T, target T, equal func(a, b T) bool) int
```
<b>Example:</b>
<b>示例:</b>
```go
package main
@@ -533,36 +564,27 @@ import (
)
func main() {
type intComparator struct{}
numbers := []int{3, 4, 5, 3, 2, 1}
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
equalFunc := func(a, b int) bool {
return a == b
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
foundIndex := algorithm.LinearSearch(intSlice, 5, comparator)
fmt.Println(foundIndex) //2
result1 := algorithm.LinearSearch(numbers, 3, equalFunc)
result2 := algorithm.LinearSearch(numbers, 6, equalFunc)
notFoundIndex := algorithm.LinearSearch(sortedNumbers, 0, comparator)
fmt.Println(notFoundIndex) //-1
fmt.Println(result1)
fmt.Println(result2)
// Output:
// 0
// -1
}
```
### <span id="LRUCache">LRUCache</span>
<p>lru实现缓存</p>
<p>lru算法实现缓存。</p>
<b>函数签名:</b>
@@ -573,7 +595,8 @@ 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
```
<b>Example:</b>
<b>示例:</b>
```go
package main
@@ -588,14 +611,26 @@ func main() {
cache.Put(1, 1)
cache.Put(2, 2)
cache.Put(3, 3)
fmt.Println(cache.Len()) // 3
result1, ok1 := cache.Get(1)
result2, ok2 := cache.Get(2)
result3, ok3 := cache.Get(3)
v, ok := cache.Get(1)
fmt.Println(v, ok) // 1 true
fmt.Println(result1, ok1)
fmt.Println(result2, ok2)
fmt.Println(result3, ok3)
ok = cache.Delete(1)
fmt.Println(ok) // true
fmt.Println(cache.Len())
ok := cache.Delete(2)
fmt.Println(ok)
// Output:
// 1 true
// 2 true
// 0 false
// 2
// true
}
```
```

View File

@@ -61,8 +61,6 @@ func main() {
}
```
### <span id="Bridge">Bridge</span>
<p>Link multiple channels into one channel until cancel the context.</p>
@@ -84,39 +82,37 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
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
}
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
for v := range c.Bridge(ctx, genVals()) {
fmt.Println(v)
}
// Output:
// 1
// 2
// 3
// 4
// 5
}
```
### <span id="FanIn">FanIn</span>
<p>Merge multiple channels into one channel until cancel the context.</p>
@@ -138,25 +134,24 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := concurrency.NewChannel[int]()
channels := make([]<-chan int, 2)
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)
}
for i := 0; i < 2; i++ {
channels[i] = c.Take(ctx, c.Repeat(ctx, i), 2)
}
chs := c.FanIn(ctx, channels...)
chs := c.FanIn(ctx, channels...)
for v := range chs {
fmt.Println(v) //1 1 0 0 or 0 0 1 1
}
for v := range chs {
fmt.Println(v) //1 1 0 0 or 0 0 1 1
}
}
```
### <span id="Repeat">Repeat</span>
<p>Create channel, put values into the channel repeatly until cancel the context.</p>
@@ -178,25 +173,24 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := concurrency.NewChannel[int]()
intStream := c.Take(ctx, c.Repeat(ctx, 1, 2), 4)
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
for v := range intStream {
fmt.Println(v)
}
// Output:
// 1
// 2
// 1
// 2
}
```
### <span id="Generate">Generate</span>
<p>Creates a channel, then put values into the channel.</p>
@@ -218,20 +212,20 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := concurrency.NewChannel[int]()
intStream := c.Generate(ctx, 1, 2, 3)
c := concurrency.NewChannel[int]()
intStream := c.Generate(ctx, 1, 2, 3)
fmt.Println(<-intStream)
fmt.Println(<-intStream)
fmt.Println(<-intStream)
fmt.Println(<-intStream)
fmt.Println(<-intStream)
fmt.Println(<-intStream)
// Output:
// 1
// 2
// 3
// Output:
// 1
// 2
// 3
}
```
@@ -256,28 +250,27 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
fn := func() string {
return "hello"
}
fn := func() string {
return "hello"
}
c := concurrency.NewChannel[string]()
intStream := c.Take(ctx, c.RepeatFn(ctx, fn), 3)
c := concurrency.NewChannel[string]()
intStream := c.Take(ctx, c.RepeatFn(ctx, fn), 3)
for v := range intStream {
fmt.Println(v)
}
// Output:
// hello
// hello
// hello
for v := range intStream {
fmt.Println(v)
}
// Output:
// hello
// hello
// hello
}
```
### <span id="Or">Or</span>
<p>Read one or more channels into one channel, will close when any readin channel is closed.</p>
@@ -299,31 +292,28 @@ import (
)
func main() {
sig := func(after time.Duration) <-chan any {
c := make(chan any)
go func() {
defer close(c)
time.Sleep(after)
}()
return c
}
sig := func(after time.Duration) <-chan any {
c := make(chan any)
go func() {
defer close(c)
time.Sleep(after)
}()
return c
}
start := time.Now()
start := time.Now()
c := concurrency.NewChannel[any]()
<-c.Or(
sig(1*time.Second),
sig(2*time.Second),
sig(3*time.Second),
)
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
fmt.Println("done after %v", time.Since(start)) //1.003s
}
```
### <span id="OrDone">OrDone</span>
<p>Read a channel into another channel, will close until cancel context.</p>
@@ -345,25 +335,23 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := concurrency.NewChannel[int]()
intStream := c.Take(ctx, c.Repeat(ctx, 1), 3)
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
for v := range c.OrDone(ctx, intStream) {
fmt.Println(v)
}
// Output:
// 1
// 1
// 1
}
```
### <span id="Take">Take</span>
<p>Create a channel whose values are taken from another channel with limit number.</p>
@@ -385,32 +373,31 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
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)
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)
c := concurrency.NewChannel[int]()
intStream := c.Take(ctx, numbers, 3)
for v := range intStream {
fmt.Println(v)
}
// Output:
// 1
// 2
// 3
for v := range intStream {
fmt.Println(v)
}
// Output:
// 1
// 2
// 3
}
```
### <span id="Tee">Tee</span>
<p>Split one chanel into two channels, until cancel the context.</p>
@@ -432,22 +419,23 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := concurrency.NewChannel[int]()
intStream := c.Take(ctx, c.Repeat(ctx, 1), 2)
c := concurrency.NewChannel[int]()
intStream := c.Take(ctx, c.Repeat(ctx, 1), 2)
ch1, ch2 := c.Tee(ctx, intStream)
ch1, ch2 := c.Tee(ctx, intStream)
for v := range ch1 {
fmt.Println(v)
fmt.Println(<-ch2)
}
// Output:
// 1
// 1
// 1
// 1
for v := range ch1 {
fmt.Println(v)
fmt.Println(<-ch2)
}
// Output:
// 1
// 1
// 1
// 1
}
```

View File

@@ -46,7 +46,7 @@ import (
type Channel[T any] struct
func NewChannel[T any]() *Channel[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -61,8 +61,6 @@ func main() {
}
```
### <span id="Bridge">Bridge</span>
<p>将多个channel链接到一个channel直到取消上下文。</p>
@@ -72,7 +70,7 @@ func main() {
```go
func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-chan T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -84,39 +82,37 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
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
}
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
for v := range c.Bridge(ctx, genVals()) {
fmt.Println(v)
}
// Output:
// 1
// 2
// 3
// 4
// 5
}
```
### <span id="FanIn">FanIn</span>
<p>将多个channel合并为一个channel直到取消上下文。</p>
@@ -126,7 +122,7 @@ func main() {
```go
func (c *Channel[T]) FanIn(ctx context.Context, channels ...<-chan T) <-chan T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -138,25 +134,24 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := concurrency.NewChannel[int]()
channels := make([]<-chan int, 2)
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)
}
for i := 0; i < 2; i++ {
channels[i] = c.Take(ctx, c.Repeat(ctx, i), 2)
}
chs := c.FanIn(ctx, channels...)
chs := c.FanIn(ctx, channels...)
for v := range chs {
fmt.Println(v) //1 1 0 0 or 0 0 1 1
}
for v := range chs {
fmt.Println(v) //1 1 0 0 or 0 0 1 1
}
}
```
### <span id="Generate">Generate</span>
<p>根据传入的值生成channel.</p>
@@ -166,7 +161,7 @@ func main() {
```go
func (c *Channel[T]) Generate(ctx context.Context, values ...T) <-chan T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -178,20 +173,20 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := concurrency.NewChannel[int]()
intStream := c.Generate(ctx, 1, 2, 3)
c := concurrency.NewChannel[int]()
intStream := c.Generate(ctx, 1, 2, 3)
fmt.Println(<-intStream)
fmt.Println(<-intStream)
fmt.Println(<-intStream)
fmt.Println(<-intStream)
fmt.Println(<-intStream)
fmt.Println(<-intStream)
// Output:
// 1
// 2
// 3
// Output:
// 1
// 2
// 3
}
```
@@ -204,7 +199,7 @@ func main() {
```go
func (c *Channel[T]) Repeat(ctx context.Context, values ...T) <-chan T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -216,26 +211,24 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := concurrency.NewChannel[int]()
intStream := c.Take(ctx, c.Repeat(ctx, 1, 2), 4)
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
for v := range intStream {
fmt.Println(v)
}
// Output:
// 1
// 2
// 1
// 2
}
```
### <span id="RepeatFn">RepeatFn</span>
<p>返回一个channel重复执行函数fn并将结果放入返回的channel直到取消上下文。</p>
@@ -245,7 +238,7 @@ func main() {
```go
func (c *Channel[T]) RepeatFn(ctx context.Context, fn func() T) <-chan T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -257,28 +250,26 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
fn := func() string {
return "hello"
}
fn := func() string {
return "hello"
}
c := concurrency.NewChannel[string]()
intStream := c.Take(ctx, c.RepeatFn(ctx, fn), 3)
c := concurrency.NewChannel[string]()
intStream := c.Take(ctx, c.RepeatFn(ctx, fn), 3)
for v := range intStream {
fmt.Println(v)
}
// Output:
// hello
// hello
// hello
for v := range intStream {
fmt.Println(v)
}
// Output:
// hello
// hello
// hello
}
```
### <span id="Or">Or</span>
<p>将一个或多个channel读取到一个channel中当任何读取channel关闭时将结束读取。</p>
@@ -288,7 +279,7 @@ func main() {
```go
func (c *Channel[T]) Or(channels ...<-chan T) <-chan T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -300,31 +291,28 @@ import (
)
func main() {
sig := func(after time.Duration) <-chan any {
c := make(chan any)
go func() {
defer close(c)
time.Sleep(after)
}()
return c
}
sig := func(after time.Duration) <-chan any {
c := make(chan any)
go func() {
defer close(c)
time.Sleep(after)
}()
return c
}
start := time.Now()
start := time.Now()
c := concurrency.NewChannel[any]()
<-c.Or(
sig(1*time.Second),
sig(2*time.Second),
sig(3*time.Second),
)
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
fmt.Println("done after %v", time.Since(start)) //1.003s
}
```
### <span id="OrDone">OrDone</span>
<p>将一个channel读入另一个channel直到取消上下文。</p>
@@ -334,7 +322,7 @@ func main() {
```go
func (c *Channel[T]) OrDone(ctx context.Context, channel <-chan T) <-chan T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -346,25 +334,23 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := concurrency.NewChannel[int]()
intStream := c.Take(ctx, c.Repeat(ctx, 1), 3)
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
for v := range c.OrDone(ctx, intStream) {
fmt.Println(v)
}
// Output:
// 1
// 1
// 1
}
```
### <span id="Take">Take</span>
<p>返回一个channel其值从另一个channel获取直到取消上下文。</p>
@@ -374,7 +360,7 @@ func main() {
```go
func (c *Channel[T]) Take(ctx context.Context, valueStream <-chan T, number int) <-chan T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -386,32 +372,31 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
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)
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)
c := concurrency.NewChannel[int]()
intStream := c.Take(ctx, numbers, 3)
for v := range intStream {
fmt.Println(v)
}
// Output:
// 1
// 2
// 3
for v := range intStream {
fmt.Println(v)
}
// Output:
// 1
// 2
// 3
}
```
### <span id="Tee">Tee</span>
<p>将一个channel分成两个channel直到取消上下文。</p>
@@ -421,7 +406,7 @@ func main() {
```go
func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -433,22 +418,22 @@ import (
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := concurrency.NewChannel[int]()
intStream := c.Take(ctx, c.Repeat(ctx, 1), 2)
c := concurrency.NewChannel[int]()
intStream := c.Take(ctx, c.Repeat(ctx, 1), 2)
ch1, ch2 := c.Tee(ctx, intStream)
ch1, ch2 := c.Tee(ctx, intStream)
for v := range ch1 {
fmt.Println(v)
fmt.Println(<-ch2)
}
// Output:
// 1
// 1
// 1
// 1
for v := range ch1 {
fmt.Println(v)
fmt.Println(<-ch2)
}
// Output:
// 1
// 1
// 1
// 1
}
```

View File

@@ -57,41 +57,52 @@ import (
)
func main() {
// bool
fmt.Println(condition.Bool(false)) // false
fmt.Println(condition.Bool(true)) // true
// bool
result1 := condition.Bool(false)
result2 := condition.Bool(true)
fmt.Println(result1) // false
fmt.Println(result2) // true
// integer
fmt.Println(condition.Bool(0)) // false
fmt.Println(condition.Bool(1)) // true
// integer
result3 := condition.Bool(0)
result4 := condition.Bool(1)
fmt.Println(result3) // false
fmt.Println(result4) // true
// float
fmt.Println(condition.Bool(0.0)) // false
fmt.Println(condition.Bool(0.1)) // true
// string
result5 := condition.Bool("")
result6 := condition.Bool(" ")
fmt.Println(result5) // false
fmt.Println(result6) // true
// string
fmt.Println(condition.Bool("")) // false
fmt.Println(condition.Bool(" ")) // true
fmt.Println(condition.Bool("0")) // true
// slice
nums := []int{}
result7 := condition.Bool(nums)
// slice
var nums [2]int
fmt.Println(condition.Bool(nums)) // false
nums = [2]int{0, 1}
fmt.Println(condition.Bool(nums)) // true
nums = append(nums, 1, 2)
result8 := condition.Bool(nums)
fmt.Println(result7) // false
fmt.Println(result8) // true
// map
fmt.Println(condition.Bool(map[string]string{})) // false
fmt.Println(condition.Bool(map[string]string{"a": "a"})) // true
// struct
result9 = condition.Bool(struct{}{})
fmt.Println(result8) // false
// struct
fmt.Println(condition.Bool(struct{}{})) // false
fmt.Println(condition.Bool(time.Now())) // true
// Output:
// false
// true
// false
// true
// false
// true
// false
// true
// false
}
```
### <span id="And">And</span>
<p>Returns true if both a and b are truthy.</p>
@@ -111,10 +122,10 @@ import (
)
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
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
}
```
@@ -139,10 +150,10 @@ import (
)
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
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
}
```
@@ -167,10 +178,10 @@ import (
)
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
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
}
```
@@ -195,10 +206,10 @@ import (
)
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
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
}
```
@@ -222,10 +233,10 @@ import (
)
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
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
}
```
@@ -249,10 +260,10 @@ import (
)
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
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
}
```
@@ -277,10 +288,18 @@ import (
)
func main() {
trueValue := "1"
falseValue := "0"
conditionTrue := 2 > 1
result1 := condition.TernaryOperator(conditionTrue, 0, 1)
fmt.Println(condition.TernaryOperator(true, trueValue, falseValue)) // "1"
conditionFalse := 2 > 3
result2 := condition.TernaryOperator(conditionFalse, 0, 1)
fmt.Println(result1)
fmt.Println(result2)
// Output:
// 0
// 1
}
```

View File

@@ -45,7 +45,7 @@ slices和map的length大于0时返回true否则返回false<br/>
```go
func Bool[T any](value T) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -56,41 +56,51 @@ import (
)
func main() {
// bool
fmt.Println(condition.Bool(false)) // false
fmt.Println(condition.Bool(true)) // true
// bool
result1 := condition.Bool(false)
result2 := condition.Bool(true)
fmt.Println(result1) // false
fmt.Println(result2) // true
// integer
fmt.Println(condition.Bool(0)) // false
fmt.Println(condition.Bool(1)) // true
// integer
result3 := condition.Bool(0)
result4 := condition.Bool(1)
fmt.Println(result3) // false
fmt.Println(result4) // true
// float
fmt.Println(condition.Bool(0.0)) // false
fmt.Println(condition.Bool(0.1)) // true
// string
result5 := condition.Bool("")
result6 := condition.Bool(" ")
fmt.Println(result5) // false
fmt.Println(result6) // true
// string
fmt.Println(condition.Bool("")) // false
fmt.Println(condition.Bool(" ")) // true
fmt.Println(condition.Bool("0")) // true
// slice
nums := []int{}
result7 := condition.Bool(nums)
// slice
var nums [2]int
fmt.Println(condition.Bool(nums)) // false
nums = [2]int{0, 1}
fmt.Println(condition.Bool(nums)) // true
nums = append(nums, 1, 2)
result8 := condition.Bool(nums)
fmt.Println(result7) // false
fmt.Println(result8) // true
// map
fmt.Println(condition.Bool(map[string]string{})) // false
fmt.Println(condition.Bool(map[string]string{"a": "a"})) // true
// struct
result9 = condition.Bool(struct{}{})
fmt.Println(result8) // false
// struct
fmt.Println(condition.Bool(struct{}{})) // false
fmt.Println(condition.Bool(time.Now())) // true
// Output:
// false
// true
// false
// true
// false
// true
// false
// true
// false
}
```
### <span id="And">And</span>
<p>逻辑且操作当切仅当a和b都为true时返回true</p>
@@ -99,7 +109,7 @@ func main() {
```go
func And[T, U any](a T, b U) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -110,15 +120,13 @@ import (
)
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
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
}
```
### <span id="Or">Or</span>
<p>逻辑或操作当切仅当a和b都为false时返回false</p>
@@ -127,7 +135,7 @@ func main() {
```go
func Or[T, U any](a T, b U) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -138,15 +146,13 @@ import (
)
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
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
}
```
### <span id="Xor">Xor</span>
<p>逻辑异或操作a和b相同返回falsea和b不相同返回true</p>
@@ -155,7 +161,7 @@ func main() {
```go
func Xor[T, U any](a T, b U) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -166,15 +172,13 @@ import (
)
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
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
}
```
### <span id="Nor">Nor</span>
<p>异或的取反操作</p>
@@ -183,7 +187,7 @@ func main() {
```go
func Nor[T, U any](a T, b U) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -194,15 +198,13 @@ import (
)
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
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
}
```
### <span id="Xnor">Xnor</span>
<p>如果a和b都是真的或a和b均是假的则返回true。</p>
@@ -211,7 +213,7 @@ func main() {
```go
func Xnor[T, U any](a T, b U) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -222,10 +224,10 @@ import (
)
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
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
}
```
@@ -237,7 +239,7 @@ func main() {
```go
func Nand[T, U any](a T, b U) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -248,15 +250,13 @@ import (
)
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
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
}
```
### <span id="TernaryOperator">TernaryOperator</span>
<p>三元运算符</p>
@@ -265,7 +265,7 @@ func main() {
```go
func TernaryOperator[T, U any](isTrue T, ifValue U, elseValue U) U
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -276,10 +276,18 @@ import (
)
func main() {
trueValue := "1"
falseValue := "0"
conditionTrue := 2 > 1
result1 := condition.TernaryOperator(conditionTrue, 0, 1)
fmt.Println(condition.TernaryOperator(true, trueValue, falseValue)) // "1"
conditionFalse := 2 > 3
result2 := condition.TernaryOperator(conditionFalse, 0, 1)
fmt.Println(result1)
fmt.Println(result2)
// Output:
// 0
// 1
}
```

View File

@@ -40,8 +40,6 @@ import (
## Documentation
### <span id="ColorHexToRGB">ColorHexToRGB</span>
<p>Convert color hex to color rgb.</p>
@@ -63,12 +61,14 @@ import (
func main() {
colorHex := "#003366"
r, g, b := convertor.ColorHexToRGB(colorHex)
fmt.Println(r, g, b) //0,51,102
fmt.Println(r, g, b)
// Output:
// 0 51 102
}
```
### <span id="ColorRGBToHex">ColorRGBToHex</span>
<p>Convert color rgb to color hex.</p>
@@ -92,14 +92,15 @@ func main() {
r := 0
g := 51
b := 102
colorHex := convertor.ColorRGBToHex(r, g, b)
colorHex := ColorRGBToHex(r, g, b)
fmt.Println(colorHex) //#003366
fmt.Println(colorHex)
// Output:
// #003366
}
```
### <span id="ToBool">ToBool</span>
<p>Convert string to bool. Use strconv.ParseBool.</p>
@@ -120,22 +121,26 @@ import (
)
func main() {
v1, _ := convertor.ToBool("1")
fmt.Println(v1) //true
cases := []string{"1", "true", "True", "false", "False", "0", "123", "0.0", "abc"}
v2, _ := convertor.ToBool("true")
fmt.Println(v2) //true
for i := 0; i < len(cases); i++ {
result, _ := convertor.ToBool(cases[i])
fmt.Println(result)
}
v3, _ := convertor.ToBool("True")
fmt.Println(v3) //true
v4, _ := convertor.ToBool("123")
fmt.Println(v4) //false
// Output:
// true
// true
// true
// false
// false
// false
// false
// false
// false
}
```
### <span id="ToBytes">ToBytes</span>
<p>Convert value to byte slice.</p>
@@ -156,16 +161,18 @@ import (
)
func main() {
bytesData, err := convertor.ToBytes("0")
bytesData, err := convertor.ToBytes("abc")
if err != nil {
fmt.Println(err)
}
fmt.Println(bytesData) //[]bytes{3, 4, 0, 0}
fmt.Println(bytesData)
// Output:
// [97 98 99]
}
```
### <span id="ToChar">ToChar</span>
<p>Convert string to char slice.</p>
@@ -186,18 +193,21 @@ import (
)
func main() {
chars := convertor.ToChar("")
fmt.Println(chars) //[]string{""}
result1 := convertor.ToChar("")
result2 := convertor.ToChar("abc")
result3 := convertor.ToChar("1 2#3")
chars = convertor.ToChar("abc")
fmt.Println(chars) //[]string{"a", "b", "c"}
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
chars = convertor.ToChar("1 2#3")
fmt.Println(chars) //[]string{"1", " ", "2", "#", "3"}
// Output:
// []
// [a b c]
// [1 2 # 3]
}
```
### <span id="ToChannel">ToChannel</span>
<p>Convert a collection of elements to a read-only channel.</p>
@@ -219,23 +229,21 @@ import (
func main() {
ch := convertor.ToChannel([]int{1, 2, 3})
result1 := <-ch
result2 := <-ch
result3 := <-ch
val1, _ := <-ch
fmt.Println(val1) //1
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
val2, _ := <-ch
fmt.Println(val2) //2
val3, _ := <-ch
fmt.Println(val3) //3
_, ok := <-ch
fmt.Println(ok) //false
// Output:
// 1
// 2
// 3
}
```
### <span id="ToFloat">ToFloat</span>
<p>Convert value to a float64 value. If param is a invalid floatable, will return 0.0 and error. </p>
@@ -256,19 +264,30 @@ import (
)
func main() {
v, err := convertor.ToFloat("")
if err != nil {
fmt.Println(err) //strconv.ParseFloat: parsing "": invalid syntax
}
fmt.Println(v) //0
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)
v, _ = convertor.ToFloat("-.11")
fmt.Println(v) //-0.11
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
}
```
### <span id="ToInt">ToInt</span>
<p>Convert value to a int64 value. If param is a invalid intable, will return 0 and error. </p>
@@ -289,19 +308,27 @@ import (
)
func main() {
v, err := convertor.ToInt("")
if err != nil {
fmt.Println(err) //strconv.ParseInt: parsing "": invalid syntax
}
fmt.Println(v) //0
result1, _ := convertor.ToInt("123")
result2, _ := convertor.ToInt("-123")
result3, _ := convertor.ToInt(float64(12.3))
result4, err := convertor.ToInt("abc")
result5, _ := convertor.ToInt(true)
v, _ = convertor.ToFloat(1.12)
fmt.Println(v) //1
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
}
```
### <span id="ToJson">ToJson</span>
<p>Convert interface to json string. If param can't be converted, will return "" and error. </p>
@@ -322,14 +349,20 @@ import (
)
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}"
aMap := map[string]int{"a": 1, "b": 2, "c": 3}
result, err := ToJson(aMap)
if err != nil {
fmt.Printf("%v", err)
}
fmt.Println(result)
// Output:
// {"a":1,"b":2,"c":3}
}
```
### <span id="ToMap">ToMap</span>
<p>Convert a slice of structs to a map based on iteratee function. </p>
@@ -358,16 +391,18 @@ func main() {
{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) //{100: "Hello", 101: "Hi"}
fmt.Println(result)
// Output:
// map[100:Hello 101:Hi]
}
```
### <span id="ToPointer">ToPointer</span>
<p>Returns a pointer to passed value. </p>
@@ -389,11 +424,13 @@ import (
func main() {
result := convertor.ToPointer(123)
fmt.Println(*result) //123
fmt.Println(*result)
// Output:
// 123
}
```
### <span id="ToString">ToString</span>
<p>ToString convert value to string, for number, string, []byte, will convert to string. For other type (slice, map, array, struct) will call json.Marshal</p>
@@ -414,13 +451,33 @@ import (
)
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]"
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]
}
```
### <span id="StructToMap">StructToMap</span>
<p>Convert struct to map, only convert exported field, struct field tag `json` should be set.</p>
@@ -451,12 +508,13 @@ func main() {
}
pm, _ := convertor.StructToMap(p)
fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
fmt.Println(pm)
// Output:
// map[name:test]
}
```
### <span id="MapToSlice">MapToSlice</span>
<p>Convert a map to a slice based on iteratee function.</p>
@@ -508,12 +566,13 @@ import (
func main() {
byteData, _ := convertor.EncodeByte("abc")
fmt.Println(byteData) //[]byte{6, 12, 0, 3, 97, 98, 99}
fmt.Println(byteData)
// Output:
// [6 12 0 3 97 98 99]
}
```
### <span id="DecodeByte">DecodeByte</span>
<p>Decode byte data to target object. target should be a pointer instance.</p>
@@ -535,8 +594,16 @@ import (
func main() {
var result string
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
convertor.DecodeByte(byteData, &result)
fmt.Println(result) //"abc"
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
err := convertor.DecodeByte(byteData, &result)
if err != nil {
return
}
fmt.Println(result)
// Output:
// abc
}
```

View File

@@ -43,16 +43,15 @@ import (
## 文档
### <span id="ColorHexToRGB">ColorHexToRGB</span>
<p>颜色值十六进制转rgb</p>
<p>颜色值十六进制转rgb</p>
<b>函数签名:</b>
```go
func ColorHexToRGB(colorHex string) (red, green, blue int)
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -65,22 +64,24 @@ import (
func main() {
colorHex := "#003366"
r, g, b := convertor.ColorHexToRGB(colorHex)
fmt.Println(r, g, b) //0,51,102
fmt.Println(r, g, b)
// Output:
// 0 51 102
}
```
### <span id="ColorRGBToHex">ColorRGBToHex</span>
<p>颜色值rgb转十六进制</p>
<p>颜色值rgb转十六进制</p>
<b>函数签名:</b>
```go
func ColorRGBToHex(red, green, blue int) string
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -94,24 +95,25 @@ func main() {
r := 0
g := 51
b := 102
colorHex := convertor.ColorRGBToHex(r, g, b)
colorHex := ColorRGBToHex(r, g, b)
fmt.Println(colorHex) //#003366
fmt.Println(colorHex)
// Output:
// #003366
}
```
### <span id="ToBool">ToBool</span>
<p>字符串转布尔类型使用strconv.ParseBool</p>
<p>字符串转布尔类型使用strconv.ParseBool</p>
<b>函数签名:</b>
```go
func ToBool(s string) (bool, error)
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -122,32 +124,36 @@ import (
)
func main() {
v1, _ := convertor.ToBool("1")
fmt.Println(v1) //true
cases := []string{"1", "true", "True", "false", "False", "0", "123", "0.0", "abc"}
v2, _ := convertor.ToBool("true")
fmt.Println(v2) //true
for i := 0; i < len(cases); i++ {
result, _ := convertor.ToBool(cases[i])
fmt.Println(result)
}
v3, _ := convertor.ToBool("True")
fmt.Println(v3) //true
v4, _ := convertor.ToBool("123")
fmt.Println(v4) //false
// Output:
// true
// true
// true
// false
// false
// false
// false
// false
// false
}
```
### <span id="ToBytes">ToBytes</span>
<p>interface转字节切片.</p>
<p>Interface转字节切片</p>
<b>函数签名:</b>
```go
func ToBytes(data any) ([]byte, error)
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -158,26 +164,28 @@ import (
)
func main() {
bytesData, err := convertor.ToBytes("0")
bytesData, err := convertor.ToBytes("abc")
if err != nil {
fmt.Println(err)
}
fmt.Println(bytesData) //[]bytes{3, 4, 0, 0}
fmt.Println(bytesData)
// Output:
// [97 98 99]
}
```
### <span id="ToChar">ToChar</span>
<p>字符串转字符切片</p>
<p>字符串转字符切片</p>
<b>函数签名:</b>
```go
func ToChar(s string) []string
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -188,29 +196,31 @@ import (
)
func main() {
chars := convertor.ToChar("")
fmt.Println(chars) //[]string{""}
result1 := convertor.ToChar("")
result2 := convertor.ToChar("abc")
result3 := convertor.ToChar("1 2#3")
chars = convertor.ToChar("abc")
fmt.Println(chars) //[]string{"a", "b", "c"}
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
chars = convertor.ToChar("1 2#3")
fmt.Println(chars) //[]string{"1", " ", "2", "#", "3"}
// Output:
// []
// [a b c]
// [1 2 # 3]
}
```
### <span id="ToChannel">ToChannel</span>
<p>将切片转为只读channel</p>
<p>将切片转为只读channel</p>
<b>函数签名:</b>
```go
func ToChannel[T any](array []T) <-chan T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -222,33 +232,31 @@ import (
func main() {
ch := convertor.ToChannel([]int{1, 2, 3})
result1 := <-ch
result2 := <-ch
result3 := <-ch
val1, _ := <-ch
fmt.Println(val1) //1
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
val2, _ := <-ch
fmt.Println(val2) //2
val3, _ := <-ch
fmt.Println(val3) //3
_, ok := <-ch
fmt.Println(ok) //false
// Output:
// 1
// 2
// 3
}
```
### <span id="ToFloat">ToFloat</span>
<p>将interface转成float64类型如果参数无法转换会返回0和error</p>
<p>将interface转成float64类型如果参数无法转换会返回0和error</p>
<b>函数签名:</b>
```go
func ToFloat(value any) (float64, error)
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -259,29 +267,40 @@ import (
)
func main() {
v, err := convertor.ToFloat("")
if err != nil {
fmt.Println(err) //strconv.ParseFloat: parsing "": invalid syntax
}
fmt.Println(v) //0
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)
v, _ = convertor.ToFloat("-.11")
fmt.Println(v) //-0.11
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
}
```
### <span id="ToInt">ToInt</span>
<p>将interface转成int64类型如果参数无法转换会返回0和error</p>
<p>将interface转成int64类型如果参数无法转换会返回0和error</p>
<b>函数签名:</b>
```go
func ToInt(value any) (int64, error)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -292,29 +311,37 @@ import (
)
func main() {
v, err := convertor.ToInt("")
if err != nil {
fmt.Println(err) //strconv.ParseInt: parsing "": invalid syntax
}
fmt.Println(v) //0
result1, _ := convertor.ToInt("123")
result2, _ := convertor.ToInt("-123")
result3, _ := convertor.ToInt(float64(12.3))
result4, err := convertor.ToInt("abc")
result5, _ := convertor.ToInt(true)
v, _ = convertor.ToFloat(1.12)
fmt.Println(v) //1
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
}
```
### <span id="ToJson">ToJson</span>
<p>将interface转成json字符串如果参数无法转换会返回""和error</p>
<p>将interface转成json字符串如果参数无法转换会返回""和error</p>
<b>函数签名:</b>
```go
func ToJson(value any) (string, error)
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -325,24 +352,30 @@ import (
)
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}"
aMap := map[string]int{"a": 1, "b": 2, "c": 3}
result, err := ToJson(aMap)
if err != nil {
fmt.Printf("%v", err)
}
fmt.Println(result)
// Output:
// {"a":1,"b":2,"c":3}
}
```
### <span id="ToMap">ToMap</span>
<p>将切片转为map</p>
<p>将切片转为map</p>
<b>函数签名:</b>
```go
func ToMap[T any, K comparable, V any](array []T, iteratee func(T) (K, V)) map[K]V
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -361,26 +394,28 @@ func main() {
{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) //{100: "Hello", 101: "Hi"}
fmt.Println(result)
// Output:
// map[100:Hello 101:Hi]
}
```
### <span id="ToPointer">ToPointer</span>
<p>返回传入值的指针</p>
<p>返回传入值的指针</p>
<b>函数签名:</b>
```go
func ToPointer[T any](value T) *T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -392,22 +427,23 @@ import (
func main() {
result := convertor.ToPointer(123)
fmt.Println(*result) //123
fmt.Println(*result)
// Output:
// 123
}
```
### <span id="ToString">ToString</span>
<p>将值转换为字符串,对于数字、字符串、[]byte将转换为字符串。 对于其他类型(切片、映射、数组、结构)将调用 json.Marshal</p>
<p>将值转换为字符串,对于数字、字符串、[]byte将转换为字符串。 对于其他类型(切片、映射、数组、结构)将调用 json.Marshal</p>
<b>函数签名:</b>
```go
func ToString(value any) string
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -418,24 +454,43 @@ import (
)
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]"
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]
}
```
### <span id="StructToMap">StructToMap</span>
<p>将struct转成map只会转换struct中可导出的字段。struct中导出字段需要设置json tag标记</p>
<p>将struct转成map只会转换struct中可导出的字段。struct中导出字段需要设置json tag标记</p>
<b>函数签名:</b>
```go
func StructToMap(value any) (map[string]any, error)
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -456,22 +511,23 @@ func main() {
}
pm, _ := convertor.StructToMap(p)
fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
fmt.Println(pm)
// Output:
// map[name:test]
}
```
### <span id="MapToSlice">MapToSlice</span>
<p>map中key和value执行函数iteratee后转为切片</p>
<p>map中key和value执行函数iteratee后转为切片</p>
<b>函数签名:</b>
```go
func MapToSlice[T any, K comparable, V any](aMap map[K]V, iteratee func(K, V) T) []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -491,18 +547,16 @@ func main() {
}
```
### <span id="EncodeByte">EncodeByte</span>
<p>将data编码成字节切片</p>
<p>将data编码成字节切片</p>
<b>函数签名:</b>
```go
func EncodeByte(data any) ([]byte, error)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -514,22 +568,23 @@ import (
func main() {
byteData, _ := convertor.EncodeByte("abc")
fmt.Println(byteData) //[]byte{6, 12, 0, 3, 97, 98, 99}
fmt.Println(byteData)
// Output:
// [6 12 0 3 97 98 99]
}
```
### <span id="DecodeByte">DecodeByte</span>
<p>解码字节切片到目标对象,目标对象需要传入一个指针实例</p>
<p>解码字节切片到目标对象,目标对象需要传入一个指针实例</p>
<b>函数签名:</b>
```go
func DecodeByte(data []byte, target any) error
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -541,8 +596,16 @@ import (
func main() {
var result string
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
convertor.DecodeByte(byteData, &result)
fmt.Println(result) //"abc"
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
err := convertor.DecodeByte(byteData, &result)
if err != nil {
return
}
fmt.Println(result)
// Output:
// abc
}
```

View File

@@ -61,8 +61,6 @@ import (
## Documentation
### <span id="AesEcbEncrypt">AesEcbEncrypt</span>
<p>Encrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -83,16 +81,19 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefghijklmnop"
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted))
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="AesEcbDecrypt">AesEcbDecrypt</span>
<p>Decrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -113,16 +114,19 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefghijklmnop"
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="AesCbcEncrypt">AesCbcEncrypt</span>
<p>Encrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -143,16 +147,19 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefghijklmnop"
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted))
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="AesCbcDecrypt">AesCbcDecrypt</span>
<p>Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -174,16 +181,19 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefghijklmnop"
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="AesCtrCrypt">AesCtrCrypt</span>
<p>Encrypt or decrypt data with key use AES CTR algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -205,17 +215,19 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefghijklmnop"
encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key))
decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="AesCfbEncrypt">AesCfbEncrypt</span>
<p>Encrypt data with key use AES CFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -237,15 +249,19 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefghijklmnop"
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted))
decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="AesCfbDecrypt">AesCfbDecrypt</span>
<p>Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -267,16 +283,19 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefghijklmnop"
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="AesOfbEncrypt">AesOfbEncrypt</span>
<p>Enecrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -298,15 +317,18 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefghijklmnop"
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted))
decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="AesCfbDecrypt">AesOfbDecrypt</span>
<p>Decrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -328,17 +350,19 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefghijklmnop"
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
decrypted := cryptor.AesOfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="Base64StdEncode">Base64StdEncode</span>
<p>Encode string with base64 encoding.</p>
@@ -359,13 +383,13 @@ import (
)
func main() {
base64Str := cryptor.Base64StdEncode("hello world")
fmt.Println(base64Str) //aGVsbG8gd29ybGQ=
base64Str := cryptor.Base64StdEncode("hello")
fmt.Println(base64Str)
// Output:
// aGVsbG8=
}
```
### <span id="Base64StdDecode">Base64StdDecode</span>
<p>Decode a base64 encoded string.</p>
@@ -387,13 +411,14 @@ import (
)
func main() {
str := cryptor.Base64StdDecode("aGVsbG8gd29ybGQ=")
fmt.Println(str) //hello world
str := cryptor.Base64StdDecode("aGVsbG8=")
fmt.Println(str)
// Output:
// hello
}
```
### <span id="DesEcbEncrypt">DesEcbEncrypt</span>
<p>Encrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p>
@@ -415,16 +440,19 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefgh"
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted))
decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="DesEcbDecrypt">DesEcbDecrypt</span>
<p>Decrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p>
@@ -446,17 +474,20 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefgh"
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byt(key)
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="DesCbcEncrypt">DesCbcEncrypt</span>
<p>Encrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
@@ -478,16 +509,19 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefgh"
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key)
fmt.Println(string(encrypted))
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="DesCbcDecrypt">DesCbcDecrypt</span>
<p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
@@ -509,17 +543,18 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefgh"
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key)
decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="DesCtrCrypt">DesCtrCrypt</span>
<p>Encrypt or decrypt data with key use DES CTR algorithm. Length of `key` param should be 8.</p>
@@ -541,17 +576,19 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefgh"
encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key))
decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="DesCfbEncrypt">DesCfbEncrypt</span>
<p>Encrypt data with key use DES CFB algorithm. Length of `key` param should be 8.</p>
@@ -573,15 +610,18 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefgh"
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key)
fmt.Println(string(encrypted))
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="DesCfbDecrypt">DesCfbDecrypt</span>
<p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
@@ -603,16 +643,18 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefgh"
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key)
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="DesOfbEncrypt">DesOfbEncrypt</span>
<p>Enecrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p>
@@ -634,15 +676,18 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefgh"
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted))
decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="DesOfbDecrypt">DesOfbDecrypt</span>
<p>Decrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p>
@@ -664,17 +709,19 @@ import (
)
func main() {
data := "hello world"
data := "hello"
key := "abcdefgh"
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="HmacMd5">HmacMd5</span>
<p>Get the md5 hmac hash of string.</p>
@@ -696,13 +743,16 @@ import (
)
func main() {
s := cryptor.HmacMd5("hello world", "12345"))
fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d
str := "hello"
key := "12345"
hms := cryptor.HmacMd5(str, key)
fmt.Println(hms)
// Output:
// e834306eab892d872525d4918a7a639a
}
```
### <span id="HmacSha1">HmacSha1</span>
<p>Get the sha1 hmac hash of string.</p>
@@ -724,13 +774,16 @@ import (
)
func main() {
s := cryptor.HmacSha1("hello world", "12345"))
fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd
str := "hello"
key := "12345"
hms := cryptor.HmacSha1(str, key)
fmt.Println(hms)
// Output:
// 5c6a9db0cccb92e36ed0323fd09b7f936de9ace0
}
```
### <span id="HmacSha256">HmacSha256</span>
<p>Get the sha256 hmac hash of string</p>
@@ -752,13 +805,17 @@ import (
)
func main() {
s := cryptor.HmacSha256("hello world", "12345"))
fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8
str := "hello"
key := "12345"
hms := cryptor.HmacSha256(str, key)
fmt.Println(hms)
// Output:
// 315bb93c4e989862ba09cb62e05d73a5f376cb36f0d786edab0c320d059fde75
}
```
### <span id="HmacSha512">HmacSha512</span>
<p>Get the sha512 hmac hash of string.</p>
@@ -780,14 +837,18 @@ import (
)
func main() {
s := cryptor.HmacSha512("hello world", "12345"))
fmt.Println(s)
//5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175
str := "hello"
key := "12345"
hms := cryptor.HmacSha512(str, key)
fmt.Println(hms)
// Output:
// dd8f1290a9dd23d354e2526d9a2e9ce8cffffdd37cb320800d1c6c13d2efc363288376a196c5458daf53f8e1aa6b45a6d856303d5c0a2064bff9785861d48cfc
}
```
### <span id="Md5String">Md5String</span>
<p>Get the md5 value of string.</p>
@@ -809,13 +870,16 @@ import (
)
func main() {
s := cryptor.Md5String("hello"))
fmt.Println(s) //5d41402abc4b2a76b9719d911017c592
str := "hello"
md5Str := cryptor.Md5String(str)
fmt.Println(md5Str)
// Output:
// 5d41402abc4b2a76b9719d911017c592
}
```
### <span id="Md5File">Md5File</span>
<p>Get the md5 value of file.</p>
@@ -842,8 +906,6 @@ func main() {
}
```
### <span id="Sha1">Sha1</span>
<p>Get the sha1 value of string.</p>
@@ -865,13 +927,16 @@ import (
)
func main() {
s := cryptor.Sha1("hello world"))
fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
str := "hello"
result := cryptor.Sha1(str)
fmt.Println(result)
// Output:
// aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
}
```
### <span id="Sha256">Sha256</span>
<p>Get the sha256 value of string.</p>
@@ -893,13 +958,16 @@ import (
)
func main() {
s := cryptor.Sha256("hello world"))
fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
str := "hello"
result := cryptor.Sha256(str)
fmt.Println(result)
// Output:
// 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
}
```
### <span id="Sha512">Sha512</span>
<p>Get the sha512 value of string.</p>
@@ -921,13 +989,16 @@ import (
)
func main() {
s := cryptor.Sha512("hello world"))
fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
str := "hello"
result := cryptor.Sha512(str)
fmt.Println(result)
// Output:
// 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
}
```
### <span id="GenerateRsaKey">GenerateRsaKey</span>
<p>Create the rsa public and private key file in current directory.</p>
@@ -956,8 +1027,6 @@ func main() {
}
```
### <span id="RsaEncrypt">RsaEncrypt</span>
<p>Encrypt data with public key file useing ras algorithm.</p>
@@ -981,19 +1050,21 @@ import (
func main() {
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
if err != nil {
fmt.Println(err)
return
}
data := []byte("hello world")
data := []byte("hello")
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
fmt.Println(string(decrypted)) //hello world
fmt.Println(string(decrypted))
// Output:
// hello
}
```
### <span id="RsaDecrypt">RsaDecrypt</span>
<p>Decrypt data with private key file useing ras algorithm.</p>
@@ -1017,14 +1088,17 @@ import (
func main() {
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
if err != nil {
fmt.Println(err)
return
}
data := []byte("hello world")
data := []byte("hello")
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
fmt.Println(string(decrypted)) //hello world
fmt.Println(string(decrypted))
// Output:
// hello
}
```

File diff suppressed because it is too large Load Diff

View File

@@ -46,7 +46,7 @@ import (
func NewHashMap() *HashMap
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -72,7 +72,7 @@ func main() {
func NewHashMapWithCapacity(size, capacity uint64) *HashMap
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -98,7 +98,7 @@ func main() {
func (hm *HashMap) Get(key any) any
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -126,7 +126,7 @@ func main() {
func (hm *HashMap) Put(key any, value any) any
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -155,7 +155,7 @@ func main() {
func (hm *HashMap) Delete(key any)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -187,7 +187,7 @@ func main() {
func (hm *HashMap) Contains(key any) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -217,7 +217,7 @@ func main() {
func (hm *HashMap) Iterate(iteratee func(key, value any))
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -252,7 +252,7 @@ func main() {
func (hm *HashMap) Keys() []any
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -284,7 +284,7 @@ func main() {
func (hm *HashMap) Values() []any
```
<b>例:</b>
<b>例:</b>
```go
package main

View File

@@ -48,7 +48,7 @@ type MaxHeap[T any] struct {
}
func NewMaxHeap[T any](comparator lancetconstraints.Comparator) *MaxHeap[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -89,7 +89,7 @@ func main() {
```go
func (h *MaxHeap[T]) Push(value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -136,7 +136,7 @@ func main() {
```go
func (h *MaxHeap[T]) Pop() (T, bool)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -184,7 +184,7 @@ func main() {
```go
func (h *MaxHeap[T]) Peek() (T, bool)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -232,7 +232,7 @@ func main() {
```go
func (h *MaxHeap[T]) Data() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -277,7 +277,7 @@ func main() {
```go
func (h *MaxHeap[T]) Size() int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -323,7 +323,7 @@ func main() {
```go
func (h *MaxHeap[T]) PrintStructure()
```
<b>例:</b>
<b>例:</b>
```go
package main

View File

@@ -81,7 +81,7 @@ type SinglyLink[T any] struct {
}
func NewSinglyLink[T any]() *SinglyLink[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -107,7 +107,7 @@ func main() {
```go
func (link *SinglyLink[T]) Values() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -139,7 +139,7 @@ func main() {
```go
func (link *SinglyLink[T]) InsertAt(index int, value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -174,7 +174,7 @@ func main() {
```go
func (link *SinglyLink[T]) InsertAtHead(value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -206,7 +206,7 @@ func main() {
```go
func (link *SinglyLink[T]) InsertAtTail(value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -237,7 +237,7 @@ func main() {
```go
func (link *SinglyLink[T]) DeleteAt(index int)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -271,7 +271,7 @@ func main() {
```go
func (link *SinglyLink[T]) DeleteAtHead()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -306,7 +306,7 @@ func main() {
```go
func (link *SinglyLink[T]) DeleteAtTail()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -339,7 +339,7 @@ func main() {
```go
func (link *SinglyLink[T]) DeleteValue(value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -373,7 +373,7 @@ func main() {
```go
func (link *SinglyLink[T]) Reverse()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -405,7 +405,7 @@ func main() {
```go
func (link *SinglyLink[T]) GetMiddleNode() *datastructure.LinkNode[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -437,7 +437,7 @@ func main() {
```go
func (link *SinglyLink[T]) Size() int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -468,7 +468,7 @@ func main() {
```go
func (link *SinglyLink[T]) IsEmpty() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -500,7 +500,7 @@ func main() {
```go
func (link *SinglyLink[T]) Clear()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -533,7 +533,7 @@ func main() {
```go
func (link *SinglyLink[T]) Clear()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -576,7 +576,7 @@ type DoublyLink[T any] struct {
}
func NewDoublyLink[T any]() *DoublyLink[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -602,7 +602,7 @@ func main() {
```go
func (link *DoublyLink[T]) Values() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -634,7 +634,7 @@ func main() {
```go
func (link *DoublyLink[T]) InsertAt(index int, value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -669,7 +669,7 @@ func main() {
```go
func (link *DoublyLink[T]) InsertAtHead(value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -701,7 +701,7 @@ func main() {
```go
func (link *DoublyLink[T]) InsertAtTail(value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -732,7 +732,7 @@ func main() {
```go
func (link *DoublyLink[T]) DeleteAt(index int)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -766,7 +766,7 @@ func main() {
```go
func (link *DoublyLink[T]) DeleteAtHead()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -801,7 +801,7 @@ func main() {
```go
func (link *DoublyLink[T]) DeleteAtTail()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -835,7 +835,7 @@ func main() {
```go
func (link *DoublyLink[T]) Reverse()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -867,7 +867,7 @@ func main() {
```go
func (link *DoublyLink[T]) GetMiddleNode() *datastructure.LinkNode[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -899,7 +899,7 @@ func main() {
```go
func (link *DoublyLink[T]) Size() int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -930,7 +930,7 @@ func main() {
```go
func (link *DoublyLink[T]) IsEmpty() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -962,7 +962,7 @@ func main() {
```go
func (link *DoublyLink[T]) Clear()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -995,7 +995,7 @@ func main() {
```go
func (link *DoublyLink[T]) Clear()
```
<b>例:</b>
<b>例:</b>
```go
package main

View File

@@ -47,6 +47,13 @@ import (
- [Unique](#Unique)
- [Union](#Union)
- [Intersection](#Intersection)
- [Difference](#Difference)
- [SymmetricDifference](#SymmetricDifference)
- [RetainAll](#RetainAll)
- [DeleteAll](#DeleteAll)
- [ForEach](#ForEach)
- [Iterator](#Iterator)
- [ListToMap](#ListToMap)
- [SubList](#SubList)
- [DeleteIf](#DeleteIf)
@@ -62,7 +69,7 @@ NewList function return a list pointer</p>
```go
type List[T any] struct {
data []T
data []T
}
func NewList[T any](data []T) *List[T]
```
@@ -671,8 +678,8 @@ import (
)
func main() {
data := make([]int, 0, 100)
data := make([]int, 0, 100)
li := list.NewList(data)
fmt.Println(li.Cap()) // 100
@@ -828,6 +835,233 @@ func main() {
### <span id="Difference">Difference</span>
<p>Return a list whose element in the original list, not in the given list.</p>
<b>Signature:</b>
```go
func (l *List[T]) Difference(other *List[T]) *List[T]
```
<b>Example:</b>
```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
}
```
### <span id="SymmetricDifference">SymmetricDifference</span>
<p>Oppoiste operation of intersection function.</p>
<b>Signature:</b>
```go
func (l *List[T]) SymmetricDifference(other *List[T]) *List[T]
```
<b>Example:</b>
```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
}
```
### <span id="RetainAll">RetainAll</span>
<p>Retains only the elements in this list that are contained in the given list.</p>
<b>Signature:</b>
```go
func (l *List[T]) RetainAll(list *List[T]) bool
```
<b>Example:</b>
```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
}
```
### <span id="DeleteAll">DeleteAll</span>
<p>Removes from this list all of its elements that are contained in the given list.</p>
<b>Signature:</b>
```go
func (l *List[T]) DeleteAll(list *List[T]) bool
```
<b>Example:</b>
```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
}
```
### <span id="ForEach">ForEach</span>
<p>Performs the given action for each element of the list.</p>
<b>Signature:</b>
```go
func (l *List[T]) ForEach(consumer func(T))
```
<b>Example:</b>
```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
}
```
### <span id="Iterator">Iterator</span>
<p>Returns an iterator over the elements in this list in proper sequence.</p>
<b>Signature:</b>
```go
func (l *List[T]) Iterator() iterator.Iterator[T]
```
<b>Example:</b>
```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
}
```
### <span id="ListToMap">ListToMap</span>
<p>Converts a list to a map based on iteratee function.</p>
<b>Signature:</b>
```go
func ListToMap[T any, K comparable, V any](list *List[T], iteratee func(T) (K, V)) map[K]V
```
<b>Example:</b>
```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}
}
```
### <span id="SubList">SubList</span>
<p>SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.</p>
@@ -876,9 +1110,9 @@ import (
)
func main() {
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
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}
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
fmt.Println(l.Data()) // []int{2, 3, 4}
}
```

View File

@@ -34,7 +34,6 @@ import (
- [PopLast](#PopLast)
- [DeleteAt](#DeleteAt)
- [InsertAt](#InsertAt)
- [UpdateAt](#UpdateAt)
- [Equal](#Equal)
- [IsEmpty](#IsEmpty)
@@ -48,6 +47,13 @@ import (
- [Unique](#Unique)
- [Union](#Union)
- [Intersection](#Intersection)
- [Difference](#Difference)
- [SymmetricDifference](#SymmetricDifference)
- [RetainAll](#RetainAll)
- [DeleteAll](#DeleteAll)
- [ForEach](#ForEach)
- [Iterator](#Iterator)
- [ListToMap](#ListToMap)
- [SubList](#SubList)
- [DeleteIf](#DeleteIf)
@@ -62,11 +68,11 @@ import (
```go
type List[T any] struct {
data []T
data []T
}
func NewList[T any](data []T) *List[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -92,7 +98,7 @@ func main() {
```go
func (l *List[T]) Contain(value T) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -121,7 +127,7 @@ func main() {
```go
func (l *List[T]) Data() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -150,7 +156,7 @@ func main() {
```go
func (l *List[T]) ValueOf(index int) (*T, bool)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -180,7 +186,7 @@ func main() {
```go
func (l *List[T]) IndexOf(value T) int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -207,7 +213,7 @@ func main() {
```go
func (l *List[T]) LastIndexOf(value T) int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -233,7 +239,7 @@ func main() {
```go
func (l *List[T]) IndexOfFunc(f func(T) bool) int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -259,7 +265,7 @@ func main() {
```go
func (l *List[T]) LastIndexOfFunc(f func(T) bool) int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -287,7 +293,7 @@ func main() {
```go
func (l *List[T]) Push(value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -316,7 +322,7 @@ func main() {
```go
func (l *List[T]) PopFirst() (*T, bool)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -348,7 +354,7 @@ func main() {
```go
func (l *List[T]) PopLast() (*T, bool)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -379,7 +385,7 @@ func main() {
```go
func (l *List[T]) DeleteAt(index int)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -417,7 +423,7 @@ func main() {
```go
func (l *List[T]) InsertAt(index int, value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -454,7 +460,7 @@ func main() {
```go
func (l *List[T]) UpdateAt(index int, value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -487,7 +493,7 @@ func main() {
```go
func (l *List[T]) Equal(other *List[T]) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -517,7 +523,7 @@ func main() {
```go
func (l *List[T]) IsEmpty() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -547,7 +553,7 @@ func main() {
```go
func (l *List[T]) Clear()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -575,7 +581,7 @@ func main() {
```go
func (l *List[T]) Clone() *List[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -604,7 +610,7 @@ func main() {
```go
func (l *List[T]) Merge(other *List[T]) *List[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -633,7 +639,7 @@ func main() {
```go
func (l *List[T]) Size() int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -660,7 +666,7 @@ func main() {
```go
func (l *List[T]) Cap() int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -671,8 +677,8 @@ import (
)
func main() {
data := make([]int, 0, 100)
data := make([]int, 0, 100)
li := list.NewList(data)
fmt.Println(li.Cap()) // 100
@@ -689,7 +695,7 @@ func main() {
```go
func (l *List[T]) Swap(i, j int)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -718,7 +724,7 @@ func main() {
```go
func (l *List[T]) Reverse()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -747,7 +753,7 @@ func main() {
```go
func (l *List[T]) Unique()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -776,7 +782,7 @@ func main() {
```go
func (l *List[T]) Union(other *List[T]) *List[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -806,7 +812,7 @@ func main() {
```go
func (l *List[T]) Intersection(other *List[T]) *List[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -826,16 +832,244 @@ func main() {
```
### <span id="Difference">Difference</span>
<p>差集运算。</p>
<b>函数签名:</b>
```go
func (l *List[T]) Difference(other *List[T]) *List[T]
```
<b>示例:</b>
```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
}
```
### <span id="SymmetricDifference">SymmetricDifference</span>
<p>对称差集运算。</p>
<b>函数签名:</b>
```go
func (l *List[T]) SymmetricDifference(other *List[T]) *List[T]
```
<b>示例:</b>
```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
}
```
### <span id="RetainAll">RetainAll</span>
<p>仅保留列表中包含在给定列表中的元素。</p>
<b>函数签名:</b>
```go
func (l *List[T]) RetainAll(list *List[T]) bool
```
<b>示例:</b>
```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
}
```
### <span id="DeleteAll">DeleteAll</span>
<p>从列表中删除给定列表中包含的所有元素。</p>
<b>函数签名:</b>
```go
func (l *List[T]) DeleteAll(list *List[T]) bool
```
<b>示例:</b>
```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
}
```
### <span id="ForEach">ForEach</span>
<p>对列表的每个元素执行给定的操作。</p>
<b>函数签名:</b>
```go
func (l *List[T]) ForEach(consumer func(T))
```
<b>示例:</b>
```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
}
```
### <span id="Iterator">Iterator</span>
<p>按顺序返回列表中元素的迭代器。</p>
<b>函数签名:</b>
```go
func (l *List[T]) Iterator() iterator.Iterator[T]
```
<b>示例:</b>
```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
}
```
### <span id="ListToMap">ListToMap</span>
<p>基于iteratee函数将列表转换为映射map。</p>
<b>函数签名:</b>
```go
func ListToMap[T any, K comparable, V any](list *List[T], iteratee func(T) (K, V)) map[K]V
```
<b>示例:</b>
```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}
}
```
### <span id="SubList">SubList</span>
<p>SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.</p>
<p>返回指定的fromIndex包含和toIndex不包含之间的原始列表的子列表。</p>
<b>函数签名:</b>
```go
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -863,7 +1097,7 @@ func main() {
```go
func (l *List[T]) DeleteIf(f func(T) bool) int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -874,9 +1108,9 @@ import (
)
func main() {
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
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}
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
fmt.Println(l.Data()) // []int{2, 3, 4}
}
```

View File

@@ -99,7 +99,7 @@ type ArrayQueue[T any] struct {
size int
}
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -125,7 +125,7 @@ func main() {
```go
func (q *ArrayQueue[T]) Data() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -152,7 +152,7 @@ func main() {
```go
func (q *ArrayQueue[T]) Enqueue(item T) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -183,7 +183,7 @@ func main() {
```go
func (q *ArrayQueue[T]) Dequeue() (T, bool)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -215,7 +215,7 @@ func main() {
```go
func (q *ArrayQueue[T]) Front() T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -247,7 +247,7 @@ func main() {
```go
func (q *ArrayQueue[T]) Back() T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -278,7 +278,7 @@ func main() {
```go
func (q *ArrayQueue[T]) Size() int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -308,7 +308,7 @@ func main() {
```go
func (q *ArrayQueue[T]) IsEmpty() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -341,7 +341,7 @@ func main() {
```go
func (q *ArrayQueue[T]) IsFull() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -373,7 +373,7 @@ func main() {
```go
func (q *ArrayQueue[T]) Clear()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -404,7 +404,7 @@ func main() {
```go
func (q *ArrayQueue[T]) Contain(value T) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -448,7 +448,7 @@ type QueueNode[T any] struct {
Next *QueueNode[T]
}
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -474,7 +474,7 @@ func main() {
```go
func (q *LinkedQueue[T]) Data() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -501,7 +501,7 @@ func main() {
```go
func (q *LinkedQueue[T]) Enqueue(value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -532,7 +532,7 @@ func main() {
```go
func (q *LinkedQueue[T]) Dequeue() (T, error)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -564,7 +564,7 @@ func main() {
```go
func (q *LinkedQueue[T]) Front() (*T, error)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -596,7 +596,7 @@ func main() {
```go
func (q *LinkedQueue[T]) Back() (*T, error)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -627,7 +627,7 @@ func main() {
```go
func (q *LinkedQueue[T]) Size() int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -657,7 +657,7 @@ func main() {
```go
func (q *LinkedQueue[T]) IsEmpty() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -690,7 +690,7 @@ func main() {
```go
func (q *LinkedQueue[T]) Clear()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -721,7 +721,7 @@ func main() {
```go
func (q *LinkedQueue[T]) Contain(value T) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -763,7 +763,7 @@ type CircularQueue[T any] struct {
capacity int
}
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -789,7 +789,7 @@ func main() {
```go
func (q *CircularQueue[T]) Data() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -816,7 +816,7 @@ func main() {
```go
func (q *CircularQueue[T]) Enqueue(value T) error
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -847,7 +847,7 @@ func main() {
```go
func (q *CircularQueue[T]) Dequeue() (*T, bool)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -880,7 +880,7 @@ func main() {
```go
func (q *CircularQueue[T]) Front() T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -912,7 +912,7 @@ func main() {
```go
func (q *CircularQueue[T]) Back() T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -943,7 +943,7 @@ func main() {
```go
func (q *CircularQueue[T]) Size() int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -973,7 +973,7 @@ func main() {
```go
func (q *CircularQueue[T]) IsEmpty() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -1006,7 +1006,7 @@ func main() {
```go
func (q *CircularQueue[T]) IsFull() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -1038,7 +1038,7 @@ func main() {
```go
func (q *CircularQueue[T]) Clear()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -1069,7 +1069,7 @@ func main() {
```go
func (q *CircularQueue[T]) Contain(value T) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -1108,7 +1108,7 @@ type PriorityQueue[T any] struct {
comparator lancetconstraints.Comparator
}
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -1134,7 +1134,7 @@ func main() {
```go
func (q *PriorityQueue[T]) Data() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -1161,7 +1161,7 @@ func main() {
```go
func (q *PriorityQueue[T]) Enqueue(item T) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -1207,7 +1207,7 @@ func main() {
```go
func (q *PriorityQueue[T]) Dequeue() (T, bool)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -1254,7 +1254,7 @@ func main() {
```go
func (q *PriorityQueue[T]) IsEmpty() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -1301,7 +1301,7 @@ func main() {
```go
func (q *PriorityQueue[T]) IsFull() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -1348,7 +1348,7 @@ func main() {
```go
func (q *PriorityQueue[T]) Size() int
```
<b>例:</b>
<b>例:</b>
```go
package main

View File

@@ -55,7 +55,7 @@ import (
type Set[T comparable] map[T]bool
func NewSet[T comparable](items ...T) Set[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -81,7 +81,7 @@ func main() {
```go
func NewSetFromSlice[T comparable](items []T) Set[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -107,7 +107,7 @@ func main() {
```go
func (s Set[T]) Values() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -134,7 +134,7 @@ func main() {
```go
func (s Set[T]) Add(items ...T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -161,7 +161,7 @@ func main() {
```go
func (s Set[T]) AddIfNotExist(item T) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -193,7 +193,7 @@ func main() {
```go
func (s Set[T]) AddIfNotExistBy(item T, checker func(element T) bool) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -232,7 +232,7 @@ func main() {
```go
func (s Set[T]) Delete(items ...T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -261,7 +261,7 @@ func main() {
```go
func (s Set[T]) Contain(item T) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -291,7 +291,7 @@ func main() {
```go
func (s Set[T]) ContainAll(other Set[T]) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -321,7 +321,7 @@ func main() {
```go
func (s Set[T]) Size() int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -348,7 +348,7 @@ func main() {
```go
func (s Set[T]) Clone() Set[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -378,7 +378,7 @@ func main() {
```go
func (s Set[T]) Equal(other Set[T]) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -408,7 +408,7 @@ func main() {
```go
func (s Set[T]) Iterate(fn func(item T))
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -439,7 +439,7 @@ func main() {
```go
func (s Set[T]) IsEmpty() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -468,7 +468,7 @@ func main() {
```go
func (s Set[T]) Union(other Set[T]) Set[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -497,7 +497,7 @@ func main() {
```go
func (s Set[T]) Intersection(other Set[T]) Set[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -525,7 +525,7 @@ func main() {
```go
func (s Set[T]) SymmetricDifference(other Set[T]) Set[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -556,7 +556,7 @@ func main() {
```go
func (s Set[T]) Minus(comparedSet Set[T]) Set[T]
```
<b>例:</b>
<b>例:</b>
```go
package main

View File

@@ -64,7 +64,7 @@ type ArrayStack[T any] struct {
}
func NewArrayStack[T any]() *ArrayStack[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -91,7 +91,7 @@ func main() {
```go
func (s *ArrayStack[T]) Push(value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -122,7 +122,7 @@ func main() {
```go
func (s *ArrayStack[T]) Pop() (*T, error)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -157,7 +157,7 @@ func main() {
```go
func (s *ArrayStack[T]) Peak() (*T, error)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -192,7 +192,7 @@ func main() {
```go
func (s *ArrayStack[T]) Data() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -223,7 +223,7 @@ func main() {
```go
func (s *ArrayStack[T]) Size() int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -254,7 +254,7 @@ func main() {
```go
func (s *ArrayStack[T]) IsEmpty() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -287,7 +287,7 @@ func main() {
```go
func (s *ArrayStack[T]) Clear()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -331,7 +331,7 @@ type LinkedStack[T any] struct {
}
func NewLinkedStack[T any]() *LinkedStack[T]
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -358,7 +358,7 @@ func main() {
```go
func (s *LinkedStack[T]) Push(value T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -389,7 +389,7 @@ func main() {
```go
func (s *LinkedStack[T]) Pop() (*T, error)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -424,7 +424,7 @@ func main() {
```go
func (s *LinkedStack[T]) Peak() (*T, error)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -459,7 +459,7 @@ func main() {
```go
func (s *LinkedStack[T]) Data() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -490,7 +490,7 @@ func main() {
```go
func (s *LinkedStack[T]) Size() int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -521,7 +521,7 @@ func main() {
```go
func (s *LinkedStack[T]) IsEmpty() bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -554,7 +554,7 @@ func main() {
```go
func (s *LinkedStack[T]) Clear()
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -588,7 +588,7 @@ func main() {
```go
func (s *LinkedStack[T]) Print()
```
<b>例:</b>
<b>例:</b>
```go
package main

View File

@@ -62,7 +62,7 @@ type TreeNode[T any] struct {
Right *TreeNode[T]
}
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -103,7 +103,7 @@ func main() {
```go
func (t *BSTree[T]) Insert(data T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -149,7 +149,7 @@ func main() {
```go
func (t *BSTree[T]) Delete(data T)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -197,7 +197,7 @@ func main() {
```go
func (t *BSTree[T]) PreOrderTraverse() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -243,7 +243,7 @@ func main() {
```go
func (t *BSTree[T]) InOrderTraverse() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -289,7 +289,7 @@ func main() {
```go
func (t *BSTree[T]) PostOrderTraverse() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -335,7 +335,7 @@ func main() {
```go
func (t *BSTree[T]) LevelOrderTraverse() []T
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -381,7 +381,7 @@ func main() {
```go
func (t *BSTree[T]) Depth() int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -427,7 +427,7 @@ func main() {
```go
func (t *BSTree[T]) HasSubTree(subTree *BSTree[T]) bool
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -479,7 +479,7 @@ func main() {
```go
func (t *BSTree[T]) Print()
```
<b>例:</b>
<b>例:</b>
```go
package main

View File

@@ -1,16 +1,18 @@
# Datetime
Package datetime supports date and time format and compare.
<div STYLE="page-break-after: always;"></div>
## 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)
- [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)
<div STYLE="page-break-after: always;"></div>
## Usage:
```go
import (
"github.com/duke-git/lancet/v2/datetime"
@@ -20,66 +22,67 @@ import (
<div STYLE="page-break-after: always;"></div>
## 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)
- [NewUnixNow](#NewUnixNow)
- [NewUnix](#NewUnix)
- [NewFormat](#NewFormat)
- [NewISO8601](#NewISO8601)
- [ToUnix](#ToUnix)
- [ToFormat](#ToFormat)
- [ToFormatForTpl](#ToFormatForTpl)
- [ToIso8601](#ToIso8601)
- [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)
- [NewUnixNow](#NewUnixNow)
- [NewUnix](#NewUnix)
- [NewFormat](#NewFormat)
- [NewISO8601](#NewISO8601)
- [ToUnix](#ToUnix)
- [ToFormat](#ToFormat)
- [ToFormatForTpl](#ToFormatForTpl)
- [ToIso8601](#ToIso8601)
<div STYLE="page-break-after: always;"></div>
## 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
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
### <span id="AddDay">AddDay</span>
<p>Add or sub days to time.</p>
<b>Signature:</b>
@@ -87,6 +90,7 @@ import (
```go
func AddDay(t time.Time, day int64) time.Time
```
<b>Example:</b>
```go
@@ -100,15 +104,24 @@ import (
func main() {
now := time.Now()
after2Days := datetime.AddDay(now, 2)
before2Days := datetime.AddDay(now, -2)
fmt.Println(after2Days, before2Days)
tomorrow := datetime.AddDay(now, 1)
diff1 := tomorrow.Sub(now)
yesterday := datetime.AddDay(now, -1)
diff2 := yesterday.Sub(now)
fmt.Println(diff1)
fmt.Println(diff2)
// Output:
// 24h0m0s
// -24h0m0s
}
```
### <span id="AddHour">AddHour</span>
<p>Add or sub hours to time.</p>
<b>Signature:</b>
@@ -116,6 +129,7 @@ func main() {
```go
func AddHour(t time.Time, hour int64) time.Time
```
<b>Example:</b>
```go
@@ -129,14 +143,24 @@ import (
func main() {
now := time.Now()
after2Hours := datetime.AddHour(now, 2)
before2Hours := datetime.AddHour(now, -2)
fmt.Println(after2Hours, after2Hours)
after2Hours := datetime.AddHour(now, 2)
diff1 := after2Hours.Sub(now)
before2Hours := datetime.AddHour(now, -2)
diff2 := before2Hours.Sub(now)
fmt.Println(diff1)
fmt.Println(diff2)
// Output:
// 2h0m0s
// -2h0m0s
}
```
### <span id="AddMinute">AddMinute</span>
<p>Add or sub minutes to time.</p>
<b>Signature:</b>
@@ -144,6 +168,7 @@ func main() {
```go
func AddMinute(t time.Time, minute int64) time.Time
```
<b>Example:</b>
```go
@@ -157,14 +182,24 @@ import (
func main() {
now := time.Now()
after2Minute := datetime.AddMinute(now, 2)
before2Minute := datetime.AddMinute(now, -2)
fmt.Println(after2Minute, before2Minute)
after2Minutes := datetime.AddMinute(now, 2)
diff1 := after2Minutes.Sub(now)
before2Minutes := datetime.AddMinute(now, -2)
diff2 := before2Minutes.Sub(now)
fmt.Println(diff1)
fmt.Println(diff2)
// Output:
// 2m0s
// -2m0s
}
```
### <span id="BeginOfMinute">BeginOfMinute</span>
<p>Return beginning minute time of day.</p>
<b>Signature:</b>
@@ -172,6 +207,7 @@ func main() {
```go
func BeginOfMinute(t time.Time) time.Time
```
<b>Example:</b>
```go
@@ -184,13 +220,18 @@ import (
)
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
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
}
```
### <span id="BeginOfHour">BeginOfHour</span>
<p>Return zero time of day.</p>
<b>Signature:</b>
@@ -198,6 +239,7 @@ func main() {
```go
func BeginOfHour(t time.Time) time.Time
```
<b>Example:</b>
```go
@@ -210,13 +252,18 @@ import (
)
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
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
}
```
### <span id="BeginOfDay">BeginOfDay</span>
<p>Return begin time of day.</p>
<b>Signature:</b>
@@ -224,6 +271,7 @@ func main() {
```go
func BeginOfDay(t time.Time) time.Time
```
<b>Example:</b>
```go
@@ -236,15 +284,18 @@ import (
)
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
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
}
```
### <span id="BeginOfWeek">BeginOfWeek</span>
<p>Return beginning time of week, week begin from Sunday.</p>
<b>Signature:</b>
@@ -252,6 +303,7 @@ func main() {
```go
func BeginOfWeek(t time.Time, beginFrom ...time.Weekday) time.Time
```
<b>Example:</b>
```go
@@ -264,15 +316,18 @@ import (
)
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
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
result := datetime.BeginOfWeek(input)
fmt.Println(result)
// Output:
// 2023-01-08 00:00:00 +0000 UTC
}
```
### <span id="BeginOfMonth">BeginOfMonth</span>
<p>Return beginning time of month</p>
<b>Signature:</b>
@@ -280,6 +335,7 @@ func main() {
```go
func BeginOfMonth(t time.Time) time.Time
```
<b>Example:</b>
```go
@@ -292,14 +348,18 @@ import (
)
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
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
}
```
### <span id="BeginOfYear">BeginOfYear</span>
<p>Return beginning time of year.</p>
<b>Signature:</b>
@@ -307,6 +367,7 @@ func main() {
```go
func BeginOfYear(t time.Time) time.Time
```
<b>Example:</b>
```go
@@ -319,15 +380,18 @@ import (
)
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
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
}
```
### <span id="EndOfMinute">EndOfMinute</span>
<p>Return end time minute of day.</p>
<b>Signature:</b>
@@ -335,6 +399,7 @@ func main() {
```go
func EndOfMinute(t time.Time) time.Time
```
<b>Example:</b>
```go
@@ -347,13 +412,18 @@ import (
)
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
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
}
```
### <span id="EndOfHour">EndOfHour</span>
<p>Return end time hour of day.</p>
<b>Signature:</b>
@@ -361,6 +431,7 @@ func main() {
```go
func EndOfHour(t time.Time) time.Time
```
<b>Example:</b>
```go
@@ -373,13 +444,18 @@ import (
)
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
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
}
```
### <span id="EndOfDay">EndOfDay</span>
<p>Return end time hour of day.</p>
<b>Signature:</b>
@@ -387,6 +463,7 @@ func main() {
```go
func EndOfDay(t time.Time) time.Time
```
<b>Example:</b>
```go
@@ -399,15 +476,18 @@ import (
)
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
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
}
```
### <span id="EndOfWeek">EndOfWeek</span>
<p>Return end time of week, week end with Saturday.</p>
<b>Signature:</b>
@@ -415,6 +495,7 @@ func main() {
```go
func EndOfWeek(t time.Time, endWith ...time.Weekday) time.Time
```
<b>Example:</b>
```go
@@ -427,15 +508,18 @@ import (
)
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
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
result := datetime.EndOfWeek(input)
fmt.Println(result)
// Output:
// 2023-01-14 23:59:59.999999999 +0000 UTC
}
```
### <span id="EndOfMonth">EndOfMonth</span>
<p>Return end time of month</p>
<b>Signature:</b>
@@ -443,6 +527,7 @@ func main() {
```go
func EndOfMonth(t time.Time) time.Time
```
<b>Example:</b>
```go
@@ -455,14 +540,18 @@ import (
)
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
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
}
```
### <span id="EndOfYear">EndOfYear</span>
<p>Return beginning time of year.</p>
<b>Signature:</b>
@@ -470,6 +559,7 @@ func main() {
```go
func EndOfYear(t time.Time) time.Time
```
<b>Example:</b>
```go
@@ -482,14 +572,18 @@ import (
)
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
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
}
```
### <span id="GetNowDate">GetNowDate</span>
<p>Get current date string, format is yyyy-mm-dd.</p>
<b>Signature:</b>
@@ -497,6 +591,7 @@ func main() {
```go
func GetNowDate() string
```
<b>Example:</b>
```go
@@ -511,12 +606,16 @@ import (
func main() {
now := time.Now()
currentDate := datetime.GetNowDate()
fmt.Println(currentDate) // 2022-01-28
fmt.Println(currentDate)
// Output:
// 2022-01-28
}
```
### <span id="GetNowTime">GetNowTime</span>
<p>Get current time string, format is hh:mm:ss.</p>
<b>Signature:</b>
@@ -524,6 +623,7 @@ func main() {
```go
func GetNowTime() string
```
<b>Example:</b>
```go
@@ -538,12 +638,16 @@ import (
func main() {
now := time.Now()
currentTime := datetime.GetNowTime()
fmt.Println(currentDate) // 15:57:33
fmt.Println(currentTime) // 15:57:33
// Output:
// 15:57:33
}
```
### <span id="GetNowDateTime">GetNowDateTime</span>
<p>Get current date time string, format is yyyy-mm-dd hh:mm:ss.</p>
<b>Signature:</b>
@@ -551,6 +655,7 @@ func main() {
```go
func GetNowDateTime() string
```
<b>Example:</b>
```go
@@ -565,12 +670,16 @@ import (
func main() {
now := time.Now()
current := datetime.GetNowDateTime()
fmt.Println(current) // 2022-01-28 15:59:33
fmt.Println(current)
// Output:
// 2022-01-28 15:59:33
}
```
### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span>
<p>Return timestamp of zero hour (timestamp of 00:00).</p>
<b>Signature:</b>
@@ -578,6 +687,7 @@ func main() {
```go
func GetZeroHourTimestamp() int64
```
<b>Example:</b>
```go
@@ -592,12 +702,16 @@ import (
func main() {
now := time.Now()
zeroTime := datetime.GetZeroHourTimestamp()
fmt.Println(zeroTime) // 1643299200
fmt.Println(zeroTime)
// Output:
// 1643299200
}
```
### <span id="GetNightTimestamp">GetNightTimestamp</span>
<p>Return timestamp of zero hour (timestamp of 23:59).</p>
<b>Signature:</b>
@@ -605,6 +719,7 @@ func main() {
```go
func GetNightTimestamp() int64
```
<b>Example:</b>
```go
@@ -619,11 +734,16 @@ import (
func main() {
now := time.Now()
nightTime := datetime.GetNightTimestamp()
fmt.Println(nightTime) // 1643385599
fmt.Println(nightTime)
// Output:
// 1643385599
}
```
### <span id="FormatTimeToStr">FormatTimeToStr</span>
<p>Format time to string, `format` param specification see note 1.</p>
<b>Signature:</b>
@@ -631,6 +751,7 @@ func main() {
```go
func FormatTimeToStr(t time.Time, format string) string
```
<b>Example:</b>
```go
@@ -643,14 +764,25 @@ import (
)
func main() {
now := time.Now()
timeStr := datetime.FormatTimeToStr(now, "yyyy/mm/dd hh:mm:ss")
fmt.Println(timeStr) //2022/01/28 16:07:44
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
}
```
### <span id="FormatStrToTime">FormatStrToTime</span>
<p>Format string to time, `format` param specification see note 1.</p>
<b>Signature:</b>
@@ -658,6 +790,7 @@ func main() {
```go
func FormatStrToTime(str, format string) (time.Time, error)
```
<b>Example:</b>
```go
@@ -669,24 +802,34 @@ import (
)
func main() {
time := datetime.FormatStrToTime("2006-01-02 15:04:05", "yyyy/mm/dd hh:mm:ss")
fmt.Println(time)
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
}
```
### <span id="NewUnixNow">NewUnixNow</span>
<p>Return unix timestamp of current time</p>
<b>Signature:</b>
```go
type theTime struct {
unix int64
unix int64
}
func NewUnixNow() *theTime
```
<b>Example:</b>
```go
@@ -699,12 +842,15 @@ import (
func main() {
tm := datetime.NewUnixNow()
fmt.Println(tm) //&{1647597438}
fmt.Println(tm)
// Output:
// &{1647597438}
}
```
### <span id="NewUnix">NewUnix</span>
<p>Return unix timestamp of specified int64 value.</p>
<b>Signature:</b>
@@ -715,6 +861,7 @@ type theTime struct {
}
func NewUnix(unix int64) *theTime
```
<b>Example:</b>
```go
@@ -727,13 +874,15 @@ import (
func main() {
tm := datetime.NewUnix(1647597438)
fmt.Println(tm) //&{1647597438}
fmt.Println(tm)
// Output:
// &{1647597438}
}
```
### <span id="NewFormat">NewFormat</span>
<p>Return unix timestamp of specified time string, t should be "yyyy-mm-dd hh:mm:ss".</p>
<b>Signature:</b>
@@ -744,6 +893,7 @@ type theTime struct {
}
func NewFormat(t string) (*theTime, error)
```
<b>Example:</b>
```go
@@ -756,14 +906,15 @@ import (
func main() {
tm, err := datetime.NewFormat("2022-03-18 17:04:05")
fmt.Println(tm) //&{1647594245}
fmt.Println(tm)
// Output:
// &{1647594245}
}
```
### <span id="NewISO8601">NewISO8601</span>
<p>Return unix timestamp of specified iso8601 time string.</p>
<b>Signature:</b>
@@ -774,6 +925,7 @@ type theTime struct {
}
func NewISO8601(iso8601 string) (*theTime, error)
```
<b>Example:</b>
```go
@@ -786,13 +938,15 @@ import (
func main() {
tm, err := datetime.NewISO8601("2006-01-02T15:04:05.999Z")
fmt.Println(tm) //&{1136214245}
fmt.Println(tm)
// Output:
// &{1136214245}
}
```
### <span id="ToUnix">ToUnix</span>
<p>Return unix timestamp.</p>
<b>Signature:</b>
@@ -800,6 +954,7 @@ func main() {
```go
func (t *theTime) ToUnix() int64
```
<b>Example:</b>
```go
@@ -812,13 +967,15 @@ import (
func main() {
tm := datetime.NewUnixNow()
fmt.Println(tm.ToUnix()) //1647597438
fmt.Println(tm.ToUnix())
// Output:
// 1647597438
}
```
### <span id="ToFormat">ToFormat</span>
<p>Return time string 'yyyy-mm-dd hh:mm:ss'.</p>
<b>Signature:</b>
@@ -826,6 +983,7 @@ func main() {
```go
func (t *theTime) ToFormat() string
```
<b>Example:</b>
```go
@@ -838,13 +996,15 @@ import (
func main() {
tm, _ := datetime.NewFormat("2022-03-18 17:04:05")
fmt.Println(tm.ToFormat()) //"2022-03-18 17:04:05"
fmt.Println(tm.ToFormat())
// Output:
// 2022-03-18 17:04:05
}
```
### <span id="ToFormatForTpl">ToFormatForTpl</span>
<p>Return the time string which format is specified tpl.</p>
<b>Signature:</b>
@@ -852,6 +1012,7 @@ func main() {
```go
func (t *theTime) ToFormatForTpl(tpl string) string
```
<b>Example:</b>
```go
@@ -865,12 +1026,15 @@ import (
func main() {
tm, _ := datetime.NewFormat("2022-03-18 17:04:05")
ts := tm.ToFormatForTpl("2006/01/02 15:04:05")
fmt.Println(ts) //"2022/03/18 17:04:05"
fmt.Println(ts)
// Output:
// 2022/03/18 17:04:05
}
```
### <span id="ToIso8601">ToIso8601</span>
<p>Return iso8601 time string.</p>
<b>Signature:</b>
@@ -878,6 +1042,7 @@ func main() {
```go
func (t *theTime) ToIso8601() string
```
<b>Example:</b>
```go
@@ -891,6 +1056,9 @@ import (
func main() {
tm, _ := datetime.NewISO8601("2006-01-02T15:04:05.999Z")
ts := tm.ToIso8601()
fmt.Println(ts) //"2006-01-02T23:04:05+08:00"
fmt.Println(ts)
// Output:
// 2006-01-02T23:04:05+08:00
}
```
```

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,17 @@
# Fileutil
Package fileutil implements some basic functions for file operations.
<div STYLE="page-break-after: always;"></div>
## Source:
- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
<div STYLE="page-break-after: always;"></div>
## Usage:
```go
import (
"github.com/duke-git/lancet/v2/fileutil"
@@ -19,30 +21,30 @@ import (
<div STYLE="page-break-after: always;"></div>
## Index
- [ClearFile](#ClearFile)
- [CreateFile](#CreateFile)
- [CreateDir](#CreateDir)
- [CopyFile](#CopyFile)
- [FileMode](#FileMode)
- [MiMeType](#MiMeType)
- [IsExist](#IsExist)
- [IsLink](#IsLink)
- [IsDir](#IsDir)
- [ListFileNames](#ListFileNames)
- [RemoveFile](#RemoveFile)
- [ReadFileToString](#ReadFileToString)
- [ReadFileByLine](#ReadFileByLine)
- [Zip](#Zip)
- [UnZip](#UnZip)
- [UnZip](#UnZip)
- [ClearFile](#ClearFile)
- [CreateFile](#CreateFile)
- [CreateDir](#CreateDir)
- [CopyFile](#CopyFile)
- [FileMode](#FileMode)
- [MiMeType](#MiMeType)
- [IsExist](#IsExist)
- [IsLink](#IsLink)
- [IsDir](#IsDir)
- [ListFileNames](#ListFileNames)
- [RemoveFile](#RemoveFile)
- [ReadFileToString](#ReadFileToString)
- [ReadFileByLine](#ReadFileByLine)
- [Zip](#Zip)
- [UnZip](#UnZip)
- [UnZip](#UnZip)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="ClearFile">ClearFile</span>
<p>Clear the file content, write empty string to the file.</p>
<b>Signature:</b>
@@ -50,6 +52,7 @@ import (
```go
func ClearFile(path string) error
```
<b>Example:</b>
```go
@@ -69,6 +72,7 @@ func main() {
```
### <span id="CreateFile">CreateFile</span>
<p>Create file in path. return true if create succeed.</p>
<b>Signature:</b>
@@ -76,6 +80,7 @@ func main() {
```go
func CreateFile(path string) bool
```
<b>Example:</b>
```go
@@ -92,9 +97,8 @@ func main() {
}
```
### <span id="CreateDir">CreateDir</span>
<p>Create directory in absolute path. param `absPath` like /a/, /a/b/.</p>
<b>Signature:</b>
@@ -102,6 +106,7 @@ func main() {
```go
func CreateDir(absPath string) error
```
<b>Example:</b>
```go
@@ -118,8 +123,8 @@ func main() {
}
```
### <span id="CopyFile">CopyFile</span>
<p>Copy src file to dest file. If dest file exist will overwrite it.</p>
<b>Signature:</b>
@@ -127,6 +132,7 @@ func main() {
```go
func CopyFile(srcFilePath string, dstFilePath string) error
```
<b>Example:</b>
```go
@@ -145,9 +151,8 @@ func main() {
}
```
### <span id="FileMode">FileMode</span>
<p>Return file mode infomation.</p>
<b>Signature:</b>
@@ -155,6 +160,7 @@ func main() {
```go
func FileMode(path string) (fs.FileMode, error)
```
<b>Example:</b>
```go
@@ -174,9 +180,8 @@ func main() {
}
```
### <span id="MiMeType">MiMeType</span>
<p>Get file mime type, 'file' param's type should be string or *os.File.</p>
<b>Signature:</b>
@@ -184,6 +189,7 @@ func main() {
```go
func MiMeType(file any) string
```
<b>Example:</b>
```go
@@ -205,10 +211,8 @@ func main() {
}
```
### <span id="IsExist">IsExist</span>
<p>Checks if a file or directory exists.</p>
<b>Signature:</b>
@@ -216,6 +220,7 @@ func main() {
```go
func IsExist(path string) bool
```
<b>Example:</b>
```go
@@ -233,9 +238,8 @@ func main() {
}
```
### <span id="IsLink">IsLink</span>
<p>Checks if a file is symbol link or not.</p>
<b>Signature:</b>
@@ -243,6 +247,7 @@ func main() {
```go
func IsLink(path string) bool
```
<b>Example:</b>
```go
@@ -259,16 +264,16 @@ func main() {
}
```
### <span id="IsDir">IsDir</span>
<p>Checks if the path is directy or not.</p>
<b>Signature:</b>
```go
func IsDir(path string) bool
func IsDir(path string) bool
```
<b>Example:</b>
```go
@@ -288,9 +293,8 @@ func main() {
}
```
### <span id="ListFileNames">ListFileNames</span>
<p>List all file names in given path.</p>
<b>Signature:</b>
@@ -298,6 +302,7 @@ func main() {
```go
func ListFileNames(path string) ([]string, error)
```
<b>Example:</b>
```go
@@ -314,9 +319,8 @@ func main() {
}
```
### <span id="RemoveFile">RemoveFile</span>
<p>Remove the file of path.</p>
<b>Signature:</b>
@@ -324,6 +328,7 @@ func main() {
```go
func RemoveFile(path string) error
```
<b>Example:</b>
```go
@@ -342,8 +347,8 @@ func main() {
}
```
### <span id="ReadFileToString">ReadFileToString</span>
<p>Return string of file content.</p>
<b>Signature:</b>
@@ -351,6 +356,7 @@ func main() {
```go
func ReadFileToString(path string) (string, error)
```
<b>Example:</b>
```go
@@ -374,9 +380,8 @@ func main() {
}
```
### <span id="ReadFileByLine">ReadFileByLine</span>
<p>Read file line by line, and return slice of lines</p>
<b>Signature:</b>
@@ -384,6 +389,7 @@ func main() {
```go
func ReadFileByLine(path string)([]string, error)
```
<b>Example:</b>
```go
@@ -408,9 +414,8 @@ func main() {
}
```
### <span id="Zip">Zip</span>
<p>Create a zip file of fpath, fpath could be a file or a directory.</p>
<b>Signature:</b>
@@ -418,6 +423,7 @@ func main() {
```go
func Zip(fpath string, destPath string) error
```
<b>Example:</b>
```go
@@ -436,10 +442,8 @@ func main() {
}
```
### <span id="UnZip">UnZip</span>
<p>Unzip the file and save it to dest path.</p>
<b>Signature:</b>
@@ -447,6 +451,7 @@ func main() {
```go
func UnZip(zipFile string, destPath string) error
```
<b>Example:</b>
```go
@@ -464,8 +469,3 @@ func main() {
}
}
```

View File

@@ -1,15 +1,17 @@
# Fileutil
fileutil包支持文件基本操作。
fileutil 包支持文件基本操作。
<div STYLE="page-break-after: always;"></div>
## 源码:
- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
<div STYLE="page-break-after: always;"></div>
## 用法:
```go
import (
"github.com/duke-git/lancet/v2/fileutil"
@@ -19,29 +21,29 @@ import (
<div STYLE="page-break-after: always;"></div>
## 目录
- [ClearFile](#ClearFile)
- [CreateFile](#CreateFile)
- [CreateDir](#CreateDir)
- [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](#ClearFile)
- [CreateFile](#CreateFile)
- [CreateDir](#CreateDir)
- [CopyFile](#CopyFile)
- [FileMode](#FileMode)
- [MiMeType](#MiMeType)
- [IsExist](#IsExist)
- [IsLink](#IsLink)
- [IsDir](#IsDir)
- [ListFileNames](#ListFileNames)
- [RemoveFile](#RemoveFile)
- [ReadFileToString](#ReadFileToString)
- [ReadFileByLine](#ReadFileByLine)
- [Zip](#Zip)
- [UnZip](#UnZip)
<div STYLE="page-break-after: always;"></div>
## 文档
### <span id="ClearFile">ClearFile</span>
<p>清空文件内容</p>
<b>函数签名:</b>
@@ -49,7 +51,8 @@ import (
```go
func ClearFile(path string) error
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -68,6 +71,7 @@ func main() {
```
### <span id="CreateFile">CreateFile</span>
<p>创建文件创建成功返回true, 否则返回false</p>
<b>函数签名:</b>
@@ -75,7 +79,8 @@ func main() {
```go
func CreateFile(path string) bool
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -91,8 +96,8 @@ func main() {
}
```
### <span id="CreateDir">CreateDir</span>
<p>使用绝对路径创建嵌套目录,例如/a/, /a/b/</p>
<b>函数签名:</b>
@@ -100,6 +105,7 @@ func main() {
```go
func CreateDir(absPath string) error
```
<b>Example:</b>
```go
@@ -116,9 +122,8 @@ func main() {
}
```
### <span id="CopyFile">CopyFile</span>
<p>拷贝文件,会覆盖原有的文件</p>
<b>函数签名:</b>
@@ -126,7 +131,8 @@ func main() {
```go
func CopyFile(srcFilePath string, dstFilePath string) error
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -144,9 +150,8 @@ func main() {
}
```
### <span id="FileMode">FileMode</span>
<p>获取文件mode信息</p>
<b>函数签名:</b>
@@ -154,7 +159,8 @@ func main() {
```go
func FileMode(path string) (fs.FileMode, error)
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -173,9 +179,8 @@ func main() {
}
```
### <span id="MiMeType">MiMeType</span>
<p>获取文件mime类型, 'file'参数的类型必须是string或者*os.File</p>
<b>函数签名:</b>
@@ -183,7 +188,8 @@ func main() {
```go
func MiMeType(file any) string
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -204,10 +210,8 @@ func main() {
}
```
### <span id="IsExist">IsExist</span>
<p>判断文件或目录是否存在</p>
<b>函数签名:</b>
@@ -215,7 +219,8 @@ func main() {
```go
func IsExist(path string) bool
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -232,9 +237,8 @@ func main() {
}
```
### <span id="IsLink">IsLink</span>
<p>判断文件是否是符号链接</p>
<b>函数签名:</b>
@@ -242,7 +246,8 @@ func main() {
```go
func IsLink(path string) bool
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -258,17 +263,17 @@ func main() {
}
```
### <span id="IsDir">IsDir</span>
<p>判断参数是否是目录</p>
<b>函数签名:</b>
```go
func IsDir(path string) bool
func IsDir(path string) bool
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -287,9 +292,8 @@ func main() {
}
```
### <span id="ListFileNames">ListFileNames</span>
<p>返回目录下所有文件名</p>
<b>函数签名:</b>
@@ -297,7 +301,8 @@ func main() {
```go
func ListFileNames(path string) ([]string, error)
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -313,9 +318,8 @@ func main() {
}
```
### <span id="RemoveFile">RemoveFile</span>
<p>删除文件</p>
<b>函数签名:</b>
@@ -323,7 +327,8 @@ func main() {
```go
func RemoveFile(path string) error
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -341,8 +346,8 @@ func main() {
}
```
### <span id="ReadFileToString">ReadFileToString</span>
<p>读取文件内容并返回字符串</p>
<b>函数签名:</b>
@@ -350,7 +355,8 @@ func main() {
```go
func ReadFileToString(path string) (string, error)
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -373,9 +379,8 @@ func main() {
}
```
### <span id="ReadFileByLine">ReadFileByLine</span>
<p>按行读取文件内容,返回字符串切片包含每一行</p>
<b>函数签名:</b>
@@ -383,7 +388,8 @@ func main() {
```go
func ReadFileByLine(path string)([]string, error)
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -407,9 +413,8 @@ func main() {
}
```
### <span id="Zip">Zip</span>
<p>zip压缩文件, fpath参数可以是文件或目录</p>
<b>函数签名:</b>
@@ -417,7 +422,8 @@ func main() {
```go
func Zip(fpath string, destPath string) error
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -435,10 +441,8 @@ func main() {
}
```
### <span id="UnZip">UnZip</span>
<p>zip解压缩文件并保存在目录中</p>
<b>Signature:</b>
@@ -446,7 +450,8 @@ func main() {
```go
func UnZip(zipFile string, destPath string) error
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -463,8 +468,3 @@ func main() {
}
}
```

View File

@@ -1,15 +1,17 @@
# Formatter
formatter contains some functions for data formatting.
<div STYLE="page-break-after: always;"></div>
## 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/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go)
<div STYLE="page-break-after: always;"></div>
## Usage:
```go
import (
"github.com/duke-git/lancet/v2/formatter"
@@ -19,15 +21,15 @@ import (
<div STYLE="page-break-after: always;"></div>
## Index
- [Comma](#Comma)
- [Comma](#Comma)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="Comma">Comma</span>
<p>Add comma to a number value by every 3 numbers from right to left. ahead by symbol char. if value is a invalid number string like "aa", return empty string.</p>
<b>Signature:</b>
@@ -35,6 +37,7 @@ import (
```go
func Comma[T constraints.Float | constraints.Integer | string](value T, symbol string) string
```
<b>Example:</b>
```go
@@ -46,7 +49,17 @@ import (
)
func main() {
fmt.Println(formatter.Comma("12345", "")) // "12,345"
fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
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
}
```

View File

@@ -1,15 +1,17 @@
# Formatter
formatter格式化器包含一些数据格式化处理方法。
formatter 格式化器包含一些数据格式化处理方法。
<div STYLE="page-break-after: always;"></div>
## 源码:
- [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/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go)
<div STYLE="page-break-after: always;"></div>
## 用法:
```go
import (
"github.com/duke-git/lancet/v2/formatter"
@@ -19,15 +21,15 @@ import (
<div STYLE="page-break-after: always;"></div>
## 目录
- [Comma](#Comma)
- [Comma](#Comma)
<div STYLE="page-break-after: always;"></div>
## 文档
### <span id="Comma">Comma</span>
<p>用逗号每隔3位分割数字/字符串支持前缀添加符号。参数value必须是数字或者可以转为数字的字符串, 否则返回空字符串</p>
<b>函数签名:</b>
@@ -35,7 +37,8 @@ import (
```go
func Comma[T constraints.Float | constraints.Integer | string](value T, symbol string) string
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -46,7 +49,17 @@ import (
)
func main() {
fmt.Println(formatter.Comma("12345", "")) // "12,345"
fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
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
}
```

View File

@@ -1,16 +1,18 @@
# Function
Package function can control the flow of function execution and support part of functional programming.
<div STYLE="page-break-after: always;"></div>
## 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)
- [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)
<div STYLE="page-break-after: always;"></div>
## Usage:
```go
import (
"github.com/duke-git/lancet/v2/function"
@@ -20,22 +22,22 @@ import (
<div STYLE="page-break-after: always;"></div>
## Index
- [After](#After)
- [Before](#Before)
- [CurryFn](#CurryFn)
- [Compose](#Compose)
- [Debounced](#Debounced)
- [Delay](#Delay)
- [Pipeline](#Pipeline)
- [Watcher](#Watcher)
- [After](#After)
- [Before](#Before)
- [CurryFn](#CurryFn)
- [Compose](#Compose)
- [Debounced](#Debounced)
- [Delay](#Delay)
- [Pipeline](#Pipeline)
- [Watcher](#Watcher)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="After">After</span>
<p>Creates a function that invokes given func once it's called n or more times.</p>
<b>Signature:</b>
@@ -43,6 +45,7 @@ import (
```go
func After(n int, fn any) func(args ...any) []reflect.Value
```
<b>Example:</b>
```go
@@ -54,33 +57,18 @@ import (
)
func main() {
arr := []string{"a", "b"}
f := function.After(len(arr), func(i int) int {
fmt.Println("last print")
return i
})
fn := function.After(2, func() {
fmt.Println("hello")
})
type cb func(args ...any) []reflect.Value
print := func(i int, s string, fn cb) {
fmt.Printf("arr[%d] is %s \n", i, s)
fn(i)
}
fn()
fn()
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
// Output:
// hello
}
```
### <span id="Before">Before</span>
<p>creates a function that invokes func once it's called less than n times.</p>
@@ -90,6 +78,7 @@ func main() {
```go
func Before(n int, fn any) func(args ...any) []reflect.Value
```
<b>Example:</b>
```go
@@ -102,29 +91,21 @@ import (
)
func main() {
arr := []string{"a", "b", "c", "d", "e"}
f := function.Before(3, func(i int) int {
return i
})
fn := function.Before(2, func() {
fmt.Println("hello")
})
var res []int64
type cb func(args ...any) []reflect.Value
appendStr := func(i int, s string, fn cb) {
v := fn(i)
res = append(res, v[0].Int())
}
fn()
fn()
fn()
fn()
for i := 0; i < len(arr); i++ {
appendStr(i, arr[i], f)
}
expected := []int64{0, 1, 2, 2, 2}
fmt.Println(res) // 0, 1, 2, 2, 2
// Output:
// hello
// hello
}
```
### <span id="CurryFn">CurryFn</span>
<p>Make curry function.</p>
@@ -135,6 +116,7 @@ func main() {
type CurryFn[T any] func(...T) T
func (cf CurryFn[T]) New(val T) func(...T) T
```
<b>Example:</b>
```go
@@ -147,22 +129,23 @@ import (
func main() {
add := func(a, b int) int {
return a + b
}
return a + b
}
var addCurry CurryFn[int] = func(values ...int) int {
return add(values[0], values[1])
}
add1 := addCurry.New(1)
var addCurry function.CurryFn[int] = func(values ...int) int {
return add(values[0], values[1])
}
add1 := addCurry.New(1)
result := add1(2)
result := add1(2)
fmt.Println(result) //3
fmt.Println(result)
// Output:
// 3
}
```
### <span id="Compose">Compose</span>
<p>Compose the function list from right to left, then return the composed function.</p>
@@ -172,6 +155,7 @@ func main() {
```go
func Compose[T any](fnList ...func(...T) T) func(...T) T
```
<b>Example:</b>
```go
@@ -183,22 +167,23 @@ import (
)
func main() {
toUpper := func(strs ...string) string {
return strings.ToUpper(strs[0])
}
toLower := func(strs ...string) string {
return strings.ToLower(strs[0])
}
transform := Compose(toUpper, toLower)
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")
result := transform("aBCde")
fmt.Println(result) //ABCDE
fmt.Println(result)
// Output:
// ABCDE
}
```
### <span id="Debounced">Debounced</span>
<p>Creates a debounced function that delays invoking fn until after wait duration have elapsed since the last time the debounced function was invoked.</p>
@@ -208,6 +193,7 @@ func main() {
```go
func Debounced(fn func(), duration time.Duration) func()
```
<b>Example:</b>
```go
@@ -220,27 +206,34 @@ import (
func main() {
count := 0
add := func() {
count++
}
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
function.debouncedAdd()
function.debouncedAdd()
function.debouncedAdd()
function.debouncedAdd()
add := func() {
count++
}
time.Sleep(100 * time.Millisecond)
fmt.Println(count) //1
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
function.debouncedAdd()
time.Sleep(100 * time.Millisecond)
fmt.Println(count) //2
debouncedAdd()
debouncedAdd()
debouncedAdd()
debouncedAdd()
time.Sleep(100 * time.Millisecond)
fmt.Println(count)
debouncedAdd()
time.Sleep(100 * time.Millisecond)
fmt.Println(count)
// Output:
// 1
// 2
}
```
### <span id="Delay">Delay</span>
<p>Invoke function after delayed time.</p>
@@ -250,6 +243,7 @@ func main() {
```go
func Delay(delay time.Duration, fn any, args ...any)
```
<b>Example:</b>
```go
@@ -261,15 +255,17 @@ import (
)
func main() {
var print = func(s string) {
fmt.Println(count) //delay 2 seconds
}
function.Delay(2*time.Second, print, "delay 2 seconds")
var print = func(s string) {
fmt.Println(s)
}
function.Delay(2*time.Second, print, "hello")
// Output:
// hello
}
```
### <span id="Schedule">Schedule</span>
<p>Invoke function every duration time, until close the returned bool chan.</p>
@@ -279,6 +275,7 @@ func main() {
```go
func Schedule(d time.Duration, fn any, args ...any) chan bool
```
<b>Example:</b>
```go
@@ -290,20 +287,24 @@ import (
)
func main() {
var res []string
appendStr := func(s string) {
res = append(res, s)
}
count := 0
stop := function.Schedule(1*time.Second, appendStr, "*")
time.Sleep(5 * time.Second)
close(stop)
increase := func() {
count++
}
fmt.Println(res) //[* * * * *]
stop := function.Schedule(2*time.Second, increase)
time.Sleep(2 * time.Second)
close(stop)
fmt.Println(count)
// Output:
// 2
}
```
### <span id="Pipeline">Pipeline</span>
<p>Pipeline takes a list of functions and returns a function whose param will be passed into
@@ -314,6 +315,7 @@ the functions one by one.</p>
```go
func Pipeline[T any](funcs ...func(T) T) func(T) T
```
<b>Example:</b>
```go
@@ -326,22 +328,26 @@ import (
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
}
return x + 1
}
double := func(x int) int {
return 2 * x
}
square := func(x int) int {
return x * x
}
fn := Pipeline(addOne, double, square)
fn := function.Pipeline(addOne, double, square)
fmt.Println(fn(2)) //36
result := fn(2)
fmt.Println(result)
// Output:
// 36
}
```
### <span id="Watcher">Watcher</span>
<p>Watcher is used for record code excution time. can start/stop/reset the watch timer. get the elapsed time of function execution.</p>
@@ -350,9 +356,9 @@ func main() {
```go
type Watcher struct {
startTime int64
stopTime int64
excuting bool
startTime int64
stopTime int64
excuting bool
}
func NewWatcher() *Watcher
func (w *Watcher) Start() //start the watcher
@@ -360,6 +366,7 @@ 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
```
<b>Example:</b>
```go
@@ -371,31 +378,28 @@ import (
)
func main() {
w := function.NewWatcher()
w := function.NewWatcher()
w.Start()
w.Start()
longRunningTask()
longRunningTask()
fmt.Println(w.excuting) //true
fmt.Println(w.excuting) //true
w.Stop()
w.Stop()
eapsedTime := w.GetElapsedTime().Milliseconds()
fmt.Println(eapsedTime)
eapsedTime := w.GetElapsedTime().Milliseconds()
w.Reset()
fmt.Println(eapsedTime)
w.Reset()
}
func longRunningTask() {
var slice []int64
for i := 0; i < 10000000; i++ {
slice = append(slice, int64(i))
}
var slice []int64
for i := 0; i < 10000000; i++ {
slice = append(slice, int64(i))
}
}
```

View File

@@ -1,16 +1,18 @@
# Function
function函数包控制函数执行流程包含部分函数式编程。
function 函数包控制函数执行流程,包含部分函数式编程。
<div STYLE="page-break-after: always;"></div>
## 源码:
- [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)
- [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)
<div STYLE="page-break-after: always;"></div>
## 用法:
```go
import (
"github.com/duke-git/lancet/v2/function"
@@ -20,22 +22,22 @@ import (
<div STYLE="page-break-after: always;"></div>
## 目录
- [After](#After)
- [Before](#Before)
- [CurryFn](#CurryFn)
- [Compose](#Compose)
- [Debounced](#Debounced)
- [Delay](#Delay)
- [Pipeline](#Pipeline)
- [Watcher](#Watcher)
- [After](#After)
- [Before](#Before)
- [CurryFn](#CurryFn)
- [Compose](#Compose)
- [Debounced](#Debounced)
- [Delay](#Delay)
- [Pipeline](#Pipeline)
- [Watcher](#Watcher)
<div STYLE="page-break-after: always;"></div>
## 文档
### <span id="After">After</span>
<p>创建一个函数当他被调用n或更多次之后将马上触发fn</p>
<b>函数签名:</b>
@@ -43,7 +45,8 @@ import (
```go
func After(n int, fn any) func(args ...any) []reflect.Value
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -54,33 +57,18 @@ import (
)
func main() {
arr := []string{"a", "b"}
f := function.After(len(arr), func(i int) int {
fmt.Println("last print")
return i
})
fn := function.After(2, func() {
fmt.Println("hello")
})
type cb func(args ...any) []reflect.Value
print := func(i int, s string, fn cb) {
fmt.Printf("arr[%d] is %s \n", i, s)
fn(i)
}
fn()
fn()
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
// Output:
// hello
}
```
### <span id="Before">Before</span>
<p>创建一个函数调用次数不超过n次之后再调用这个函数将返回一次最后调用fn的结果</p>
@@ -90,7 +78,8 @@ func main() {
```go
func Before(n int, fn any) func(args ...any) []reflect.Value
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -102,28 +91,21 @@ import (
)
func main() {
arr := []string{"a", "b", "c", "d", "e"}
f := function.Before(3, func(i int) int {
return i
})
fn := function.Before(2, func() {
fmt.Println("hello")
})
var res []int64
type cb func(args ...any) []reflect.Value
appendStr := func(i int, s string, fn cb) {
v := fn(i)
res = append(res, v[0].Int())
}
fn()
fn()
fn()
fn()
for i := 0; i < len(arr); i++ {
appendStr(i, arr[i], f)
}
fmt.Println(res) // 0, 1, 2, 2, 2
// Output:
// hello
// hello
}
```
### <span id="CurryFn">CurryFn</span>
<p>创建柯里化函数</p>
@@ -134,7 +116,8 @@ func main() {
type CurryFn[T any] func(...T) T
func (cf CurryFn[T]) New(val T) func(...T) T
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -145,23 +128,24 @@ import (
)
func main() {
add := func(a, b int) int {
return a + b
}
add := func(a, b int) int {
return a + b
}
var addCurry CurryFn[int] = func(values ...int) int {
return add(values[0], values[1])
}
add1 := addCurry.New(1)
var addCurry function.CurryFn[int] = func(values ...int) int {
return add(values[0], values[1])
}
add1 := addCurry.New(1)
result := add1(2)
result := add1(2)
fmt.Println(result) //3
fmt.Println(result)
// Output:
// 3
}
```
### <span id="Compose">Compose</span>
<p>从右至左组合函数列表fnList返回组合后的函数</p>
@@ -171,7 +155,8 @@ func main() {
```go
func Compose[T any](fnList ...func(...T) T) func(...T) T
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -182,22 +167,23 @@ import (
)
func main() {
toUpper := func(strs ...string) string {
return strings.ToUpper(strs[0])
}
toLower := func(strs ...string) string {
return strings.ToLower(strs[0])
}
transform := Compose(toUpper, toLower)
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")
result := transform("aBCde")
fmt.Println(result) //ABCDE
fmt.Println(result)
// Output:
// ABCDE
}
```
### <span id="Debounced">Debounced</span>
<p>创建一个debounced函数该函数延迟调用fn直到自上次调用debounced函数后等待持续时间过去。</p>
@@ -207,7 +193,8 @@ func main() {
```go
func Debounced(fn func(), duration time.Duration) func()
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -218,28 +205,35 @@ import (
)
func main() {
count := 0
add := func() {
count++
}
count := 0
add := func() {
count++
}
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
function.debouncedAdd()
function.debouncedAdd()
function.debouncedAdd()
function.debouncedAdd()
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
time.Sleep(100 * time.Millisecond)
fmt.Println(count) //1
debouncedAdd()
debouncedAdd()
debouncedAdd()
debouncedAdd()
function.debouncedAdd()
time.Sleep(100 * time.Millisecond)
fmt.Println(count) //2
time.Sleep(100 * time.Millisecond)
fmt.Println(count)
debouncedAdd()
time.Sleep(100 * time.Millisecond)
fmt.Println(count)
// Output:
// 1
// 2
}
```
### <span id="Delay">Delay</span>
<p>延迟delay时间后调用函数</p>
@@ -249,7 +243,8 @@ func main() {
```go
func Delay(delay time.Duration, fn any, args ...any)
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -260,15 +255,17 @@ import (
)
func main() {
var print = func(s string) {
fmt.Println(count) //test delay
}
function.Delay(2*time.Second, print, "test delay")
var print = func(s string) {
fmt.Println(s)
}
function.Delay(2*time.Second, print, "hello")
// Output:
// hello
}
```
### <span id="Schedule">Schedule</span>
<p>每次持续时间调用函数,直到关闭返回的 bool chan</p>
@@ -278,7 +275,8 @@ func main() {
```go
func Schedule(d time.Duration, fn any, args ...any) chan bool
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -289,21 +287,24 @@ import (
)
func main() {
var res []string
appendStr := func(s string) {
res = append(res, s)
}
count := 0
stop := function.Schedule(1*time.Second, appendStr, "*")
time.Sleep(5 * time.Second)
close(stop)
increase := func() {
count++
}
fmt.Println(res) //[* * * * *]
stop := function.Schedule(2*time.Second, increase)
time.Sleep(2 * time.Second)
close(stop)
fmt.Println(count)
// Output:
// 2
}
```
### <span id="Pipeline">Pipeline</span>
<p>执行函数pipeline.</p>
@@ -313,7 +314,8 @@ func main() {
```go
func Pipeline[T any](funcs ...func(T) T) func(T) T
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -325,23 +327,26 @@ import (
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
}
return x + 1
}
double := func(x int) int {
return 2 * x
}
square := func(x int) int {
return x * x
}
f := Pipeline(addOne, double, square)
fn := function.Pipeline(addOne, double, square)
fmt.Println(fn(2)) //36
result := fn(2)
fmt.Println(result)
// Output:
// 36
}
```
### <span id="Watcher">Watcher</span>
<p>Watcher用于记录代码执行时间。可以启动/停止/重置手表定时器。获取函数执行的时间。</p>
@@ -350,9 +355,9 @@ func main() {
```go
type Watcher struct {
startTime int64
stopTime int64
excuting bool
startTime int64
stopTime int64
excuting bool
}
func NewWatcher() *Watcher
func (w *Watcher) Start() //start the watcher
@@ -360,7 +365,8 @@ 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
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -373,30 +379,27 @@ import (
func main() {
w := function.NewWatcher()
w.Start()
w.Start()
longRunningTask()
longRunningTask()
fmt.Println(w.excuting) //true
fmt.Println(w.excuting) //true
w.Stop()
w.Stop()
eapsedTime := w.GetElapsedTime().Milliseconds()
fmt.Println(eapsedTime)
eapsedTime := w.GetElapsedTime().Milliseconds()
w.Reset()
fmt.Println(eapsedTime)
w.Reset()
}
func longRunningTask() {
var slice []int64
for i := 0; i < 10000000; i++ {
slice = append(slice, int64(i))
}
var slice []int64
for i := 0; i < 10000000; i++ {
slice = append(slice, int64(i))
}
}
```

View File

@@ -1,16 +1,17 @@
# Maputil
Package maputil includes some functions to manipulate map.
<div STYLE="page-break-after: always;"></div>
## 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/map.go](https://github.com/duke-git/lancet/blob/main/maputil/map.go)
<div STYLE="page-break-after: always;"></div>
## Example:
```go
import (
"github.com/duke-git/lancet/v2/maputil"
@@ -20,22 +21,22 @@ import (
<div STYLE="page-break-after: always;"></div>
## Index
- [ForEach](#ForEach)
- [Filter](#Filter)
- [Intersect](#Intersect)
- [Keys](#Keys)
- [Merge](#Merge)
- [Minus](#Minus)
- [Values](#Values)
- [IsDisjoint](#IsDisjoint)
- [ForEach](#ForEach)
- [Filter](#Filter)
- [Intersect](#Intersect)
- [Keys](#Keys)
- [Merge](#Merge)
- [Minus](#Minus)
- [Values](#Values)
- [IsDisjoint](#IsDisjoint)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="ForEach">ForEach</span>
<p>Executes iteratee funcation for every key and value pair in map.</p>
<b>Signature:</b>
@@ -43,6 +44,7 @@ import (
```go
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V))
```
<b>Example:</b>
```go
@@ -54,26 +56,28 @@ import (
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
}
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
}
var sum int
var sum int
maputil.ForEach(m, func(_ string, value int) {
sum += value
})
fmt.Println(sum) // 10
maputil.ForEach(m, func(_ string, value int) {
sum += value
})
fmt.Println(sum)
// Output:
// 10
}
```
### <span id="Filter">Filter</span>
<p>Iterates over map, return a new map contains all key and value pairs pass the predicate function.</p>
<b>Signature:</b>
@@ -81,6 +85,7 @@ func main() {
```go
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V
```
<b>Example:</b>
```go
@@ -92,29 +97,32 @@ import (
)
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
}
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
})
res := maputil.Filter(m, isEven)
fmt.Println(res) // map[string]int{"b": 2, "d": 4,}
maputil.Filter(m, func(_ string, value int) {
sum += value
})
result := maputil.Filter(m, isEven)
fmt.Println(result)
// Output:
// map[b:2 d:4]
}
```
### <span id="Intersect">Intersect</span>
<p>Iterates over maps, return a new map of key and value pairs in all given maps.</p>
<b>Signature:</b>
@@ -122,6 +130,7 @@ func main() {
```go
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V
```
<b>Example:</b>
```go
@@ -133,37 +142,42 @@ import (
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"a": 1,
"b": 2,
"c": 6,
"d": 7,
}
m2 := map[string]int{
"a": 1,
"b": 2,
"c": 6,
"d": 7,
}
m3 := map[string]int{
"a": 1,
"b": 9,
"e": 9,
}
m3 := map[string]int{
"a": 1,
"b": 9,
"e": 9,
}
fmt.Println(maputil.Intersect(m1)) // map[string]int{"a": 1, "b": 2, "c": 3}
result1 := maputil.Intersect(m1)
result2 := maputil.Intersect(m1, m2)
result3 := maputil.Intersect(m1, m2, m3)
fmt.Println(maputil.Intersect(m1, m2)) // map[string]int{"a": 1, "b": 2}
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(maputil.Intersect(m1, m2, m3)) // map[string]int{"a": 1}
// Output:
// map[a:1 b:2 c:3]
// map[a:1 b:2]
// map[a:1]
}
```
### <span id="Keys">Keys</span>
<p>Returns a slice of the map's keys.</p>
<b>Signature:</b>
@@ -171,6 +185,7 @@ func main() {
```go
func Keys[K comparable, V any](m map[K]V) []K
```
<b>Example:</b>
```go
@@ -182,24 +197,26 @@ import (
)
func main() {
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
keys := maputil.Keys(m)
sort.Ints(keys)
fmt.Println(keys) // []int{1, 2, 3, 4, 5}
keys := maputil.Keys(m)
sort.Ints(keys)
fmt.Println(keys)
// Output:
// [1 2 3 4 5]
}
```
### <span id="Merge">Merge</span>
<p>Merge maps, next key will overwrite previous key.</p>
<b>Signature:</b>
@@ -207,6 +224,7 @@ func main() {
```go
func Merge[K comparable, V any](maps ...map[K]V) map[K]V
```
<b>Example:</b>
```go
@@ -218,22 +236,26 @@ import (
)
func main() {
m1 := map[int]string{
1: "a",
2: "b",
}
m2 := map[int]string{
1: "1",
3: "2",
}
fmt.Println(maputil.Merge(m1, m2)) // map[int]string{1:"1", 2:"b", 3:"2",}
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]
}
```
### <span id="Minus">Minus</span>
<p>Creates an map of whose key in mapA but not in mapB.</p>
<b>Signature:</b>
@@ -241,6 +263,7 @@ func main() {
```go
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V
```
<b>Example:</b>
```go
@@ -252,25 +275,29 @@ import (
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"a": 11,
"b": 22,
"d": 33,
}
m2 := map[string]int{
"a": 11,
"b": 22,
"d": 33,
}
result := maputil.Minus(m1, m2)
fmt.Println(maputil.Minus(m1, m2)) //map[string]int{"c": 3}
fmt.Println(result)
// Output:
// map[c:3]
}
```
### <span id="Values">Values</span>
<p>Returns a slice of the map's values.</p>
<b>Signature:</b>
@@ -278,6 +305,7 @@ func main() {
```go
func Values[K comparable, V any](m map[K]V) []V
```
<b>Example:</b>
```go
@@ -289,22 +317,26 @@ import (
)
func main() {
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
values := maputil.Values(m)
sort.Strings(values)
values := maputil.Values(m)
sort.Strings(values)
fmt.Println(values) // []string{"a", "a", "b", "c", "d"}
fmt.Println(values)
// Output:
// [a a b c d]
}
```
### <span id="IsDisjoint">IsDisjoint</span>
<p>Checks two maps are disjoint if they have no keys in common</p>
<b>Signature:</b>
@@ -312,6 +344,7 @@ func main() {
```go
func IsDisjoint[K comparable, V any](mapA, mapB map[K]V) bool
```
<b>Example:</b>
```go
@@ -323,30 +356,28 @@ import (
)
func main() {
m1 := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
m2 := map[string]int{
"d": 22,
}
m3 := map[int]string{
6: "a",
}
m3 := map[string]int{
"a": 22,
}
ok := maputil.IsDisjoint(m2, m1)
fmt.Println(ok) // false
result1 := maputil.IsDisjoint(m1, m2)
result2 := maputil.IsDisjoint(m1, m3)
ok = maputil.IsDisjoint(m2, m3)
fmt.Println(ok) // true
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```
```

View File

@@ -1,16 +1,17 @@
# Maputil
maputil包包括一些操作map的函数。
maputil 包包括一些操作 map 的函数。
<div STYLE="page-break-after: always;"></div>
## 源码:
- [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/map.go](https://github.com/duke-git/lancet/blob/main/maputil/map.go)
<div STYLE="page-break-after: always;"></div>
## 用法:
```go
import (
"github.com/duke-git/lancet/v2/maputil"
@@ -20,22 +21,22 @@ import (
<div STYLE="page-break-after: always;"></div>
## 目录:
- [ForEach](#ForEach)
- [Filter](#Filter)
- [Intersect](#Intersect)
- [Keys](#Keys)
- [Merge](#Merge)
- [Minus](#Minus)
- [Values](#Values)
- [IsDisjoint](#IsDisjoint)
- [ForEach](#ForEach)
- [Filter](#Filter)
- [Intersect](#Intersect)
- [Keys](#Keys)
- [Merge](#Merge)
- [Minus](#Minus)
- [Values](#Values)
- [IsDisjoint](#IsDisjoint)
<div STYLE="page-break-after: always;"></div>
## API文档:
## API 文档:
### <span id="ForEach">ForEach</span>
<p>对map中的每对key和value执行iteratee函数</p>
<b>函数签名:</b>
@@ -43,7 +44,8 @@ import (
```go
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V))
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -54,26 +56,28 @@ import (
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
}
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
}
var sum int
var sum int
maputil.ForEach(m, func(_ string, value int) {
sum += value
})
fmt.Println(sum) // 10
maputil.ForEach(m, func(_ string, value int) {
sum += value
})
fmt.Println(sum)
// Output:
// 10
}
```
### <span id="Filter">Filter</span>
<p>迭代map中的每对key和value, 返回符合predicate函数的key, value</p>
<b>函数签名:</b>
@@ -81,7 +85,8 @@ func main() {
```go
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -92,29 +97,32 @@ import (
)
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
}
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
})
res := maputil.Filter(m, isEven)
fmt.Println(res) // map[string]int{"b": 2, "d": 4,}
maputil.Filter(m, func(_ string, value int) {
sum += value
})
result := Filter(m, isEven)
fmt.Println(result)
// Output:
// map[b:2 d:4]
}
```
### <span id="Intersect">Intersect</span>
<p>多个map的交集操作</p>
<b>函数签名:</b>
@@ -122,7 +130,8 @@ func main() {
```go
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -133,37 +142,42 @@ import (
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"a": 1,
"b": 2,
"c": 6,
"d": 7,
}
m2 := map[string]int{
"a": 1,
"b": 2,
"c": 6,
"d": 7,
}
m3 := map[string]int{
"a": 1,
"b": 9,
"e": 9,
}
m3 := map[string]int{
"a": 1,
"b": 9,
"e": 9,
}
fmt.Println(maputil.Intersect(m1)) // map[string]int{"a": 1, "b": 2, "c": 3}
result1 := maputil.Intersect(m1)
result2 := maputil.Intersect(m1, m2)
result3 := maputil.Intersect(m1, m2, m3)
fmt.Println(maputil.Intersect(m1, m2)) // map[string]int{"a": 1, "b": 2}
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(maputil.Intersect(m1, m2, m3)) // map[string]int{"a": 1}
// Output:
// map[a:1 b:2 c:3]
// map[a:1 b:2]
// map[a:1]
}
```
### <span id="Keys">Keys</span>
<p>返回map中所有key的切片</p>
<b>函数签名:</b>
@@ -171,7 +185,8 @@ func main() {
```go
func Keys[K comparable, V any](m map[K]V) []K
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -182,24 +197,26 @@ import (
)
func main() {
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
keys := maputil.Keys(m)
sort.Ints(keys)
fmt.Println(keys) // []int{1, 2, 3, 4, 5}
keys := maputil.Keys(m)
sort.Ints(keys)
fmt.Println(keys)
// Output:
// [1 2 3 4 5]
}
```
### <span id="Merge">Merge</span>
<p>合并多个maps, 相同的key会被后来的key覆盖</p>
<b>函数签名:</b>
@@ -207,7 +224,8 @@ func main() {
```go
func Merge[K comparable, V any](maps ...map[K]V) map[K]V
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -218,21 +236,26 @@ import (
)
func main() {
m1 := map[int]string{
1: "a",
2: "b",
}
m2 := map[int]string{
1: "1",
3: "2",
}
fmt.Println(maputil.Merge(m1, m2)) // map[int]string{1:"1", 2:"b", 3:"2",}
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]
}
```
### <span id="Minus">Minus</span>
<p>返回一个map其中的key存在于mapA不存在于mapB.</p>
<b>函数签名:</b>
@@ -240,7 +263,8 @@ func main() {
```go
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -251,25 +275,29 @@ import (
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"a": 11,
"b": 22,
"d": 33,
}
m2 := map[string]int{
"a": 11,
"b": 22,
"d": 33,
}
fmt.Println(maputil.Minus(m1, m2)) //map[string]int{"c": 3}
result := maputil.Minus(m1, m2)
fmt.Println(result)
// Output:
// map[c:3]
}
```
### <span id="Values">Values</span>
<p>返回map中所有value的切片</p>
<b>函数签名:</b>
@@ -277,7 +305,8 @@ func main() {
```go
func Values[K comparable, V any](m map[K]V) []V
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -288,23 +317,24 @@ import (
)
func main() {
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
values := maputil.Values(m)
sort.Strings(values)
values := maputil.Values(m)
sort.Strings(values)
fmt.Println(values) // []string{"a", "a", "b", "c", "d"}
// Output:
// [a a b c d]
}
```
### <span id="IsDisjoint">IsDisjoint</span>
<p>验证两个map是否具有不同的key</p>
<b>函数签名:</b>
@@ -312,7 +342,8 @@ func main() {
```go
func IsDisjoint[K comparable, V any](mapA, mapB map[K]V) bool
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -323,30 +354,28 @@ import (
)
func main() {
m1 := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
m2 := map[string]int{
"d": 22,
}
m3 := map[int]string{
6: "a",
}
m3 := map[string]int{
"a": 22,
}
ok := maputil.IsDisjoint(m2, m1)
fmt.Println(ok) // false
result1 := maputil.IsDisjoint(m1, m2)
result2 := maputil.IsDisjoint(m1, m3)
ok = maputil.IsDisjoint(m2, m3)
fmt.Println(ok) // true
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```
```

View File

@@ -1,16 +1,17 @@
# Mathutil
Package mathutil implements some functions for math calculation.
<div STYLE="page-break-after: always;"></div>
## Source:
- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
<div STYLE="page-break-after: always;"></div>
## Example:
```go
import (
"github.com/duke-git/lancet/v2/mathutil"
@@ -20,26 +21,26 @@ import (
<div STYLE="page-break-after: always;"></div>
## 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)
- [Average](#Average)
- [Exponent](#Exponent)
- [Fibonacci](#Fibonacci)
- [Factorial](#Factorial)
- [Max](#Max)
- [MaxBy](#MaxBy)
- [Min](#Min)
- [MinBy](#MaxBy)
- [Percent](#Percent)
- [RoundToFloat](#RoundToFloat)
- [RoundToString](#RoundToString)
- [TruncRound](#TruncRound)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="Average">Average</span>
<p>Return average value of numbers. Maybe call RoundToFloat to round result.</p>
<b>Signature:</b>
@@ -47,6 +48,7 @@ import (
```go
func Average[T constraints.Integer | constraints.Float](numbers ...T) T
```
<b>Example:</b>
```go
@@ -58,16 +60,22 @@ import (
)
func main() {
fmt.Println(mathutil.Average(0, 0)) //0
fmt.Println(mathutil.Average(1, 1)) //1
avg := mathutil.Average(1.2, 1.4) //1.2999999998
roundAvg := mmathutil.RoundToFloat(avg, 1) // 1.3
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
// 1.3
}
```
### <span id="Exponent">Exponent</span>
<p>Calculate x to the nth power.</p>
<b>Signature:</b>
@@ -75,6 +83,7 @@ func main() {
```go
func Exponent(x, n int64) int64
```
<b>Example:</b>
```go
@@ -86,15 +95,23 @@ import (
)
func main() {
fmt.Println(mathutil.Exponent(10, 0)) //1
fmt.Println(mathutil.Exponent(10, 1)) //10
fmt.Println(mathutil.Exponent(10, 2)) //100
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
}
```
### <span id="Fibonacci">Fibonacci</span>
<p>Calculate the nth number of fibonacci sequence.</p>
<b>Signature:</b>
@@ -102,6 +119,7 @@ func main() {
```go
func Fibonacci(first, second, n int) int
```
<b>Example:</b>
```go
@@ -113,17 +131,23 @@ import (
)
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
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
}
```
### <span id="Factorial">Factorial</span>
<p>Calculate the factorial of x.</p>
<b>Signature:</b>
@@ -131,6 +155,7 @@ func main() {
```go
func Factorial(x uint) uint
```
<b>Example:</b>
```go
@@ -142,16 +167,23 @@ import (
)
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
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
}
```
### <span id="Max">Max</span>
<p>Return max value of numbers.</p>
<b>Signature:</b>
@@ -159,6 +191,7 @@ func main() {
```go
func Max[T constraints.Integer | constraints.Float](numbers ...T) T
```
<b>Example:</b>
```go
@@ -170,23 +203,28 @@ import (
)
func main() {
fmt.Println(mathutil.Max(0, 0)) //0
fmt.Println(mathutil.Max(1, 2, 3)) //3
fmt.Println(mathutil.Max(1.2, 1.4, 1.1, 1.4)) //1.4
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
}
```
### <span id="MaxBy">MaxBy</span>
<p>Return the maximum value of a slice using the given comparator function.</p>
<b>Signature:</b>
```go
func MaxBy[T any](slice []T, comparator func(T, T) bool) T
func MaxBy[T any](slice []T, comparator func(T, T) bool) T
```
<b>Example:</b>
```go
@@ -198,26 +236,31 @@ import (
)
func main() {
res1 := mathutil.MaxBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
return len(v1) > len(v2)
})
fmt.Println(res1) //abc
result1 := mathutil.MaxBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
return len(v1) > len(v2)
})
res2 := mathutil.MaxBy([]string{"abd", "abc", "ab"}, func(v1, v2 string) bool {
return len(v1) > len(v2)
})
fmt.Println(res2) //abd
result2 := mathutil.MaxBy([]string{"abd", "abc", "ab"}, func(v1, v2 string) bool {
return len(v1) > len(v2)
})
res3 := mathutil.MaxBy([]string{}, func(v1, v2 string) bool {
return len(v1) > len(v2)
})
fmt.Println(res3) //“”
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
//
}
```
### <span id="Min">Min</span>
<p>Return the minimum value of numbers.</p>
<b>Signature:</b>
@@ -225,6 +268,7 @@ func main() {
```go
func Min[T constraints.Integer | constraints.Float](numbers ...T) T
```
<b>Example:</b>
```go
@@ -236,22 +280,28 @@ import (
)
func main() {
fmt.Println(mathutil.Min(0, 0)) //0
fmt.Println(mathutil.Min(1, 2, 3)) //1
fmt.Println(mathutil.Min(1.2, 1.4, 1.1, 1.4)) //1.1
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
}
```
### <span id="MinBy">MinBy</span>
<p>Return the minimum value of a slice using the given comparator function.</p>
<b>Signature:</b>
```go
func MinBy[T any](slice []T, comparator func(T, T) bool) T
func MinBy[T any](slice []T, comparator func(T, T) bool) T
```
<b>Example:</b>
```go
@@ -263,27 +313,31 @@ import (
)
func main() {
res1 := mathutil.MinBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
return len(v1) < len(v2)
})
fmt.Println(res1) //a
result1 := mathutil.MinBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
return len(v1) < len(v2)
})
res2 := mathutil.MinBy([]string{"ab", "ac", "abc"}, func(v1, v2 string) bool {
return len(v1) < len(v2)
})
fmt.Println(res2) //ab
result2 := mathutil.MinBy([]string{"ab", "ac", "abc"}, func(v1, v2 string) bool {
return len(v1) < len(v2)
})
res3 := mathutil.MinBy([]string{}, func(v1, v2 string) bool {
return len(v1) < len(v2)
})
fmt.Println(res3) //“”
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
//
}
```
### <span id="Percent">Percent</span>
<p>calculate the percentage of val to total, retain n decimal places.</p>
<b>Signature:</b>
@@ -291,6 +345,7 @@ func main() {
```go
func Percent(val, total float64, n int) float64
```
<b>Example:</b>
```go
@@ -302,14 +357,20 @@ import (
)
func main() {
fmt.Println(mathutil.Percent(1, 2, 2)) //0.5
fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //0.33
result1 := mathutil.Percent(1, 2, 2)
result2 := mathutil.Percent(0.1, 0.3, 2)
fmt.Println(result1)
fmt.Println(result2)
// Output:
// 0.5
// 0.33
}
```
### <span id="RoundToFloat">RoundToFloat</span>
<p>Round float up to n decimal places.</p>
<b>Signature:</b>
@@ -317,6 +378,7 @@ func main() {
```go
func RoundToFloat(x float64, n int) float64
```
<b>Example:</b>
```go
@@ -328,18 +390,23 @@ import (
)
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
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
}
```
### <span id="RoundToString">RoundToString</span>
<p>Round float up to n decimal places. will return string.</p>
<b>Signature:</b>
@@ -347,6 +414,7 @@ func main() {
```go
func RoundToString(x float64, n int) string
```
<b>Example:</b>
```go
@@ -358,17 +426,23 @@ import (
)
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"
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
}
```
### <span id="TruncRound">TruncRound</span>
<p>Round float off n decimal places.</p>
<b>Signature:</b>
@@ -376,6 +450,7 @@ func main() {
```go
func TruncRound(x float64, n int) float64
```
<b>Example:</b>
```go
@@ -387,13 +462,17 @@ import (
)
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
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
}
```

View File

@@ -1,16 +1,17 @@
# Mathutil
mathutil包实现了一些数学计算的函数.
mathutil 包实现了一些数学计算的函数.
<div STYLE="page-break-after: always;"></div>
## 源码:
- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
<div STYLE="page-break-after: always;"></div>
## 用法:
```go
import (
"github.com/duke-git/lancet/v2/mathutil"
@@ -20,25 +21,26 @@ import (
<div STYLE="page-break-after: always;"></div>
## 目录
- [Average](#Average)
- [Exponent](#Exponent)
- [Fibonacci](#Fibonacci)
- [Factorial](#Factorial)
- [Max](#Max)
- [MaxBy](#MaxBy)
- [Min](#Min)
- [MinBy](#MaxBy)
- [Percent](#Percent)
- [RoundToFloat](#RoundToFloat)
- [RoundToString](#RoundToString)
- [TruncRound](#TruncRound)
- [Average](#Average)
- [Exponent](#Exponent)
- [Fibonacci](#Fibonacci)
- [Factorial](#Factorial)
- [Max](#Max)
- [MaxBy](#MaxBy)
- [Min](#Min)
- [MinBy](#MaxBy)
- [Percent](#Percent)
- [RoundToFloat](#RoundToFloat)
- [RoundToString](#RoundToString)
- [TruncRound](#TruncRound)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="Average">Average</span>
<p>计算平均数. 可能需要对结果调用RoundToFloat方法四舍五入</p>
<b>函数签名:</b>
@@ -46,7 +48,8 @@ import (
```go
func Average[T constraints.Integer | constraints.Float](numbers ...T) T
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -57,15 +60,22 @@ import (
)
func main() {
fmt.Println(mathutil.Average(0, 0)) //0
fmt.Println(mathutil.Average(1, 1)) //1
avg := mathutil.Average(1.2, 1.4) //1.2999999998
roundAvg := mmathutil.RoundToFloat(avg, 1) // 1.3
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
// 1.3
}
```
### <span id="Exponent">Exponent</span>
<p>指数计算x的n次方</p>
<b>函数签名:</b>
@@ -73,7 +83,8 @@ func main() {
```go
func Exponent(x, n int64) int64
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -84,15 +95,23 @@ import (
)
func main() {
fmt.Println(mathutil.Exponent(10, 0)) //1
fmt.Println(mathutil.Exponent(10, 1)) //10
fmt.Println(mathutil.Exponent(10, 2)) //100
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
}
```
### <span id="Fibonacci">Fibonacci</span>
<p>计算斐波那契数列的第n个数</p>
<b>函数签名:</b>
@@ -100,7 +119,8 @@ func main() {
```go
func Fibonacci(first, second, n int) int
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -111,17 +131,23 @@ import (
)
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
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
}
```
### <span id="Factorial">Factorial</span>
<p>计算阶乘</p>
<b>函数签名:</b>
@@ -129,7 +155,8 @@ func main() {
```go
func Factorial(x uint) uint
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -140,15 +167,23 @@ import (
)
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
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
}
```
### <span id="Max">Max</span>
<p>返回参数中的最大数</p>
<b>函数签名:</b>
@@ -156,7 +191,8 @@ func main() {
```go
func Max[T constraints.Integer | constraints.Float](numbers ...T) T
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -167,23 +203,29 @@ import (
)
func main() {
fmt.Println(mathutil.Max(0, 0)) //0
fmt.Println(mathutil.Max(1, 2, 3)) //3
fmt.Println(mathutil.Max(1.2, 1.4, 1.1, 1.4)) //1.4
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
}
```
### <span id="MaxBy">MaxBy</span>
<p>使用给定的比较器函数返回切片的最大值</p>
<b>函数签名:</b>
```go
func MaxBy[T any](slice []T, comparator func(T, T) bool) T
func MaxBy[T any](slice []T, comparator func(T, T) bool) T
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -194,27 +236,31 @@ import (
)
func main() {
res1 := mathutil.MaxBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
return len(v1) > len(v2)
})
fmt.Println(res1) //abc
result1 := mathutil.MaxBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
return len(v1) > len(v2)
})
res2 := mathutil.MaxBy([]string{"abd", "abc", "ab"}, func(v1, v2 string) bool {
return len(v1) > len(v2)
})
fmt.Println(res2) //abd
result2 := mathutil.MaxBy([]string{"abd", "abc", "ab"}, func(v1, v2 string) bool {
return len(v1) > len(v2)
})
res3 := mathutil.MaxBy([]string{}, func(v1, v2 string) bool {
return len(v1) > len(v2)
})
fmt.Println(res3) //“”
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
//
}
```
### <span id="Min">Min</span>
<p>返回参数中的最小数</p>
<b>函数签名:</b>
@@ -222,7 +268,8 @@ func main() {
```go
func Min[T constraints.Integer | constraints.Float](numbers ...T) T
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -233,23 +280,29 @@ import (
)
func main() {
fmt.Println(mathutil.Min(0, 0)) //0
fmt.Println(mathutil.Min(1, 2, 3)) //1
fmt.Println(mathutil.Min(1.2, 1.4, 1.1, 1.4)) //1.1
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
}
```
### <span id="MinBy">MinBy</span>
<p>使用给定的比较器函数返回切片的最小值</p>
<b>函数签名:</b>
```go
func MinBy[T any](slice []T, comparator func(T, T) bool) T
func MinBy[T any](slice []T, comparator func(T, T) bool) T
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -260,27 +313,31 @@ import (
)
func main() {
res1 := mathutil.MinBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
return len(v1) < len(v2)
})
fmt.Println(res1) //a
result1 := mathutil.MinBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
return len(v1) < len(v2)
})
res2 := mathutil.MinBy([]string{"ab", "ac", "abc"}, func(v1, v2 string) bool {
return len(v1) < len(v2)
})
fmt.Println(res2) //ab
result2 := mathutil.MinBy([]string{"ab", "ac", "abc"}, func(v1, v2 string) bool {
return len(v1) < len(v2)
})
res3 := mathutil.MinBy([]string{}, func(v1, v2 string) bool {
return len(v1) < len(v2)
})
fmt.Println(res3) //“”
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
//
}
```
### <span id="Percent">Percent</span>
<p>计算百分比保留n位小数</p>
<b>函数签名:</b>
@@ -288,7 +345,8 @@ func main() {
```go
func Percent(val, total float64, n int) float64
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -299,14 +357,20 @@ import (
)
func main() {
fmt.Println(mathutil.Percent(1, 2, 2)) //0.5
fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //0.33
result1 := mathutil.Percent(1, 2, 2)
result2 := mathutil.Percent(0.1, 0.3, 2)
fmt.Println(result1)
fmt.Println(result2)
// Output:
// 0.5
// 0.33
}
```
### <span id="RoundToFloat">RoundToFloat</span>
<p>四舍五入保留n位小数</p>
<b>函数签名:</b>
@@ -314,7 +378,8 @@ func main() {
```go
func RoundToFloat(x float64, n int) float64
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -325,18 +390,23 @@ import (
)
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
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
}
```
### <span id="RoundToString">RoundToString</span>
<p>四舍五入保留n位小数返回字符串</p>
<b>函数签名:</b>
@@ -344,7 +414,8 @@ func main() {
```go
func RoundToString(x float64, n int) string
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -355,17 +426,23 @@ import (
)
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"
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
}
```
### <span id="TruncRound">TruncRound</span>
<p>截短n位小数不进行四舍五入</p>
<b>函数签名:</b>
@@ -373,7 +450,8 @@ func main() {
```go
func TruncRound(x float64, n int) float64
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -384,13 +462,17 @@ import (
)
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
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
}
```

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -56,8 +56,8 @@ import (
)
func main() {
randBytes := random.RandBytes(4)
fmt.Println(randBytes)
randBytes := random.RandBytes(4)
fmt.Println(randBytes)
}
```
@@ -82,8 +82,8 @@ import (
)
func main() {
rInt := random.RandInt(1, 10)
fmt.Println(rInt)
rInt := random.RandInt(1, 10)
fmt.Println(rInt)
}
```
@@ -108,8 +108,8 @@ import (
)
func main() {
randStr := random.RandString(6)
fmt.Println(randStr) //pGWsze
randStr := random.RandString(6)
fmt.Println(randStr) //pGWsze
}
```
@@ -134,8 +134,8 @@ import (
)
func main() {
randStr := random.RandString(6)
fmt.Println(randStr) //PACWGF
randStr := random.RandString(6)
fmt.Println(randStr) //PACWGF
}
```
@@ -160,8 +160,8 @@ import (
)
func main() {
randStr := random.RandLower(6)
fmt.Println(randStr) //siqbew
randStr := random.RandLower(6)
fmt.Println(randStr) //siqbew
}
```
@@ -186,8 +186,8 @@ import (
)
func main() {
randStr := random.RandNumeral(6)
fmt.Println(randStr) //035172
randStr := random.RandNumeral(6)
fmt.Println(randStr) //035172
}
```
@@ -212,8 +212,8 @@ import (
)
func main() {
randStr := random.RandNumeralOrLetter(6)
fmt.Println(randStr) //0aW7cQ
randStr := random.RandNumeralOrLetter(6)
fmt.Println(randStr) //0aW7cQ
}
```
@@ -238,10 +238,10 @@ import (
)
func main() {
uuid, err := random.UUIdV4()
uuid, err := random.UUIdV4()
if err != nil {
return
}
fmt.Println(uuid)
fmt.Println(uuid)
}
```

View File

@@ -45,7 +45,7 @@ import (
func RandBytes(length int) []byte
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -56,8 +56,8 @@ import (
)
func main() {
randBytes := random.RandBytes(4)
fmt.Println(randBytes)
randBytes := random.RandBytes(4)
fmt.Println(randBytes)
}
```
@@ -71,7 +71,7 @@ func main() {
func RandInt(min, max int) int
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -82,8 +82,8 @@ import (
)
func main() {
rInt := random.RandInt(1, 10)
fmt.Println(rInt)
rInt := random.RandInt(1, 10)
fmt.Println(rInt)
}
```
@@ -97,7 +97,7 @@ func main() {
func RandString(length int) string
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -108,8 +108,8 @@ import (
)
func main() {
randStr := random.RandString(6)
fmt.Println(randStr) //pGWsze
randStr := random.RandString(6)
fmt.Println(randStr) //pGWsze
}
```
@@ -123,7 +123,7 @@ func main() {
func RandUpper(length int) string
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -134,8 +134,8 @@ import (
)
func main() {
randStr := random.RandString(6)
fmt.Println(randStr) //PACWGF
randStr := random.RandString(6)
fmt.Println(randStr) //PACWGF
}
```
@@ -149,7 +149,7 @@ func main() {
func RandLower(length int) string
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -160,8 +160,8 @@ import (
)
func main() {
randStr := random.RandLower(6)
fmt.Println(randStr) //siqbew
randStr := random.RandLower(6)
fmt.Println(randStr) //siqbew
}
```
@@ -175,7 +175,7 @@ func main() {
func RandNumeral(length int) string
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -186,8 +186,8 @@ import (
)
func main() {
randStr := random.RandNumeral(6)
fmt.Println(randStr) //035172
randStr := random.RandNumeral(6)
fmt.Println(randStr) //035172
}
```
@@ -201,7 +201,7 @@ func main() {
func RandNumeralOrLetter(length int) string
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -212,8 +212,8 @@ import (
)
func main() {
randStr := random.RandNumeralOrLetter(6)
fmt.Println(randStr) //0aW7cQ
randStr := random.RandNumeralOrLetter(6)
fmt.Println(randStr) //0aW7cQ
}
```
@@ -227,7 +227,7 @@ func main() {
func UUIdV4() (string, error)
```
<b>例:</b>
<b>例:</b>
```go
package main
@@ -238,10 +238,10 @@ import (
)
func main() {
uuid, err := random.UUIdV4()
uuid, err := random.UUIdV4()
if err != nil {
return
}
fmt.Println(uuid)
fmt.Println(uuid)
}
```

View File

@@ -1,16 +1,17 @@
# Retry
Package retry is for executing a function repeatedly until it was successful or canceled by the context.
<div STYLE="page-break-after: always;"></div>
## Source:
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
<div STYLE="page-break-after: always;"></div>
## Usage:
```go
import (
"github.com/duke-git/lancet/v2/retry"
@@ -20,18 +21,19 @@ import (
<div STYLE="page-break-after: always;"></div>
## Index
- [Context](#Context)
- [Retry](#Retry)
- [RetryFunc](#RetryFunc)
- [RetryDuration](#RetryDuration)
- [RetryTimes](#RetryTimes)
- [Context](#Context)
- [Retry](#Retry)
- [RetryFunc](#RetryFunc)
- [RetryDuration](#RetryDuration)
- [RetryTimes](#RetryTimes)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="Context">Context</span>
<p>Set retry context config, can cancel the retry with context.</p>
<b>Signature:</b>
@@ -39,43 +41,46 @@ import (
```go
func Context(ctx context.Context)
```
<b>Example:</b>
```go
import (
"context"
"errors"
"fmt"
"github.com/duke-git/lancet/v2/retry"
"time"
"context"
"errors"
"fmt"
"github.com/duke-git/lancet/v2/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")
}
ctx, cancel := context.WithCancel(context.TODO())
err := retry.Retry(increaseNumber,
retry.RetryDuration(time.Microsecond*50),
retry.Context(ctx),
)
number := 0
increaseNumber := func() error {
number++
if number > 3 {
cancel()
}
return errors.New("error occurs")
}
if err != nil {
fmt.Println(err) //retry is cancelled
}
duration := retry.RetryDuration(time.Microsecond*50)
retry.Retry(increaseNumber,
duration,
retry.Context(ctx),
)
fmt.Println(number)
// Output:
// 4
}
```
### <span id="RetryFunc">RetryFunc</span>
<p>Function that retry executes.</p>
<b>Signature:</b>
@@ -83,6 +88,7 @@ func main() {
```go
type RetryFunc func() error
```
<b>Example:</b>
```go
@@ -96,28 +102,31 @@ import (
)
func main() {
var number int
number := 0
var increaseNumber retry.RetryFunc = func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
duration := retry.RetryDuration(time.Microsecond*50)
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
err := retry.Retry(increaseNumber, duration)
if err != nil {
log.Fatal(err)
}
return
}
fmt.Println(number) //3
fmt.Println(number)
// Output:
// 3
}
```
### <span id="RetryTimes">RetryTimes</span>
<p>Set times of retry. Default times is 5.</p>
<b>Signature:</b>
@@ -125,6 +134,7 @@ func main() {
```go
func RetryTimes(n uint)
```
<b>Example:</b>
```go
@@ -138,26 +148,28 @@ import (
)
func main() {
var number int
number := 0
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
err := retry.Retry(increaseNumber, retry.RetryTimes(2))
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
}
fmt.Println(err)
}
// Output:
// function main.main.func1 run failed after 2 times retry
}
```
### <span id="RetryDuration">RetryDuration</span>
<p>Set duration of retries. Default duration is 3 second.</p>
<b>Signature:</b>
@@ -165,6 +177,7 @@ func main() {
```go
func RetryDuration(d time.Duration)
```
<b>Example:</b>
```go
@@ -178,26 +191,31 @@ import (
)
func main() {
var number int
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
number := 0
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
duration := retry.RetryDuration(time.Microsecond*50)
err := retry.Retry(increaseNumber, duration)
if err != nil {
log.Fatal(err)
}
return
}
fmt.Println(number) //3
fmt.Println(number)
// Output:
// 3
}
```
### <span id="Retry">Retry</span>
<p>Executes the retryFunc repeatedly until it was successful or canceled by the context.</p>
<b>Signature:</b>
@@ -205,6 +223,7 @@ func main() {
```go
func Retry(retryFunc RetryFunc, opts ...Option) error
```
<b>Example:</b>
```go
@@ -218,20 +237,25 @@ import (
)
func main() {
var number int
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
number := 0
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
duration := retry.RetryDuration(time.Microsecond*50)
err := retry.Retry(increaseNumber, duration)
if err != nil {
log.Fatal(err)
}
return
}
fmt.Println(number) //3
fmt.Println(number)
// Output:
// 3
}
```

View File

@@ -1,16 +1,17 @@
# Retry
retry重试执行函数直到函数运行成功或被context cancel。
retry 重试执行函数直到函数运行成功或被 context cancel。
<div STYLE="page-break-after: always;"></div>
## 源码:
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
<div STYLE="page-break-after: always;"></div>
## 用法:
```go
import (
"github.com/duke-git/lancet/v2/retry"
@@ -20,20 +21,19 @@ import (
<div STYLE="page-break-after: always;"></div>
## 目录
- [Context](#Context)
- [Retry](#Retry)
- [RetryFunc](#RetryFunc)
- [RetryDuration](#RetryDuration)
- [RetryTimes](#RetryTimes)
- [Context](#Context)
- [Retry](#Retry)
- [RetryFunc](#RetryFunc)
- [RetryDuration](#RetryDuration)
- [RetryTimes](#RetryTimes)
<div STYLE="page-break-after: always;"></div>
## Document文档
## Document 文档
### <span id="Context">Context</span>
<p>设置重试context参数</p>
<b>函数签名:</b>
@@ -41,43 +41,46 @@ import (
```go
func Context(ctx context.Context)
```
<b>例子:</b>
<b>示例:</b>
```go
import (
"context"
"errors"
"fmt"
"lancet-demo/retry"
"time"
"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")
}
ctx, cancel := context.WithCancel(context.TODO())
err := retry.Retry(increaseNumber,
retry.RetryDuration(time.Microsecond*50),
retry.Context(ctx),
)
number := 0
increaseNumber := func() error {
number++
if number > 3 {
cancel()
}
return errors.New("error occurs")
}
if err != nil {
fmt.Println(err) //retry is cancelled
}
duration := retry.RetryDuration(time.Microsecond*50)
retry.Retry(increaseNumber,
duration,
retry.Context(ctx),
)
fmt.Println(number)
// Output:
// 4
}
```
### <span id="RetryFunc">RetryFunc</span>
<p>被重试执行的函数</p>
<b>函数签名:</b>
@@ -85,7 +88,8 @@ func main() {
```go
type RetryFunc func() error
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -98,27 +102,31 @@ import (
)
func main() {
var number int
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
number := 0
var increaseNumber retry.RetryFunc = func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
duration := retry.RetryDuration(time.Microsecond*50)
err := retry.Retry(increaseNumber, duration)
if err != nil {
log.Fatal(err)
}
return
}
fmt.Println(number) //3
fmt.Println(number)
// Output:
// 3
}
```
### <span id="RetryTimes">RetryTimes</span>
<p>设置重试次数默认5</p>
<b>函数签名:</b>
@@ -126,7 +134,8 @@ func main() {
```go
func RetryTimes(n uint)
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -139,25 +148,28 @@ import (
)
func main() {
var number int
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
number := 0
err := retry.Retry(increaseNumber, retry.RetryTimes(2))
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
}
fmt.Println(err)
}
// Output:
// function main.main.func1 run failed after 2 times retry
}
```
### <span id="RetryDuration">RetryDuration</span>
<p>设置重试间隔时间默认3秒</p>
<b>函数签名:</b>
@@ -165,7 +177,8 @@ func main() {
```go
func RetryDuration(d time.Duration)
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -178,26 +191,31 @@ import (
)
func main() {
var number int
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
number := 0
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
duration := retry.RetryDuration(time.Microsecond*50)
err := retry.Retry(increaseNumber, duration)
if err != nil {
log.Fatal(err)
}
return
}
fmt.Println(number) //3
fmt.Println(number)
// Output:
// 3
}
```
### <span id="Retry">Retry</span>
<p>重试执行函数retryFunc直到函数运行成功或被context停止</p>
<b>函数签名:</b>
@@ -205,7 +223,8 @@ func main() {
```go
func Retry(retryFunc RetryFunc, opts ...Option) error
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -218,20 +237,25 @@ import (
)
func main() {
var number int
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
number := 0
increaseNumber := func() error {
number++
if number == 3 {
return nil
}
return errors.New("error occurs")
}
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
duration := retry.RetryDuration(time.Microsecond*50)
err := retry.Retry(increaseNumber, duration)
if err != nil {
log.Fatal(err)
}
return
}
fmt.Println(number) //3
fmt.Println(number)
// Output:
// 3
}
```

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,17 @@
# System
Package system contains some functions about os, runtime, shell command.
<div STYLE="page-break-after: always;"></div>
## Source:
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
<div STYLE="page-break-after: always;"></div>
## Usage:
```go
import (
"github.com/duke-git/lancet/v2/system"
@@ -20,23 +21,23 @@ import (
<div STYLE="page-break-after: always;"></div>
## Index
- [IsWindows](#IsWindows)
- [IsLinux](#IsLinux)
- [IsMac](#IsMac)
- [GetOsEnv](#GetOsEnv)
- [SetOsEnv](#SetOsEnv)
- [RemoveOsEnv](#RemoveOsEnv)
- [CompareOsEnv](#CompareOsEnv)
- [ExecCommand](#ExecCommand)
- [GetOsBits](#GetOsBits)
- [IsWindows](#IsWindows)
- [IsLinux](#IsLinux)
- [IsMac](#IsMac)
- [GetOsEnv](#GetOsEnv)
- [SetOsEnv](#SetOsEnv)
- [RemoveOsEnv](#RemoveOsEnv)
- [CompareOsEnv](#CompareOsEnv)
- [ExecCommand](#ExecCommand)
- [GetOsBits](#GetOsBits)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="IsWindows">IsWindows</span>
<p>Check if current os is windows.</p>
<b>Signature:</b>
@@ -44,24 +45,23 @@ import (
```go
func IsWindows() bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
isOsWindows := system.IsWindows()
fmt.Println(isOsWindows)
isOsWindows := system.IsWindows()
fmt.Println(isOsWindows)
}
```
### <span id="IsLinux">IsLinux</span>
<p>Check if current os is linux.</p>
<b>Signature:</b>
@@ -69,23 +69,23 @@ func main() {
```go
func IsLinux() bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
isOsLinux := system.IsLinux()
fmt.Println(isOsLinux)
isOsLinux := system.IsLinux()
fmt.Println(isOsLinux)
}
```
### <span id="IsMac">IsMac</span>
<p>Check if current os is macos.</p>
<b>Signature:</b>
@@ -93,23 +93,23 @@ func main() {
```go
func IsMac() bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
isOsMac := system.IsMac()
fmt.Println(isOsMac)
isOsMac := system.IsMac()
fmt.Println(isOsMac)
}
```
### <span id="GetOsEnv">GetOsEnv</span>
<p>Gets the value of the environment variable named by the key.</p>
<b>Signature:</b>
@@ -117,23 +117,29 @@ func main() {
```go
func GetOsEnv(key string) string
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
fooEnv := system.GetOsEnv("foo")
fmt.Println(fooEnv)
err := system.SetOsEnv("foo", "abc")
result := system.GetOsEnv("foo")
fmt.Println(err)
fmt.Println(result)
// Output:
// <nil>
// abc
}
```
### <span id="SetOsEnv">SetOsEnv</span>
<p>Sets the value of the environment variable named by the key.</p>
<b>Signature:</b>
@@ -141,24 +147,29 @@ func main() {
```go
func SetOsEnv(key, value string) error
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
err := system.SetOsEnv("foo", "foo_value")
fmt.Println(err)
err := system.SetOsEnv("foo", "abc")
result := system.GetOsEnv("foo")
fmt.Println(err)
fmt.Println(result)
// Output:
// <nil>
// abc
}
```
### <span id="RemoveOsEnv">RemoveOsEnv</span>
<p>Remove a single environment variable.</p>
<b>Signature:</b>
@@ -166,25 +177,37 @@ func main() {
```go
func RemoveOsEnv(key string) error
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
err := system.RemoveOsEnv("foo")
if err != nil {
fmt.Println(err)
}
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:
// <nil>
// <nil>
// abc
//
}
```
### <span id="CompareOsEnv">CompareOsEnv</span>
<p>Get env named by the key and compare it with comparedEnv.</p>
<b>Signature:</b>
@@ -192,25 +215,32 @@ func main() {
```go
func CompareOsEnv(key, comparedEnv string) bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
system.SetOsEnv("foo", "foo_value")
res := system.CompareOsEnv("foo", "foo_value")
fmt.Println(res) //true
err := system.SetOsEnv("foo", "abc")
if err != nil {
return
}
result := system.CompareOsEnv("foo", "abc")
fmt.Println(result)
// Output:
// true
}
```
### <span id="ExecCommand">CompareOsEnv</span>
<p>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.</p>
<b>Signature:</b>
@@ -218,40 +248,39 @@ func main() {
```go
func ExecCommand(command string) (stdout, stderr string, err error)
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
// linux or mac
stdout, stderr, err := system.ExecCommand("ls")
fmt.Println("std out: ", stdout)
fmt.Println("std err: ", stderr)
assert.Equal("", stderr)
// linux or mac
stdout, stderr, err := system.ExecCommand("ls")
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)
// 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())
}
// 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())
}
}
```
### <span id="GetOsBits">GetOsBits</span>
<p>Get current os bits, 32bit or 64bit. return 32 or 64</p>
<b>Signature:</b>
@@ -259,19 +288,17 @@ func main() {
```go
func GetOsBits() int
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
osBit := system.GetOsBits()
fmt.Println(osBit)
osBit := system.GetOsBits()
fmt.Println(osBit) // 32 or 64
}
```

View File

@@ -1,16 +1,17 @@
# System
system包含os, runtime, shell command相关函数。
system 包含 os, runtime, shell command 相关函数。
<div STYLE="page-break-after: always;"></div>
## 源码:
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
<div STYLE="page-break-after: always;"></div>
## 用法:
```go
import (
"github.com/duke-git/lancet/v2/system"
@@ -20,23 +21,23 @@ import (
<div STYLE="page-break-after: always;"></div>
## 目录
- [IsWindows](#IsWindows)
- [IsLinux](#IsLinux)
- [IsMac](#IsMac)
- [GetOsEnv](#GetOsEnv)
- [SetOsEnv](#SetOsEnv)
- [RemoveOsEnv](#RemoveOsEnv)
- [CompareOsEnv](#CompareOsEnv)
- [ExecCommand](#ExecCommand)
- [GetOsBits](#GetOsBits)
- [IsWindows](#IsWindows)
- [IsLinux](#IsLinux)
- [IsMac](#IsMac)
- [GetOsEnv](#GetOsEnv)
- [SetOsEnv](#SetOsEnv)
- [RemoveOsEnv](#RemoveOsEnv)
- [CompareOsEnv](#CompareOsEnv)
- [ExecCommand](#ExecCommand)
- [GetOsBits](#GetOsBits)
<div STYLE="page-break-after: always;"></div>
## Documentation文档
## Documentation 文档
### <span id="IsWindows">IsWindows</span>
<p>检查当前操作系统是否是windows</p>
<b>Signature:</b>
@@ -44,24 +45,23 @@ import (
```go
func IsWindows() bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
isOsWindows := system.IsWindows()
fmt.Println(isOsWindows)
isOsWindows := system.IsWindows()
fmt.Println(isOsWindows)
}
```
### <span id="IsLinux">IsLinux</span>
<p>检查当前操作系统是否是linux</p>
<b>Signature:</b>
@@ -69,23 +69,23 @@ func main() {
```go
func IsLinux() bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
isOsLinux := system.IsLinux()
fmt.Println(isOsLinux)
isOsLinux := system.IsLinux()
fmt.Println(isOsLinux)
}
```
### <span id="IsMac">IsMac</span>
<p>检查当前操作系统是否是macos</p>
<b>Signature:</b>
@@ -93,23 +93,23 @@ func main() {
```go
func IsMac() bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
isOsMac := system.IsMac()
fmt.Println(isOsMac)
isOsMac := system.IsMac()
fmt.Println(isOsMac)
}
```
### <span id="GetOsEnv">GetOsEnv</span>
<p>获取key命名的环境变量的值</p>
<b>Signature:</b>
@@ -117,23 +117,29 @@ func main() {
```go
func GetOsEnv(key string) string
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
fooEnv := system.GetOsEnv("foo")
fmt.Println(fooEnv)
err := system.SetOsEnv("foo", "abc")
result := system.GetOsEnv("foo")
fmt.Println(err)
fmt.Println(result)
// Output:
// <nil>
// abc
}
```
### <span id="SetOsEnv">SetOsEnv</span>
<p>设置由key命名的环境变量的值</p>
<b>Signature:</b>
@@ -141,24 +147,29 @@ func main() {
```go
func SetOsEnv(key, value string) error
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
err := system.SetOsEnv("foo", "foo_value")
fmt.Println(err)
err := system.SetOsEnv("foo", "abc")
result := system.GetOsEnv("foo")
fmt.Println(err)
fmt.Println(result)
// Output:
// <nil>
// abc
}
```
### <span id="RemoveOsEnv">RemoveOsEnv</span>
<p>删除单个环境变量</p>
<b>Signature:</b>
@@ -166,25 +177,37 @@ func main() {
```go
func RemoveOsEnv(key string) error
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
err := system.RemoveOsEnv("foo")
if err != nil {
fmt.Println(err)
}
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:
// <nil>
// <nil>
// abc
//
}
```
### <span id="CompareOsEnv">CompareOsEnv</span>
<p>获取key命名的环境变量值并与compareEnv进行比较</p>
<b>Signature:</b>
@@ -192,25 +215,32 @@ func main() {
```go
func CompareOsEnv(key, comparedEnv string) bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
system.SetOsEnv("foo", "foo_value")
res := system.CompareOsEnv("foo", "foo_value")
fmt.Println(res) //true
err := system.SetOsEnv("foo", "abc")
if err != nil {
return
}
result := system.CompareOsEnv("foo", "abc")
fmt.Println(result)
// Output:
// true
}
```
### <span id="ExecCommand">ExecCommand</span>
<p>执行shell命令返回命令的stdout和stderr字符串如果出现错误则返回错误。参数`command`是一个完整的命令字符串如ls-alinuxdirwindowsping 127.0.0.1。在linux中使用/bin/bash-c执行命令在windows中使用powershell.exe执行命令。</p>
<b>Signature:</b>
@@ -218,40 +248,39 @@ func main() {
```go
func ExecCommand(command string) (stdout, stderr string, err error)
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
// linux or mac
stdout, stderr, err := system.ExecCommand("ls")
fmt.Println("std out: ", stdout)
fmt.Println("std err: ", stderr)
assert.Equal("", stderr)
// linux or mac
stdout, stderr, err := system.ExecCommand("ls")
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)
// 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())
}
// 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())
}
}
```
### <span id="GetOsBits">GetOsBits</span>
<p>获取当前操作系统位数返回32或64</p>
<b>函数签名:</b>
@@ -259,23 +288,17 @@ func main() {
```go
func GetOsBits() int
```
<b>例子:</b>
<b>示例:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/system"
"fmt"
"github.com/duke-git/lancet/v2/system"
)
func main() {
osBit := system.GetOsBits()
fmt.Println(osBit)
osBit := system.GetOsBits()
fmt.Println(osBit) // 32 or 64
}
```

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,17 @@
# Xerror
Package xerror implements helpers for errors.
<div STYLE="page-break-after: always;"></div>
## Source:
- [https://github.com/duke-git/lancet/blob/main/xerror/xerror.go](https://github.com/duke-git/lancet/blob/main/xerror/xerror.go)
- [https://github.com/duke-git/lancet/blob/main/xerror/xerror.go](https://github.com/duke-git/lancet/blob/main/xerror/xerror.go)
<div STYLE="page-break-after: always;"></div>
## Usage:
```go
import (
"github.com/duke-git/lancet/v2/xerror"
@@ -19,15 +21,15 @@ import (
<div STYLE="page-break-after: always;"></div>
## Index
- [Unwrap](#Unwrap)
- [Unwrap](#Unwrap)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="Unwrap">Unwrap</span>
<p>Unwrap if err is nil then it returns a valid value. If err is not nil, Unwrap panics with err.</p>
<b>Signature:</b>
@@ -35,6 +37,7 @@ import (
```go
func Unwrap[T any](val T, err error) T
```
<b>Example:</b>
```go
@@ -46,20 +49,20 @@ import (
)
func main() {
result1 := xerror.Unwrap(strconv.Atoi("42"))
fmt.Println(result1)
result1 := xerror.Unwrap(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)
}()
_, err := strconv.Atoi("4o2")
defer func() {
v := recover()
result2 := reflect.DeepEqual(err.Error(), v.(*strconv.NumError).Error())
fmt.Println(result2)
}()
xerror.Unwrap(strconv.Atoi("4o2"))
xerror.Unwrap(strconv.Atoi("4o2"))
// Output:
// 42
// true
// Output:
// 42
// true
}
```

View File

@@ -1,15 +1,17 @@
# Xerror
xerror错误处理逻辑封装
xerror 错误处理逻辑封装
<div STYLE="page-break-after: always;"></div>
## 源码:
- [https://github.com/duke-git/lancet/blob/main/xerror/xerror.go](https://github.com/duke-git/lancet/blob/main/xerror/xerror.go)
- [https://github.com/duke-git/lancet/blob/main/xerror/xerror.go](https://github.com/duke-git/lancet/blob/main/xerror/xerror.go)
<div STYLE="page-break-after: always;"></div>
## 用法:
```go
import (
"github.com/duke-git/lancet/v2/xerror"
@@ -19,15 +21,15 @@ import (
<div STYLE="page-break-after: always;"></div>
## 目录
- [Unwrap](#Unwrap)
- [Unwrap](#Unwrap)
<div STYLE="page-break-after: always;"></div>
## 文档
### <span id="Unwrap">Unwrap</span>
<p>检查error, 如果err为nil则展开则它返回一个有效值如果err不是nil则Unwrap使用err发生panic。</p>
<b>函数签名:</b>
@@ -35,7 +37,8 @@ import (
```go
func Unwrap[T any](val T, err error) T
```
<b>例子:</b>
<b>示例:</b>
```go
package main
@@ -46,20 +49,20 @@ import (
)
func main() {
result1 := xerror.Unwrap(strconv.Atoi("42"))
fmt.Println(result1)
result1 := xerror.Unwrap(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)
}()
_, err := strconv.Atoi("4o2")
defer func() {
v := recover()
result2 := reflect.DeepEqual(err.Error(), v.(*strconv.NumError).Error())
fmt.Println(result2)
}()
xerror.Unwrap(strconv.Atoi("4o2"))
xerror.Unwrap(strconv.Atoi("4o2"))
// Output:
// 42
// true
// Output:
// 42
// true
}
```

View File

@@ -47,7 +47,7 @@ func Before(n int, fn any) func(args ...any) []reflect.Value {
type CurryFn[T any] func(...T) T
// New make a curry function for specific value.
// Play: Todo
// Play: https://go.dev/play/p/5HopfDwANKX
func (cf CurryFn[T]) New(val T) func(...T) T {
return func(vals ...T) T {
args := append([]T{val}, vals...)
@@ -56,7 +56,7 @@ func (cf CurryFn[T]) New(val T) func(...T) T {
}
// Compose compose the functions from right to left.
// Play: Todo
// Play: https://go.dev/play/p/KKfugD4PKYF
func Compose[T any](fnList ...func(...T) T) func(...T) T {
return func(args ...T) T {
firstFn := fnList[0]

View File

@@ -114,15 +114,15 @@ func ExampleSchedule() {
count++
}
stop := Schedule(1*time.Second, increase)
stop := Schedule(2*time.Second, increase)
time.Sleep(3 * time.Second)
time.Sleep(2 * time.Second)
close(stop)
fmt.Println(count)
// Output:
// 3
// 2
}
func ExamplePipeline() {

View File

@@ -3,7 +3,7 @@ package function
import "time"
// Watcher is used for record code excution time
// Play: Todo
// Play: https://go.dev/play/p/l2yrOpCLd1I
type Watcher struct {
startTime int64
stopTime int64

View File

@@ -55,7 +55,7 @@ func Factorial(x uint) uint {
}
// Percent calculate the percentage of value to total.
// Play: Todo
// Play: https://go.dev/play/p/QQM9B13coSP
func Percent(val, total float64, n int) float64 {
if total == 0 {
return float64(0)

View File

@@ -13,12 +13,21 @@
package netutil
import (
"bytes"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"reflect"
"regexp"
"sort"
"strings"
"time"
"github.com/duke-git/lancet/v2/slice"
)
// HttpGet send get http request.
@@ -78,3 +87,220 @@ func ConvertMapToQueryString(param map[string]any) string {
}
return build.String()
}
// HttpRequest struct is a composed http request
type HttpRequest struct {
RawURL string
Method string
Headers http.Header
QueryParams url.Values
FormData url.Values
Body []byte
}
// HttpClientConfig contains some configurations for http client
type HttpClientConfig struct {
SSLEnabled bool
TLSConfig *tls.Config
Compressed bool
HandshakeTimeout time.Duration
ResponseTimeout time.Duration
Verbose bool
}
// defaultHttpClientConfig defalut client config
var defaultHttpClientConfig = &HttpClientConfig{
Compressed: false,
HandshakeTimeout: 20 * time.Second,
ResponseTimeout: 40 * time.Second,
}
// HttpClient is used for sending http request
type HttpClient struct {
*http.Client
TLS *tls.Config
Request *http.Request
Config HttpClientConfig
}
// NewHttpClient make a HttpClient instance
func NewHttpClient() *HttpClient {
client := &HttpClient{
Client: &http.Client{
Transport: &http.Transport{
TLSHandshakeTimeout: defaultHttpClientConfig.HandshakeTimeout,
ResponseHeaderTimeout: defaultHttpClientConfig.ResponseTimeout,
DisableCompression: !defaultHttpClientConfig.Compressed,
},
},
Config: *defaultHttpClientConfig,
}
return client
}
// NewHttpClientWithConfig make a HttpClient instance with pass config
func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient {
if config == nil {
config = defaultHttpClientConfig
}
client := &HttpClient{
Client: &http.Client{
Transport: &http.Transport{
TLSHandshakeTimeout: config.HandshakeTimeout,
ResponseHeaderTimeout: config.ResponseTimeout,
DisableCompression: !config.Compressed,
},
},
Config: *config,
}
if config.SSLEnabled {
client.TLS = config.TLSConfig
}
return client
}
// SendRequest send http request.
// Play: https://go.dev/play/p/jUSgynekH7G
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error) {
err := validateRequest(request)
if err != nil {
return nil, err
}
rawUrl := request.RawURL
req, err := http.NewRequest(request.Method, rawUrl, bytes.NewBuffer(request.Body))
if err != nil {
return nil, err
}
client.setTLS(rawUrl)
client.setHeader(req, request.Headers)
err = client.setQueryParam(req, rawUrl, request.QueryParams)
if err != nil {
return nil, err
}
if request.FormData != nil {
client.setFormData(req, request.FormData)
}
client.Request = req
resp, err := client.Client.Do(req)
if err != nil {
return nil, err
}
return resp, nil
}
// DecodeResponse decode response into target object.
// Play: https://go.dev/play/p/jUSgynekH7G
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error {
if resp == nil {
return errors.New("invalid target param")
}
defer resp.Body.Close()
return json.NewDecoder(resp.Body).Decode(target)
}
// setTLS set http client transport TLSClientConfig
func (client *HttpClient) setTLS(rawUrl string) {
if strings.HasPrefix(rawUrl, "https") {
if transport, ok := client.Client.Transport.(*http.Transport); ok {
transport.TLSClientConfig = client.TLS
}
}
}
// setHeader set http rquest header
func (client *HttpClient) setHeader(req *http.Request, headers http.Header) {
if headers == nil {
headers = make(http.Header)
}
if _, ok := headers["Accept"]; !ok {
headers["Accept"] = []string{"*/*"}
}
if _, ok := headers["Accept-Encoding"]; !ok && client.Config.Compressed {
headers["Accept-Encoding"] = []string{"deflate, gzip"}
}
req.Header = headers
}
// setQueryParam set http request query string param
func (client *HttpClient) setQueryParam(req *http.Request, reqUrl string, queryParam url.Values) error {
if queryParam != nil {
if !strings.Contains(reqUrl, "?") {
reqUrl = reqUrl + "?" + queryParam.Encode()
} else {
reqUrl = reqUrl + "&" + queryParam.Encode()
}
u, err := url.Parse(reqUrl)
if err != nil {
return err
}
req.URL = u
}
return nil
}
func (client *HttpClient) setFormData(req *http.Request, values url.Values) {
formData := []byte(values.Encode())
req.Body = io.NopCloser(bytes.NewReader(formData))
req.ContentLength = int64(len(formData))
}
// validateRequest check if a request has url, and valid method.
func validateRequest(req *HttpRequest) error {
if req.RawURL == "" {
return errors.New("invalid request url")
}
// common HTTP methods
methods := []string{"GET", "POST", "PUT", "DELETE", "PATCH",
"HEAD", "CONNECT", "OPTIONS", "TRACE"}
if !slice.Contain(methods, strings.ToUpper(req.Method)) {
return errors.New("invalid request method")
}
return nil
}
// StructToUrlValues convert struct to url valuse,
// only convert the field which is exported and has `json` tag.
// Play: https://go.dev/play/p/pFqMkM40w9z
func StructToUrlValues(targetStruct any) url.Values {
rv := reflect.ValueOf(targetStruct)
rt := reflect.TypeOf(targetStruct)
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
}
if rt.Kind() != reflect.Struct {
panic(fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", targetStruct))
}
result := url.Values{}
fieldNum := rt.NumField()
pattern := `^[A-Z]`
regex := regexp.MustCompile(pattern)
for i := 0; i < fieldNum; i++ {
name := rt.Field(i).Name
tag := rt.Field(i).Tag.Get("json")
if regex.MatchString(name) && tag != "" {
result.Add(tag, fmt.Sprintf("%v", rv.Field(i).Interface()))
}
}
return result
}

View File

@@ -1,235 +0,0 @@
package netutil
import (
"bytes"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"reflect"
"regexp"
"strings"
"time"
"github.com/duke-git/lancet/v2/slice"
)
// HttpRequest struct is a composed http request
type HttpRequest struct {
RawURL string
Method string
Headers http.Header
QueryParams url.Values
FormData url.Values
Body []byte
}
// HttpClientConfig contains some configurations for http client
type HttpClientConfig struct {
SSLEnabled bool
TLSConfig *tls.Config
Compressed bool
HandshakeTimeout time.Duration
ResponseTimeout time.Duration
Verbose bool
}
// defaultHttpClientConfig defalut client config
var defaultHttpClientConfig = &HttpClientConfig{
Compressed: false,
HandshakeTimeout: 20 * time.Second,
ResponseTimeout: 40 * time.Second,
}
// HttpClient is used for sending http request
type HttpClient struct {
*http.Client
TLS *tls.Config
Request *http.Request
Config HttpClientConfig
}
// NewHttpClient make a HttpClient instance
func NewHttpClient() *HttpClient {
client := &HttpClient{
Client: &http.Client{
Transport: &http.Transport{
TLSHandshakeTimeout: defaultHttpClientConfig.HandshakeTimeout,
ResponseHeaderTimeout: defaultHttpClientConfig.ResponseTimeout,
DisableCompression: !defaultHttpClientConfig.Compressed,
},
},
Config: *defaultHttpClientConfig,
}
return client
}
// NewHttpClientWithConfig make a HttpClient instance with pass config
func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient {
if config == nil {
config = defaultHttpClientConfig
}
client := &HttpClient{
Client: &http.Client{
Transport: &http.Transport{
TLSHandshakeTimeout: config.HandshakeTimeout,
ResponseHeaderTimeout: config.ResponseTimeout,
DisableCompression: !config.Compressed,
},
},
Config: *config,
}
if config.SSLEnabled {
client.TLS = config.TLSConfig
}
return client
}
// SendRequest send http request.
// Play: https://go.dev/play/p/jUSgynekH7G
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error) {
err := validateRequest(request)
if err != nil {
return nil, err
}
rawUrl := request.RawURL
req, err := http.NewRequest(request.Method, rawUrl, bytes.NewBuffer(request.Body))
if err != nil {
return nil, err
}
client.setTLS(rawUrl)
client.setHeader(req, request.Headers)
err = client.setQueryParam(req, rawUrl, request.QueryParams)
if err != nil {
return nil, err
}
if request.FormData != nil {
client.setFormData(req, request.FormData)
}
client.Request = req
resp, err := client.Client.Do(req)
if err != nil {
return nil, err
}
return resp, nil
}
// DecodeResponse decode response into target object.
// Play: https://go.dev/play/p/jUSgynekH7G
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error {
if resp == nil {
return errors.New("invalid target param")
}
defer resp.Body.Close()
return json.NewDecoder(resp.Body).Decode(target)
}
// setTLS set http client transport TLSClientConfig
func (client *HttpClient) setTLS(rawUrl string) {
if strings.HasPrefix(rawUrl, "https") {
if transport, ok := client.Client.Transport.(*http.Transport); ok {
transport.TLSClientConfig = client.TLS
}
}
}
// setHeader set http rquest header
func (client *HttpClient) setHeader(req *http.Request, headers http.Header) {
if headers == nil {
headers = make(http.Header)
}
if _, ok := headers["Accept"]; !ok {
headers["Accept"] = []string{"*/*"}
}
if _, ok := headers["Accept-Encoding"]; !ok && client.Config.Compressed {
headers["Accept-Encoding"] = []string{"deflate, gzip"}
}
req.Header = headers
}
// setQueryParam set http request query string param
func (client *HttpClient) setQueryParam(req *http.Request, reqUrl string, queryParam url.Values) error {
if queryParam != nil {
if !strings.Contains(reqUrl, "?") {
reqUrl = reqUrl + "?" + queryParam.Encode()
} else {
reqUrl = reqUrl + "&" + queryParam.Encode()
}
u, err := url.Parse(reqUrl)
if err != nil {
return err
}
req.URL = u
}
return nil
}
func (client *HttpClient) setFormData(req *http.Request, values url.Values) {
formData := []byte(values.Encode())
req.Body = io.NopCloser(bytes.NewReader(formData))
req.ContentLength = int64(len(formData))
}
// validateRequest check if a request has url, and valid method.
func validateRequest(req *HttpRequest) error {
if req.RawURL == "" {
return errors.New("invalid request url")
}
// common HTTP methods
methods := []string{"GET", "POST", "PUT", "DELETE", "PATCH",
"HEAD", "CONNECT", "OPTIONS", "TRACE"}
if !slice.Contain(methods, strings.ToUpper(req.Method)) {
return errors.New("invalid request method")
}
return nil
}
// StructToUrlValues convert struct to url valuse,
// only convert the field which is exported and has `json` tag.
// Play: https://go.dev/play/p/pFqMkM40w9z
func StructToUrlValues(targetStruct any) url.Values {
rv := reflect.ValueOf(targetStruct)
rt := reflect.TypeOf(targetStruct)
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
}
if rt.Kind() != reflect.Struct {
panic(fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", targetStruct))
}
result := url.Values{}
fieldNum := rt.NumField()
pattern := `^[A-Z]`
regex := regexp.MustCompile(pattern)
for i := 0; i < fieldNum; i++ {
name := rt.Field(i).Name
tag := rt.Field(i).Tag.Get("json")
if regex.MatchString(name) && tag != "" {
result.Add(tag, fmt.Sprintf("%v", rv.Field(i).Interface()))
}
}
return result
}

View File

@@ -1,98 +0,0 @@
package netutil
import (
"io"
"log"
"net/http"
"net/url"
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestHttpClient_Get(t *testing.T) {
assert := internal.NewAssert(t, "TestHttpClient_Get")
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
Method: "GET",
}
httpClient := NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil || resp.StatusCode != 200 {
log.Fatal(err)
}
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 {
t.Log(err)
}
assert.Equal(1, todo.Id)
}
func TestHttpClent_Post(t *testing.T) {
header := http.Header{}
header.Add("Content-Type", "multipart/form-data")
postData := url.Values{}
postData.Add("userId", "1")
postData.Add("title", "testItem")
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos",
Method: "POST",
Headers: header,
FormData: postData,
}
httpClient := NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil {
log.Fatal(err)
}
body, _ := io.ReadAll(resp.Body)
t.Log("response: ", resp.StatusCode, string(body))
}
func TestStructToUrlValues(t *testing.T) {
assert := internal.NewAssert(t, "TestStructToUrlValues")
type TodoQuery struct {
Id int `json:"id"`
UserId int `json:"userId"`
}
todoQuery := TodoQuery{
Id: 1,
UserId: 1,
}
todoValues := StructToUrlValues(todoQuery)
assert.Equal("1", todoValues.Get("id"))
assert.Equal("1", todoValues.Get("userId"))
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos",
Method: "GET",
QueryParams: todoValues,
}
httpClient := NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil || resp.StatusCode != 200 {
log.Fatal(err)
}
body, _ := io.ReadAll(resp.Body)
t.Log("response: ", string(body))
}

View File

@@ -1,99 +0,0 @@
package netutil
import "fmt"
func ExampleHttpClient_SendRequest() {
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
Method: "GET",
}
httpClient := 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
}
func ExampleHttpClient_DecodeResponse() {
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
Method: "GET",
}
httpClient := 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
}
func ExampleStructToUrlValues() {
type TodoQuery struct {
Id int `json:"id"`
Name string `json:"name"`
}
todoQuery := TodoQuery{
Id: 1,
Name: "Test",
}
todoValues := StructToUrlValues(todoQuery)
fmt.Println(todoValues.Get("id"))
fmt.Println(todoValues.Get("name"))
// Output:
// 1
// Test
}
func ExampleConvertMapToQueryString() {
var m = map[string]any{
"c": 3,
"a": 1,
"b": 2,
}
qs := ConvertMapToQueryString(m)
fmt.Println(qs)
// Output:
// a=1&b=2&c=3
}

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"io"
"log"
"net/http"
"net/url"
"testing"
@@ -156,3 +157,90 @@ func TestParseResponse(t *testing.T) {
}
t.Log("response: ", toDoResp)
}
func TestHttpClient_Get(t *testing.T) {
assert := internal.NewAssert(t, "TestHttpClient_Get")
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
Method: "GET",
}
httpClient := NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil || resp.StatusCode != 200 {
log.Fatal(err)
}
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 {
t.Log(err)
}
assert.Equal(1, todo.Id)
}
func TestHttpClent_Post(t *testing.T) {
header := http.Header{}
header.Add("Content-Type", "multipart/form-data")
postData := url.Values{}
postData.Add("userId", "1")
postData.Add("title", "testItem")
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos",
Method: "POST",
Headers: header,
FormData: postData,
}
httpClient := NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil {
log.Fatal(err)
}
body, _ := io.ReadAll(resp.Body)
t.Log("response: ", resp.StatusCode, string(body))
}
func TestStructToUrlValues(t *testing.T) {
assert := internal.NewAssert(t, "TestStructToUrlValues")
type TodoQuery struct {
Id int `json:"id"`
UserId int `json:"userId"`
}
todoQuery := TodoQuery{
Id: 1,
UserId: 1,
}
todoValues := StructToUrlValues(todoQuery)
assert.Equal("1", todoValues.Get("id"))
assert.Equal("1", todoValues.Get("userId"))
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos",
Method: "GET",
QueryParams: todoValues,
}
httpClient := NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil || resp.StatusCode != 200 {
log.Fatal(err)
}
body, _ := io.ReadAll(resp.Body)
t.Log("response: ", string(body))
}

View File

@@ -89,3 +89,68 @@ func ExampleEncodeUrl() {
// Output:
// http://www.lancet.com?a=1&b=%5B2%5D
}
func ExampleHttpClient_DecodeResponse() {
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
Method: "GET",
}
httpClient := 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
}
func ExampleStructToUrlValues() {
type TodoQuery struct {
Id int `json:"id"`
Name string `json:"name"`
}
todoQuery := TodoQuery{
Id: 1,
Name: "Test",
}
todoValues := StructToUrlValues(todoQuery)
fmt.Println(todoValues.Get("id"))
fmt.Println(todoValues.Get("name"))
// Output:
// 1
// Test
}
func ExampleConvertMapToQueryString() {
var m = map[string]any{
"c": 3,
"a": 1,
"b": 2,
}
qs := ConvertMapToQueryString(m)
fmt.Println(qs)
// Output:
// a=1&b=2&c=3
}

View File

@@ -6,7 +6,6 @@ import (
)
func ExampleRandInt() {
result := RandInt(1, 10)
if result >= 1 && result < 10 {

261
stream/stream.go Normal file
View File

@@ -0,0 +1,261 @@
// Copyright 2023 dudaodong@gmail.com. All rights resulterved.
// Use of this source code is governed by MIT license
// Package stream implements a sequence of elements supporting sequential and parallel aggregate operations.
// this package is an experiment to explore if stream in go can work as the way java does. it's complete, but not
// powerful like other libs
package stream
import (
"bytes"
"encoding/gob"
"golang.org/x/exp/constraints"
)
// A stream should implements methods:
// type StreamI[T any] interface {
// // part methods of Java Stream Specification.
// Distinct() StreamI[T]
// Filter(predicate func(item T) bool) StreamI[T]
// FlatMap(mapper func(item T) StreamI[T]) StreamI[T]
// Map(mapper func(item T) T) StreamI[T]
// Peek(consumer func(item T)) StreamI[T]
// Sort(less func(a, b T) bool) StreamI[T]
// Max(less func(a, b T) bool) (T, bool)
// Min(less func(a, b T) bool) (T, bool)
// Limit(maxSize int) StreamI[T]
// Skip(n int) StreamI[T]
// AllMatch(predicate func(item T) bool) bool
// AnyMatch(predicate func(item T) bool) bool
// NoneMatch(predicate func(item T) bool) bool
// ForEach(consumer func(item T))
// Reduce(init T, accumulator func(a, b T) T) T
// Count() int
// FindFirst() (T, bool)
// ToSlice() []T
// // part of methods custom extension
// Reverse() StreamI[T]
// Range(start, end int64) StreamI[T]
// Concat(streams ...StreamI[T]) StreamI[T]
// }
type stream[T any] struct {
source []T
}
// Of creates a stream stream whose elements are the specified values.
func Of[T any](elems ...T) stream[T] {
return FromSlice(elems)
}
// Generate stream where each element is generated by the provided generater function
// generater function: func() func() (item T, ok bool) {}
func Generate[T any](generator func() func() (item T, ok bool)) stream[T] {
source := make([]T, 0)
var zeroValue T
for next, item, ok := generator(), zeroValue, true; ok; {
item, ok = next()
if ok {
source = append(source, item)
}
}
return FromSlice(source)
}
// FromSlice create stream from slice.
func FromSlice[T any](source []T) stream[T] {
return stream[T]{source: source}
}
// FromChannel create stream from channel.
func FromChannel[T any](source <-chan T) stream[T] {
s := make([]T, 0)
for v := range source {
s = append(s, v)
}
return FromSlice(s)
}
// FromRange create a number stream from start to end. both start and end are included. [start, end]
func FromRange[T constraints.Integer | constraints.Float](start, end, step T) stream[T] {
if end < start {
panic("stream.FromRange: param start should be before param end")
} else if step <= 0 {
panic("stream.FromRange: param step should be positive")
}
l := int((end-start)/step) + 1
source := make([]T, l, l)
for i := 0; i < l; i++ {
source[i] = start + (T(i) * step)
}
return FromSlice(source)
}
// Distinct returns a stream that removes the duplicated items.
func (s stream[T]) Distinct() stream[T] {
source := make([]T, 0)
distinct := map[string]bool{}
for _, v := range s.source {
// todo: performance issue
k := hashKey(v)
if _, ok := distinct[k]; !ok {
distinct[k] = true
source = append(source, v)
}
}
return FromSlice(source)
}
func hashKey(data any) string {
buffer := bytes.NewBuffer(nil)
encoder := gob.NewEncoder(buffer)
err := encoder.Encode(data)
if err != nil {
panic("stream.hashKey: get hashkey failed")
}
return buffer.String()
}
// Filter returns a stream consisting of the elements of this stream that match the given predicate.
func (s stream[T]) Filter(predicate func(item T) bool) stream[T] {
source := make([]T, 0)
for _, v := range s.source {
if predicate(v) {
source = append(source, v)
}
}
return FromSlice(source)
}
// Map returns a stream consisting of the elements of this stream that apply the given function to elements of stream.
func (s stream[T]) Map(mapper func(item T) T) stream[T] {
source := make([]T, s.Count(), s.Count())
for i, v := range s.source {
source[i] = mapper(v)
}
return FromSlice(source)
}
// 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.
func (s stream[T]) Peek(consumer func(item T)) stream[T] {
for _, v := range s.source {
consumer(v)
}
return s
}
// 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.
func (s stream[T]) Skip(n int) stream[T] {
if n <= 0 {
return s
}
source := make([]T, 0)
l := len(s.source)
if n > l {
return FromSlice(source)
}
for i := n; i < l; i++ {
source = append(source, s.source[i])
}
return FromSlice(source)
}
// Limit returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.
func (s stream[T]) Limit(maxSize int) stream[T] {
if s.source == nil {
return s
}
if maxSize < 0 {
return FromSlice([]T{})
}
source := make([]T, 0, maxSize)
for i := 0; i < len(s.source) && i < maxSize; i++ {
source = append(source, s.source[i])
}
return FromSlice(source)
}
// AllMatch returns whether all elements of this stream match the provided predicate.
func (s stream[T]) AllMatch(predicate func(item T) bool) bool {
for _, v := range s.source {
if !predicate(v) {
return false
}
}
return true
}
// AnyMatch returns whether any elements of this stream match the provided predicate.
func (s stream[T]) AnyMatch(predicate func(item T) bool) bool {
for _, v := range s.source {
if predicate(v) {
return true
}
}
return false
}
// NoneMatch returns whether no elements of this stream match the provided predicate.
func (s stream[T]) NoneMatch(predicate func(item T) bool) bool {
return !s.AnyMatch(predicate)
}
// ForEach performs an action for each element of this stream.
func (s stream[T]) ForEach(action func(item T)) {
for _, v := range s.source {
action(v)
}
}
// 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.
func (s stream[T]) Reduce(init T, accumulator func(a, b T) T) T {
for _, v := range s.source {
init = accumulator(init, v)
}
return init
}
// Count returns the count of elements in the stream.
func (s stream[T]) Count() int {
return len(s.source)
}
// ToSlice return the elements in the stream.
func (s stream[T]) ToSlice() []T {
return s.source
}

249
stream/stream_test.go Normal file
View File

@@ -0,0 +1,249 @@
package stream
import (
"fmt"
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestOf(t *testing.T) {
assert := internal.NewAssert(t, "TestFromSlice")
stream := Of(1, 2, 3)
assert.Equal([]int{1, 2, 3}, stream.ToSlice())
}
func TestGenerate(t *testing.T) {
assert := internal.NewAssert(t, "TestFromSlice")
n := 0
max := 4
generator := func() func() (int, bool) {
return func() (int, bool) {
n++
return n, n < max
}
}
stream := Generate(generator)
assert.Equal([]int{1, 2, 3}, stream.ToSlice())
}
func TestFromSlice(t *testing.T) {
assert := internal.NewAssert(t, "TestFromSlice")
stream := FromSlice([]int{1, 2, 3})
assert.Equal([]int{1, 2, 3}, stream.ToSlice())
}
func TestFromChannel(t *testing.T) {
assert := internal.NewAssert(t, "TestFromChannel")
ch := make(chan int)
go func() {
for i := 1; i < 4; i++ {
ch <- i
}
close(ch)
}()
stream := FromChannel(ch)
assert.Equal([]int{1, 2, 3}, stream.ToSlice())
}
func TestFromRange(t *testing.T) {
assert := internal.NewAssert(t, "TestFromRange")
s1 := FromRange(1, 5, 1)
s2 := FromRange(1.1, 5.0, 1.0)
assert.Equal([]int{1, 2, 3, 4, 5}, s1.ToSlice())
assert.Equal([]float64{1.1, 2.1, 3.1, 4.1}, s2.ToSlice())
}
func TestStream_Distinct(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_Distinct")
nums := FromSlice([]int{1, 2, 2, 3, 3, 3})
distinctNums := nums.Distinct()
assert.Equal([]int{1, 2, 2, 3, 3, 3}, nums.ToSlice())
assert.Equal([]int{1, 2, 3}, distinctNums.ToSlice())
type Person struct {
Id string
Name string
Age uint
}
people := []Person{
{Id: "001", Name: "Tom", Age: 10},
{Id: "001", Name: "Tom", Age: 10},
{Id: "002", Name: "Jim", Age: 20},
{Id: "003", Name: "Mike", Age: 30},
}
stream := FromSlice(people)
distinctStream := stream.Distinct()
// {[{001 Tom 10} {001 Tom 10} {002 Jim 20} {003 Mike 30}]}
t.Log(stream)
// {[{001 Tom 10} {002 Jim 20} {003 Mike 30}]}
t.Log(distinctStream)
}
func TestStream_Filter(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_Filter")
stream := FromSlice([]int{1, 2, 3, 4, 5})
isEven := func(n int) bool {
return n%2 == 0
}
even := stream.Filter(isEven)
assert.Equal([]int{2, 4}, even.ToSlice())
}
func TestStream_Map(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_Map")
stream := FromSlice([]int{1, 2, 3})
addOne := func(n int) int {
return n + 1
}
s := stream.Map(addOne)
assert.Equal([]int{2, 3, 4}, s.ToSlice())
}
func TestStream_Peek(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_Peek")
stream := FromSlice([]int{1, 2, 3, 4, 5, 6})
result := []string{}
stream = stream.Filter(func(n int) bool {
return n <= 3
}).Peek(func(n int) {
result = append(result, fmt.Sprint("current: ", n))
})
assert.Equal([]int{1, 2, 3}, stream.ToSlice())
assert.Equal([]string{
"current: 1", "current: 2", "current: 3",
}, result)
}
func TestStream_Skip(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_Peek")
stream := FromSlice([]int{1, 2, 3, 4, 5, 6})
s1 := stream.Skip(-1)
s2 := stream.Skip(0)
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s1.ToSlice())
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s2.ToSlice())
}
func TestStream_Limit(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_Limit")
stream := FromSlice([]int{1, 2, 3, 4, 5, 6})
s1 := stream.Limit(-1)
s2 := stream.Limit(0)
s3 := stream.Limit(1)
s4 := stream.Limit(6)
assert.Equal([]int{}, s1.ToSlice())
assert.Equal([]int{}, s2.ToSlice())
assert.Equal([]int{1}, s3.ToSlice())
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s4.ToSlice())
}
func TestStream_AllMatch(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_AllMatch")
stream := FromSlice([]int{1, 2, 3, 4, 5, 6})
result1 := stream.AllMatch(func(item int) bool {
return item > 0
})
result2 := stream.AllMatch(func(item int) bool {
return item > 1
})
assert.Equal(true, result1)
assert.Equal(false, result2)
}
func TestStream_AnyMatch(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_AnyMatch")
stream := FromSlice([]int{1, 2, 3})
result1 := stream.AnyMatch(func(item int) bool {
return item > 3
})
result2 := stream.AnyMatch(func(item int) bool {
return item > 1
})
assert.Equal(false, result1)
assert.Equal(true, result2)
}
func TestStream_NoneMatch(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_NoneMatch")
stream := FromSlice([]int{1, 2, 3})
result1 := stream.NoneMatch(func(item int) bool {
return item > 3
})
result2 := stream.NoneMatch(func(item int) bool {
return item > 1
})
assert.Equal(true, result1)
assert.Equal(false, result2)
}
func TestStream_ForEach(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_ForEach")
stream := FromSlice([]int{1, 2, 3})
result := 0
stream.ForEach(func(item int) {
result += item
})
assert.Equal(6, result)
}
func TestStream_Reduce(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_Reduce")
stream := FromSlice([]int{1, 2, 3})
result := stream.Reduce(0, func(a, b int) int {
return a + b
})
assert.Equal(6, result)
}

View File

@@ -283,7 +283,7 @@ func SplitEx(s, sep string, removeEmptyString bool) []string {
}
// Substring returns a substring of the specified length starting at the specified offset position.
// Play: Todo
// Play: https://go.dev/play/p/q3sM6ehnPDp
func Substring(s string, offset int, length uint) string {
rs := []rune(s)
size := len(rs)

View File

@@ -3,10 +3,10 @@ package system
import "fmt"
func ExampleSetOsEnv() {
ok := SetOsEnv("foo", "abc")
err := SetOsEnv("foo", "abc")
result := GetOsEnv("foo")
fmt.Println(ok)
fmt.Println(err)
fmt.Println(result)
// Output:
// <nil>
@@ -25,14 +25,14 @@ func ExampleGetOsEnv() {
}
func ExampleRemoveOsEnv() {
ok1 := SetOsEnv("foo", "abc")
err1 := SetOsEnv("foo", "abc")
result1 := GetOsEnv("foo")
ok2 := RemoveOsEnv("foo")
err2 := RemoveOsEnv("foo")
result2 := GetOsEnv("foo")
fmt.Println(ok1)
fmt.Println(ok2)
fmt.Println(err1)
fmt.Println(err2)
fmt.Println(result1)
fmt.Println(result2)
@@ -49,9 +49,10 @@ func ExampleCompareOsEnv() {
return
}
result1 := CompareOsEnv("foo", "abc")
result := CompareOsEnv("foo", "abc")
fmt.Println(result)
fmt.Println(result1)
// Output:
// true
}

View File

@@ -25,7 +25,7 @@ var (
chineseMobileMatcher *regexp.Regexp = regexp.MustCompile(`^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$`)
chineseIdMatcher *regexp.Regexp = regexp.MustCompile(`^[1-9]\d{5}(18|19|20|21|22)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$`)
chineseMatcher *regexp.Regexp = regexp.MustCompile("[\u4e00-\u9fa5]")
chinesePhoneMatcher *regexp.Regexp = regexp.MustCompile(`\d{3}-\d{8}|\d{4}-\d{7}`)
chinesePhoneMatcher *regexp.Regexp = regexp.MustCompile(`\d{3}-\d{8}|\d{4}-\d{7}|\d{4}-\d{8}`)
creditCardMatcher *regexp.Regexp = regexp.MustCompile(`^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$`)
base64Matcher *regexp.Regexp = regexp.MustCompile(`^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$`)
)

View File

@@ -208,6 +208,7 @@ func TestIsChinesePhone(t *testing.T) {
assert.Equal(true, IsChinesePhone("010-32116675"))
assert.Equal(true, IsChinesePhone("0464-8756213"))
assert.Equal(true, IsChinesePhone("0731-82251545")) //长沙晚报电话
assert.Equal(false, IsChinesePhone("123-87562"))
}