1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-08 14:42:27 +08:00

Compare commits

..

28 Commits

Author SHA1 Message Date
dudaodong
be67de3b40 release v1.3.0 2022-06-22 15:58:41 +08:00
dudaodong
6898ed413e docs: add doc for UniqueBy function 2022-06-22 15:47:48 +08:00
dudaodong
5dbdbcd651 docs: add doc for UniqueBy function 2022-06-22 15:45:29 +08:00
dudaodong
ae0facd32d refactor: clean code for slice/slice.go 2022-06-22 14:21:45 +08:00
dudaodong
2d7e19fb87 feat: add UniqueBy function in slice.go 2022-06-22 12:00:01 +08:00
dudaodong
24d4a03227 update .gitignore file 2022-06-22 11:27:31 +08:00
dudaodong
93fb089f6e docs: add CreateDir function for fileutil 2022-06-17 17:25:16 +08:00
dudaodong
2fe272f2ef docs: add CreateDir function for fileutil 2022-06-17 17:22:08 +08:00
dudaodong
77859ffa15 docs: add doc for SplitEx function 2022-06-17 17:19:59 +08:00
dudaodong
f83f47df3a feat: add SplitEx function 2022-06-17 17:13:58 +08:00
dudaodong
885c08847d docs: add doc for function IndexOf and LastIndexOf 2022-06-17 17:11:09 +08:00
dudaodong
cc4a20751f test: add unit test for funcation IndexOf and LastIndexOf 2022-06-17 17:02:44 +08:00
dudaodong
b0d1d39452 feat: add IndexOf and LastIndexOf function in slice.go 2022-06-17 17:01:37 +08:00
dudaodong
02fa7bc8be docs: add doc for function Equal and EqualWithFunc 2022-06-17 16:57:42 +08:00
dudaodong
433eb63b86 feat: add EqualWith function for slice 2022-06-17 15:47:36 +08:00
dudaodong
a2541dac03 feat: add Equal function for slice 2022-06-17 15:37:36 +08:00
dudaodong
690e746811 update readme file 2022-04-29 14:50:29 +08:00
dudaodong
7cb97a26c5 release v1.2.9 2022-04-14 11:41:46 +08:00
dudaodong
39d373d37b fix: fix http post to support multipart/form-data header 2022-04-14 11:39:21 +08:00
dudaodong
1aefd6aa12 release v1.2.8 2022-04-13 11:46:14 +08:00
dudaodong
c7aa44b8a4 fix: fix http post fucntion 2022-04-13 11:38:45 +08:00
dudaodong
0e3dc68de5 release v1.2.7 2022-03-29 10:52:55 +08:00
dudaodong
4083e75ed4 fix: fix ToBytes bug 2022-03-26 21:09:28 +08:00
dudaodong
1327eff62f docs: add doc for unix time 2022-03-24 16:09:19 +08:00
dudaodong
eb24c37143 docs: add doc for unix time 2022-03-24 16:07:17 +08:00
dudaodong
b7a6c91064 feat: add unix date conversion 2022-03-24 16:03:57 +08:00
dudaodong
555e185871 feat: add unix date conversion 2022-03-24 16:01:41 +08:00
dudaodong
cb0efc5cc7 docs: replace path '/main' with '/v1' 2022-03-16 16:18:28 +08:00
106 changed files with 2133 additions and 7772 deletions

View File

@@ -17,7 +17,7 @@ jobs:
fetch-depth: 2 fetch-depth: 2
- uses: actions/setup-go@v2 - uses: actions/setup-go@v2
with: with:
go-version: "1.18" go-version: "1.16"
- name: Run coverage - name: Run coverage
run: go test -v ./... -coverprofile=coverage.txt -covermode=atomic run: go test -v ./... -coverprofile=coverage.txt -covermode=atomic
- name: Upload coverage to Codecov - name: Upload coverage to Codecov

1
.gitignore vendored
View File

@@ -6,4 +6,5 @@ fileutil/*.txt
fileutil/*.zip fileutil/*.zip
fileutil/*.link fileutil/*.link
fileutil/unzip/* fileutil/unzip/*
slice/testdata/*
cryptor/*.pem cryptor/*.pem

146
README.md
View File

@@ -4,12 +4,13 @@
<br/> <br/>
![Go version](https://img.shields.io/badge/go-%3E%3D1.16<recommend>-9cf) ![Go version](https://img.shields.io/badge/go-%3E%3D1.16<recommend>-9cf)
[![Release](https://img.shields.io/badge/release-2.0.3-green.svg)](https://github.com/duke-git/lancet/releases) [![Release](https://img.shields.io/badge/release-1.2.9-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) [![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet/v2)](https://goreportcard.com/report/github.com/duke-git/lancet/v2) [![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/github.com/duke-git/lancet)
[![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) [![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)
[![codecov](https://codecov.io/gh/duke-git/lancet/branch/main/graph/badge.svg?token=FC48T1F078)](https://codecov.io/gh/duke-git/lancet) [![codecov](https://codecov.io/gh/duke-git/lancet/branch/main/graph/badge.svg?token=FC48T1F078)](https://codecov.io/gh/duke-git/lancet)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/duke-git/lancet/blob/main/LICENSE) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/duke-git/lancet/blob/main/LICENSE)
</div> </div>
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -23,21 +24,14 @@ English | [简体中文](./README_zh-CN.md)
## Feature ## Feature
- 👏 Comprehensive, efficient and reusable. - 👏 Comprehensive, efficient and reusable.
- 💪 250+ go util functions, support string, slice, datetime, net, crypt... - 💪 200+ go util functions, support string, slice, datetime, net, crypt...
- 💅 Only depend on the go standard library. - 💅 Only depend on the go standard library.
- 🌍 Unit test for every exported function. - 🌍 Unit test for every exported function.
## Installation ## Installation
### Note:
1. <b>For users who use go1.18 and above, it is recommended to install lancet v2.x.x. Cause v2.x.x rewrite all functions with generics of go1.18.</b>
```go ```go
go get github.com/duke-git/lancet/v2 // will install latest version of v2.x.x go get github.com/duke-git/lancet
```
2. <b>For users who use version below go1.18, you should install v1.x.x. now latest v1 is v1.2.7. </b>
```go
go get github.com/duke-git/lancet@v1.2.7 // below go1.18, install latest version of v1.x.x
``` ```
## Usage ## Usage
@@ -45,7 +39,7 @@ go get github.com/duke-git/lancet@v1.2.7 // below go1.18, install latest version
Lancet organizes the code into package structure, and you need to import the corresponding package name when use it. For example, if you use string-related functions,import the strutil package like below: Lancet organizes the code into package structure, and you need to import the corresponding package name when use it. For example, if you use string-related functions,import the strutil package like below:
```go ```go
import "github.com/duke-git/lancet/v2/strutil" import "github.com/duke-git/lancet/strutil"
``` ```
## Example ## Example
@@ -57,7 +51,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -68,31 +62,10 @@ func main() {
``` ```
## API Documentation ## API Documentation
### 1. Convertor package contains some functions for data convertion.
### Algorithm package implements some basic algorithm. eg. sort, search.
```go ```go
import "github.com/duke-git/lancet/v2/algorithm" import "github.com/duke-git/lancet/convertor"
```
#### Function list:
- [BubbleSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#BubbleSort)
- [CountSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#CountSort)
- [HeapSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#HeapSort)
- [InsertionSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#InsertionSort)
- [MergeSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#MergeSort)
- [QuickSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#QuickSort)
- [SelectionSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#SelectionSort)
- [ShellSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#ShellSort)
- [BinarySearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#BinarySearch)
- [BinaryIterativeSearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#BinaryIterativeSearch)
- [LinearSearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#LinearSearch)
- [LRUCache](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#LRUCache)
### Convertor package contains some functions for data convertion.
```go
import "github.com/duke-git/lancet/v2/convertor"
``` ```
#### Function list: #### Function list:
- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ColorHexToRGB) - [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ColorHexToRGB)
@@ -105,10 +78,10 @@ import "github.com/duke-git/lancet/v2/convertor"
- [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToString) - [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToString)
- [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#StructToMap) - [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#StructToMap)
### Cryptor package is for data encryption and decryption. ### 2. Cryptor package is for data encryption and decryption.
```go ```go
import "github.com/duke-git/lancet/v2/cryptor" import "github.com/duke-git/lancet/cryptor"
``` ```
#### Function list: #### Function list:
@@ -145,11 +118,11 @@ import "github.com/duke-git/lancet/v2/cryptor"
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaEncrypt) - [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaEncrypt)
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaDecrypt) - [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaDecrypt)
### Datetime package supports date and time format and compare. ### 3. Datetime package supports date and time format and compare.
```go ```go
import "github.com/duke-git/lancet/v2/datetime" import "github.com/duke-git/lancet/datetime"
``` ```
#### Function list: #### Function list:
- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddDay) - [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddDay)
@@ -183,16 +156,17 @@ import "github.com/duke-git/lancet/v2/datetime"
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToFormatForTpl) - [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToFormatForTpl)
- [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToIso8601) - [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToIso8601)
### Fileutil package implements some basic functions for file operations. ### 4. Fileutil package implements some basic functions for file operations.
```go ```go
import "github.com/duke-git/lancet/v2/fileutil" import "github.com/duke-git/lancet/fileutil"
``` ```
#### Function list #### Function list
- [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ClearFile) - [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ClearFile)
- [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CreateFile) - [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CreateFile)
- [CreateDir](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CreateDir)
- [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CopyFile) - [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CopyFile)
- [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#FileMode) - [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#FileMode)
- [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#MiMeType) - [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#MiMeType)
@@ -206,10 +180,10 @@ import "github.com/duke-git/lancet/v2/fileutil"
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#Zip) - [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#Zip)
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#UnZip) - [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#UnZip)
### Formatter contains some functions for data formatting. ### 5. Formatter contains some functions for data formatting.
```go ```go
import "github.com/duke-git/lancet/v2/formatter" import "github.com/duke-git/lancet/formatter"
``` ```
#### Function list: #### Function list:
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#Comma) - [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#Comma)
@@ -217,7 +191,7 @@ import "github.com/duke-git/lancet/v2/formatter"
### Function package can control the flow of function execution and support part of functional programming ### Function package can control the flow of function execution and support part of functional programming
```go ```go
import "github.com/duke-git/lancet/v2/function" import "github.com/duke-git/lancet/function"
``` ```
#### Function list: #### Function list:
@@ -230,45 +204,26 @@ import "github.com/duke-git/lancet/v2/function"
- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function.md#Watcher) - [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function.md#Watcher)
### Maputil package includes some functions to manipulate map. ### 6. Mathutil package implements some functions for math calculation.
```go ```go
import "github.com/duke-git/lancet/v2/maputil" import "github.com/duke-git/lancet/mathutil"
``` ```
#### Function list: #### Function list:
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#ForEach)
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Filter)
- [Intersect](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Intersect)
- [Keys](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Keys)
- [Merge](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Merge)
- [Minus](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Minus)
- [Values](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Values)
### Mathutil package implements some functions for math calculation.
```go
import "github.com/duke-git/lancet/v2/mathutil"
```
#### Function list:
- [Average](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Average)
- [Exponent](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Exponent) - [Exponent](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Exponent)
- [Fibonacci](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Fibonacci) - [Fibonacci](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Fibonacci)
- [Factorial](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Factorial) - [Factorial](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Factorial)
- [Max](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Max)
- [Min](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Min)
- [Percent](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Percent) - [Percent](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Percent)
- [RoundToFloat](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RoundToFloat) - [RoundToFloat](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RoundToFloat)
- [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RoundToString) - [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RoundToString)
- [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#TruncRound) - [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#TruncRound)
### Netutil package contains functions to get net information and send http request. ### 7. Netutil package contains functions to get net information and send http request.
```go ```go
import "github.com/duke-git/lancet/v2/netutil" import "github.com/duke-git/lancet/netutil"
``` ```
#### Function list: #### Function list:
@@ -285,10 +240,10 @@ import "github.com/duke-git/lancet/v2/netutil"
- [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPatch) - [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPatch)
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ParseHttpResponse) - [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ParseHttpResponse)
### Random package implements some basic functions to generate random int and string. ### 8. Random package implements some basic functions to generate random int and string.
```go ```go
import "github.com/duke-git/lancet/v2/random" import "github.com/duke-git/lancet/random"
``` ```
#### Function list: #### Function list:
@@ -297,10 +252,10 @@ import "github.com/duke-git/lancet/v2/random"
- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandString) - [RandString](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandString)
- [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4) - [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4)
### Retry package is for executing a function repeatedly until it was successful or canceled by the context. ### 9. Retry package is for executing a function repeatedly until it was successful or canceled by the context.
```go ```go
import "github.com/duke-git/lancet/v2/retry" import "github.com/duke-git/lancet/retry"
``` ```
#### Function list: #### Function list:
@@ -310,10 +265,10 @@ import "github.com/duke-git/lancet/v2/retry"
- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryDuration) - [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryDuration)
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryTimes) - [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryTimes)
### Slice contains some functions to manipulate slice. ### 10. Slice contains some functions to manipulate slice.
```go ```go
import "github.com/duke-git/lancet/v2/slice" import "github.com/duke-git/lancet/slice"
``` ```
#### Function list: #### Function list:
@@ -325,37 +280,40 @@ import "github.com/duke-git/lancet/v2/slice"
- [Count](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Count) - [Count](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Count)
- [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Difference) - [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Difference)
- [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceBy) - [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceBy)
- [DifferenceWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceWith) - [DeleteByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DeleteByIndex)
- [DeleteAt](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DeleteAt)
- [Drop](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Drop) - [Drop](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Drop)
- [Every](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Every) - [Every](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Every)
- [Equal](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Equal)
- [EqualWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#EqualWith)
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Filter) - [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Filter)
- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Find) - [Find](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Find)
- [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice.md#FindLast) - [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice.md#FindLast)
- [FlattenDeep](#FlattenDeep) - [FlattenDeep](https://github.com/duke-git/lancet/blob/main/docs/slice.md#FlattenDeep)
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ForEach) - [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ForEach)
- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupBy) - [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupBy)
- [GroupWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupWith)
- [IntSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IntSlice) - [IntSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IntSlice)
- [IndexOf](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IndexOf)
- [LastIndexOf](https://github.com/duke-git/lancet/blob/main/docs/slice.md#LastIndexOf)
- [InterfaceSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InterfaceSlice) - [InterfaceSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InterfaceSlice)
- [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Intersection) - [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Intersection)
- [InsertAt](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InsertAt) - [InsertByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InsertByIndex)
- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Map) - [Map](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Map)
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reverse) - [ReverseSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ReverseSlice)
- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reduce) - [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reduce)
- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Shuffle) - [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Shuffle)
- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SortByField) - [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SortByField)
- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Some) - [Some](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Some)
- [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#StringSlice) - [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#StringSlice)
- [SymmetricDifference](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SymmetricDifference)
- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Unique) - [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Unique)
- [UniqueBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UniqueBy)
- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Union) - [Union](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Union)
- [UpdateAt](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UpdateAt) - [UpdateByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UpdateByIndex)
- [Without](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Without) - [Without](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Without)
### Strutil package contains some functions to manipulate string. ### 11. Strutil package contains some functions to manipulate string.
```go ```go
import "github.com/duke-git/lancet/v2/strutil" import "github.com/duke-git/lancet/strutil"
``` ```
#### Function list: #### Function list:
@@ -374,14 +332,16 @@ import "github.com/duke-git/lancet/v2/strutil"
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadStart) - [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadStart)
- [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#ReverseStr) - [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#ReverseStr)
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SnakeCase) - [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SnakeCase)
- [SplitEx](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SplitEx)
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Wrap) - [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Wrap)
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Unwrap) - [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Unwrap)
### System package contain some functions about os, runtime, shell command. ### 12. System package contain some functions about os, runtime, shell command.
```go ```go
import "github.com/duke-git/lancet/v2/system" import "github.com/duke-git/lancet/system"
``` ```
#### Function list: #### Function list:
- [IsWindows](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsWindows) - [IsWindows](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsWindows)
- [IsLinux](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsLinux) - [IsLinux](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsLinux)
@@ -392,12 +352,11 @@ import "github.com/duke-git/lancet/v2/system"
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#CompareOsEnv) - [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#CompareOsEnv)
- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system.md#ExecCommand) - [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system.md#ExecCommand)
### Validator package contains some functions for data validation. ### 13. Validator package contains some functions for data validation.
```go ```go
import "github.com/duke-git/lancet/v2/validator" import "github.com/duke-git/lancet/validator"
``` ```
#### Function list: #### Function list:
- [ContainChinese](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainChinese) - [ContainChinese](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainChinese)
@@ -426,13 +385,6 @@ import "github.com/duke-git/lancet/v2/validator"
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsStrongPassword) - [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsStrongPassword)
- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsUrl) - [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsUrl)
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsWeakPassword) - [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsWeakPassword)
### xerror package implements helpers for errors.
```go
import "github.com/duke-git/lancet/v2/xerror"
```
#### Function list:
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#Unwrap)
## How to Contribute ## How to Contribute

View File

@@ -4,12 +4,13 @@
<br/> <br/>
![Go version](https://img.shields.io/badge/go-%3E%3D1.16<recommend>-9cf) ![Go version](https://img.shields.io/badge/go-%3E%3D1.16<recommend>-9cf)
[![Release](https://img.shields.io/badge/release-2.0.3-green.svg)](https://github.com/duke-git/lancet/releases) [![Release](https://img.shields.io/badge/release-1.3.0-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) [![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet/v2)](https://goreportcard.com/report/github.com/duke-git/lancet/v2) [![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/github.com/duke-git/lancet)
[![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) [![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)
[![codecov](https://codecov.io/gh/duke-git/lancet/branch/main/graph/badge.svg?token=FC48T1F078)](https://codecov.io/gh/duke-git/lancet) [![codecov](https://codecov.io/gh/duke-git/lancet/branch/main/graph/badge.svg?token=FC48T1F078)](https://codecov.io/gh/duke-git/lancet)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/duke-git/lancet/blob/main/LICENSE) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/duke-git/lancet/blob/main/LICENSE)
</div> </div>
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -23,21 +24,14 @@
## 特性 ## 特性
- 👏 全面、高效、可复用 - 👏 全面、高效、可复用
- 💪 250+常用go工具函数支持string、slice、datetime、net、crypt... - 💪 200+常用go工具函数支持string、slice、datetime、net、crypt...
- 💅 只依赖go标准库 - 💅 只依赖go标准库
- 🌍 所有导出函数单元测试覆盖率100% - 🌍 所有导出函数单元测试覆盖率100%
## 安装 ## 安装
### Note:
1. <b>对于使用go1.18及以上的用户建议安装v2.x.x。 因为v2.x.x用go1.18的泛型重写了大部分函数。</b>
```go ```go
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x go get github.com/duke-git/lancet
```
2. <b>使用go1.18以下版本的用户必须安装v1.x.x。目前最新的v1版本是v1.2.7。</b>
```go
go get github.com/duke-git/lancet@v1.2.7 // 使用go1.18以下版本, 必须安装v1.x.x版本
``` ```
## 用法 ## 用法
@@ -45,7 +39,7 @@ go get github.com/duke-git/lancet@v1.2.7 // 使用go1.18以下版本, 必须安
lancet是以包的结构组织代码的使用时需要导入相应的包名。例如如果使用字符串相关函数需要导入strutil包: lancet是以包的结构组织代码的使用时需要导入相应的包名。例如如果使用字符串相关函数需要导入strutil包:
```go ```go
import "github.com/duke-git/lancet/v2/strutil" import "github.com/duke-git/lancet/strutil"
``` ```
## 例子 ## 例子
@@ -57,7 +51,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -68,30 +62,10 @@ func main() {
``` ```
## API文档 ## API文档
### 1. convertor转换器包支持一些常见的数据类型转换。
### algorithm算法包实现一些基本算法。eg. sort, search.
```go ```go
import "github.com/duke-git/lancet/v2/algorithm" import "github.com/duke-git/lancet/convertor"
```
#### Function list:
- [BubbleSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#BubbleSort)
- [CountSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#CountSort)
- [HeapSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#HeapSort)
- [InsertionSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#InsertionSort)
- [MergeSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#MergeSort)
- [QuickSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#QuickSort)
- [SelectionSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#SelectionSort)
- [ShellSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#ShellSort)
- [BinarySearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#BinarySearch)
- [BinaryIterativeSearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#BinaryIterativeSearch)
- [LinearSearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#LinearSearch)
- [LRUCache](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#LRUCache)
### convertor转换器包支持一些常见的数据类型转换。
```go
import "github.com/duke-git/lancet/v2/convertor"
``` ```
#### 函数列表: #### 函数列表:
- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ColorHexToRGB) - [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ColorHexToRGB)
@@ -104,10 +78,10 @@ import "github.com/duke-git/lancet/v2/convertor"
- [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToString) - [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToString)
- [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#StructToMap) - [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#StructToMap)
### cryptor加密包支持数据加密和解密获取md5hash值。支持base64, md5, hmac, aes, des, rsa。 ### 2. cryptor加密包支持数据加密和解密获取md5hash值。支持base64, md5, hmac, aes, des, rsa。
```go ```go
import "github.com/duke-git/lancet/v2/cryptor" import "github.com/duke-git/lancet/cryptor"
``` ```
#### 函数列表: #### 函数列表:
@@ -144,11 +118,11 @@ import "github.com/duke-git/lancet/v2/cryptor"
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaEncrypt) - [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaEncrypt)
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaDecrypt) - [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaDecrypt)
### datetime日期时间处理包格式化日期比较日期。 ### 3. datetime日期时间处理包格式化日期比较日期。
```go ```go
import "github.com/duke-git/lancet/v2/datetime" import "github.com/duke-git/lancet/datetime"
``` ```
#### 函数列表: #### 函数列表:
- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddDay) - [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddDay)
@@ -181,17 +155,17 @@ import "github.com/duke-git/lancet/v2/datetime"
- [ToFormat](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormat) - [ToFormat](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormat)
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormatForTpl) - [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormatForTpl)
- [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToIso8601) - [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToIso8601)
### 4. fileutil包支持文件基本操作。
### fileutil包支持文件基本操作。
```go ```go
import "github.com/duke-git/lancet/v2/fileutil" import "github.com/duke-git/lancet/fileutil"
``` ```
#### 函数列表: #### 函数列表:
- [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ClearFile) - [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ClearFile)
- [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CreateFile) - [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CreateFile)
- [CreateDir](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CreateDir)
- [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CopyFile) - [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CopyFile)
- [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#FileMode) - [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#FileMode)
- [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#MiMeType) - [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#MiMeType)
@@ -205,10 +179,10 @@ import "github.com/duke-git/lancet/v2/fileutil"
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#Zip) - [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#Zip)
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#UnZip) - [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#UnZip)
### formatter格式化器包含一些数据格式化处理方法。 ### 5. formatter格式化器包含一些数据格式化处理方法。
```go ```go
import "github.com/duke-git/lancet/v2/formatter" import "github.com/duke-git/lancet/formatter"
``` ```
#### 函数列表: #### 函数列表:
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#Comma) - [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#Comma)
@@ -217,7 +191,7 @@ import "github.com/duke-git/lancet/v2/formatter"
### function函数包控制函数执行流程包含部分函数式编程。 ### function函数包控制函数执行流程包含部分函数式编程。
```go ```go
import "github.com/duke-git/lancet/v2/function" import "github.com/duke-git/lancet/function"
``` ```
#### 函数列表: #### 函数列表:
@@ -229,44 +203,25 @@ import "github.com/duke-git/lancet/v2/function"
- [Delay](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Delay) - [Delay](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Delay)
- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Watcher) - [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Watcher)
### 6. mathutil包实现了一些数学计算的函数。
### maputil包包括一些操作map的函数.
```go ```go
import "github.com/duke-git/lancet/v2/maputil" import "github.com/duke-git/lancet/mathutil"
```
#### 函数列表:
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#ForEach)
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Filter)
- [Intersect](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Intersect)
- [Keys](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Keys)
- [Merge](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Merge)
- [Minus](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Minus)
- [Values](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Values)
### mathutil包实现了一些数学计算的函数。
```go
import "github.com/duke-git/lancet/v2/mathutil"
``` ```
#### Function list: #### Function list:
- [Average](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Average)
- [Exponent](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Exponent) - [Exponent](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Exponent)
- [Fibonacci](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Fibonacci) - [Fibonacci](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Fibonacci)
- [Factorial](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Factorial) - [Factorial](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Factorial)
- [Max](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Max)
- [Min](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Min)
- [Percent](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Percent) - [Percent](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Percent)
- [RoundToFloat](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToFloat) - [RoundToFloat](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToFloat)
- [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToString) - [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToString)
- [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#TruncRound) - [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#TruncRound)
### netutil网络包支持获取ip地址发送http请求。 ### 7. netutil网络包支持获取ip地址发送http请求。
```go ```go
import "github.com/duke-git/lancet/v2/netutil" import "github.com/duke-git/lancet/netutil"
``` ```
#### 函数列表: #### 函数列表:
@@ -283,10 +238,10 @@ import "github.com/duke-git/lancet/v2/netutil"
- [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPatch) - [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPatch)
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ParseHttpResponse) - [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ParseHttpResponse)
### random随机数生成器包可以生成随机[]bytes, int, string。 ### 8. random随机数生成器包可以生成随机[]bytes, int, string。
```go ```go
import "github.com/duke-git/lancet/v2/random" import "github.com/duke-git/lancet/random"
``` ```
#### 函数列表: #### 函数列表:
@@ -294,10 +249,10 @@ import "github.com/duke-git/lancet/v2/random"
- [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandInt) - [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandInt)
- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandString) - [RandString](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandString)
- [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4) - [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4)
### retry重试执行函数直到函数运行成功或被context cancel。 ### 9. retry重试执行函数直到函数运行成功或被context cancel。
```go ```go
import "github.com/duke-git/lancet/v2/retry" import "github.com/duke-git/lancet/retry"
``` ```
#### 函数列表: #### 函数列表:
@@ -308,10 +263,10 @@ import "github.com/duke-git/lancet/v2/retry"
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryTimes) - [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryTimes)
### slice包包含操作切片的方法集合。 ### 10. slice包包含操作切片的方法集合。
```go ```go
import "github.com/duke-git/lancet/v2/slice" import "github.com/duke-git/lancet/slice"
``` ```
#### 函数列表: #### 函数列表:
@@ -323,39 +278,41 @@ import "github.com/duke-git/lancet/v2/slice"
- [Count](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Count) - [Count](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Count)
- [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Difference) - [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Difference)
- [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DifferenceBy) - [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DifferenceBy)
- [DifferenceWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceWith) - [DeleteByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DeleteByIndex)
- [DeleteAt](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DeleteAt)
- [Drop](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Drop) - [Drop](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Drop)
- [Every](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Every) - [Every](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Every)
- [Equal](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Equal)
- [EqualWith](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#EqualWith)
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Filter) - [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Filter)
- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Find) - [Find](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Find)
- [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#FindLast) - [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#FindLast)
- [FlattenDeep](#FlattenDeep) - [FlattenDeep](https://github.com/duke-git/lancet/blob/main/docs/slice.md#FlattenDeep)
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ForEach) - [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ForEach)
- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupBy) - [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupBy)
- [GroupWith](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupWith)
- [IntSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IntSlice) - [IntSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IntSlice)
- [IndexOf](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IndexOf)
- [LastIndexOf](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#LastIndexOf)
- [InterfaceSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InterfaceSlice) - [InterfaceSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InterfaceSlice)
- [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Intersection) - [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Intersection)
- [InsertAt](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InsertAt) - [InsertByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InsertByIndex)
- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Map) - [Map](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Map)
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reverse) - [ReverseSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ReverseSlice)
- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reduce) - [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reduce)
- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Shuffle) - [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Shuffle)
- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SortByField) - [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SortByField)
- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Some) - [Some](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Some)
- [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#StringSlice) - [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#StringSlice)
- [SymmetricDifference](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SymmetricDifference)
- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Unique) - [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Unique)
- [UniqueBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UniqueBy)
- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Union) - [Union](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Union)
- [UpdateAt](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UpdateAt) - [UpdateByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UpdateByIndex)
- [Without](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Without) - [Without](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Without)
### strutil包含处理字符串的相关函数。 ### 12. strutil包含处理字符串的相关函数。
```go ```go
import "github.com/duke-git/lancet/v2/strutil" import "github.com/duke-git/lancet/strutil"
``` ```
#### 函数列表: #### 函数列表:
@@ -374,14 +331,15 @@ import "github.com/duke-git/lancet/v2/strutil"
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadStart) - [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadStart)
- [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#ReverseStr) - [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#ReverseStr)
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SnakeCase) - [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SnakeCase)
- [SplitEx](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SplitEx)
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Wrap) - [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Wrap)
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Unwrap) - [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Unwrap)
### system包含os, runtime, shell command相关函数。 ### 13. system包含os, runtime, shell command相关函数。
```go ```go
import "github.com/duke-git/lancet/v2/system" import "github.com/duke-git/lancet/system"
``` ```
#### 函数列表: #### 函数列表:
@@ -394,10 +352,10 @@ import "github.com/duke-git/lancet/v2/system"
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#CompareOsEnv) - [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#CompareOsEnv)
- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#ExecCommand) - [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#ExecCommand)
### validator验证器包包含常用字符串格式验证函数。 ### 14. validator验证器包包含常用字符串格式验证函数。
```go ```go
import "github.com/duke-git/lancet/v2/validator" import "github.com/duke-git/lancet/validator"
``` ```
#### 函数列表: #### 函数列表:
@@ -428,14 +386,6 @@ import "github.com/duke-git/lancet/v2/validator"
- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsUrl) - [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsUrl)
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsWeakPassword) - [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsWeakPassword)
validator.md#IsWeakPassword)
### xerror包实现一些错误处理函数
```go
import "github.com/duke-git/lancet/v2/xerror"
```
#### 函数列表:
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)
## 如何贡献代码 ## 如何贡献代码

View File

@@ -1,102 +0,0 @@
package algorithm
type lruNode[K comparable, V any] struct {
key K
value V
pre *lruNode[K, V]
next *lruNode[K, V]
}
// newLruNode return a lruNode pointer
func newLruNode[K comparable, V any](key K, value V) *lruNode[K, V] {
return &lruNode[K, V]{
key: key,
value: value,
pre: nil,
next: nil,
}
}
// LRUCache lru cache (thread unsafe)
type LRUCache[K comparable, V any] struct {
cache map[K]*lruNode[K, V]
head *lruNode[K, V]
tail *lruNode[K, V]
capacity int
length int
}
// NewLRUCache return a LRUCache pointer
func NewLRUCache[K comparable, V any](capacity int) *LRUCache[K, V] {
return &LRUCache[K, V]{
cache: make(map[K]*lruNode[K, V], capacity),
head: nil,
tail: nil,
capacity: capacity,
length: 0,
}
}
// Get value of key from lru cache
func (l *LRUCache[K, V]) Get(key K) (V, bool) {
var value V
node, ok := l.cache[key]
if ok {
l.moveToHead(node)
return node.value, true
}
return value, false
}
// Put value of key into lru cache
func (l *LRUCache[K, V]) Put(key K, value V) {
node, ok := l.cache[key]
if !ok {
newNode := newLruNode(key, value)
l.cache[key] = newNode
l.addNode(newNode)
if len(l.cache) > l.capacity {
oldKey := l.deleteNode(l.head)
delete(l.cache, oldKey)
}
} else {
node.value = value
l.moveToHead(node)
}
l.length = len(l.cache)
}
func (l *LRUCache[K, V]) addNode(node *lruNode[K, V]) {
if l.tail != nil {
l.tail.next = node
node.pre = l.tail
node.next = nil
}
l.tail = node
if l.head == nil {
l.head = node
}
}
func (l *LRUCache[K, V]) deleteNode(node *lruNode[K, V]) K {
if node == l.tail {
l.tail = l.tail.pre
} else if node == l.head {
l.head = l.head.next
} else {
node.pre.next = node.next
node.next.pre = node.pre
}
return node.key
}
func (l *LRUCache[K, V]) moveToHead(node *lruNode[K, V]) {
if l.tail == node {
return
}
l.deleteNode(node)
l.addNode(node)
}

View File

@@ -1,36 +0,0 @@
package algorithm
import (
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestLRUCache(t *testing.T) {
asssert := internal.NewAssert(t, "TestLRUCache")
cache := NewLRUCache[int, int](2)
cache.Put(1, 1)
cache.Put(2, 2)
_, ok := cache.Get(0)
asssert.Equal(false, ok)
v, ok := cache.Get(1)
asssert.Equal(true, ok)
asssert.Equal(1, v)
v, ok = cache.Get(2)
asssert.Equal(true, ok)
asssert.Equal(2, v)
cache.Put(3, 3)
v, ok = cache.Get(1)
asssert.Equal(false, ok)
asssert.NotEqual(1, v)
v, ok = cache.Get(3)
asssert.Equal(true, ok)
asssert.Equal(3, v)
}

View File

@@ -1,63 +0,0 @@
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
// Use of this source code is governed by MIT license
// Package algorithm contain some basic algorithm functions. eg. sort, search, list, linklist, stack, queue, tree, graph. TODO
package algorithm
import "github.com/duke-git/lancet/v2/lancetconstraints"
// Search algorithms see https://github.com/TheAlgorithms/Go/tree/master/search
// 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
func LinearSearch[T any](slice []T, target T, comparator lancetconstraints.Comparator) int {
for i, v := range slice {
if comparator.Compare(v, target) == 0 {
return i
}
}
return -1
}
// 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
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int {
if highIndex < lowIndex || len(sortedSlice) == 0 {
return -1
}
midIndex := int(lowIndex + (highIndex-lowIndex)/2)
isMidValGreatTarget := comparator.Compare(sortedSlice[midIndex], target) == 1
isMidValLessTarget := comparator.Compare(sortedSlice[midIndex], target) == -1
if isMidValGreatTarget {
return BinarySearch(sortedSlice, target, lowIndex, midIndex-1, comparator)
} else if isMidValLessTarget {
return BinarySearch(sortedSlice, target, midIndex+1, highIndex, comparator)
}
return midIndex
}
// BinaryIterativeSearch search for target within a sorted slice.
// If a target is found, the index of the target is returned. Else the function return -1
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int {
startIndex := lowIndex
endIndex := highIndex
var midIndex int
for startIndex <= endIndex {
midIndex = int(startIndex + (endIndex-startIndex)/2)
isMidValGreatTarget := comparator.Compare(sortedSlice[midIndex], target) == 1
isMidValLessTarget := comparator.Compare(sortedSlice[midIndex], target) == -1
if isMidValGreatTarget {
endIndex = midIndex - 1
} else if isMidValLessTarget {
startIndex = midIndex + 1
} else {
return midIndex
}
}
return -1
}

View File

@@ -1,33 +0,0 @@
package algorithm
import (
"testing"
"github.com/duke-git/lancet/v2/internal"
)
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
func TestLinearSearch(t *testing.T) {
asssert := internal.NewAssert(t, "TestLinearSearch")
comparator := &intComparator{}
asssert.Equal(4, LinearSearch(sortedNumbers, 5, comparator))
asssert.Equal(-1, LinearSearch(sortedNumbers, 9, comparator))
}
func TestBinarySearch(t *testing.T) {
asssert := internal.NewAssert(t, "TestBinarySearch")
comparator := &intComparator{}
asssert.Equal(4, BinarySearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator))
asssert.Equal(-1, BinarySearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator))
}
func TestBinaryIterativeSearch(t *testing.T) {
asssert := internal.NewAssert(t, "TestBinaryIterativeSearch")
comparator := &intComparator{}
asssert.Equal(4, BinaryIterativeSearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator))
asssert.Equal(-1, BinaryIterativeSearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator))
}

View File

@@ -1,208 +0,0 @@
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
// Use of this source code is governed by MIT license
// Package algorithm contain some basic algorithm functions. eg. sort, search
package algorithm
import "github.com/duke-git/lancet/v2/lancetconstraints"
// BubbleSort use bubble to sort slice.
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
for i := 0; i < len(slice); i++ {
for j := 0; j < len(slice)-1-i; j++ {
isCurrGreatThanNext := comparator.Compare(slice[j], slice[j+1]) == 1
if isCurrGreatThanNext {
swap(slice, j, j+1)
}
}
}
return slice
}
// InsertionSort use insertion to sort slice.
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
size := len(slice)
if size <= 1 {
return slice
}
for i := 1; i < size; i++ {
currentItem := slice[i]
preIndex := i - 1
preItem := slice[preIndex]
isPreLessThanCurrent := comparator.Compare(preItem, currentItem) == -1
for preIndex >= 0 && isPreLessThanCurrent {
slice[preIndex+1] = slice[preIndex]
preIndex--
}
slice[preIndex+1] = currentItem
}
return slice
}
// SelectionSort use selection to sort slice.
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
for i := 0; i < len(slice); i++ {
min := i
for j := i + 1; j < len(slice); j++ {
if comparator.Compare(slice[j], slice[min]) == -1 {
min = j
}
}
swap(slice, i, min)
}
return slice
}
// ShellSort shell sort slice.
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
size := len(slice)
if size <= 1 {
return slice
}
gap := 1
for gap < size/3 {
gap = 3*gap + 1
}
for gap >= 1 {
for i := gap; i < size; i++ {
for j := i; j >= gap && comparator.Compare(slice[j], slice[j-gap]) == -1; j -= gap {
swap(slice, j, j-gap)
}
}
gap /= 3
}
return slice
}
// QuickSort quick sorting for slice, lowIndex is 0 and highIndex is len(slice)-1
func QuickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T {
if lowIndex < highIndex {
p := partition(slice, lowIndex, highIndex, comparator)
QuickSort(slice, lowIndex, p-1, comparator)
QuickSort(slice, p+1, highIndex, comparator)
}
return slice
}
// partition split slice into two parts
func partition[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int {
p := slice[highIndex]
i := lowIndex
for j := lowIndex; j < highIndex; j++ {
if comparator.Compare(slice[j], p) == -1 { //slice[j] < p
swap(slice, i, j)
i++
}
}
swap(slice, i, highIndex)
return i
}
// HeapSort use heap to sort slice
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
size := len(slice)
for i := size/2 - 1; i >= 0; i-- {
sift(slice, i, size-1, comparator)
}
for j := size - 1; j > 0; j-- {
swap(slice, 0, j)
sift(slice, 0, j-1, comparator)
}
return slice
}
func sift[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) {
i := lowIndex
j := 2*i + 1
temp := slice[i]
for j <= highIndex {
if j < highIndex && comparator.Compare(slice[j], slice[j+1]) == -1 { //slice[j] < slice[j+1]
j++
}
if comparator.Compare(temp, slice[j]) == -1 { //tmp < slice[j]
slice[i] = slice[j]
i = j
j = 2*i + 1
} else {
break
}
}
slice[i] = temp
}
// MergeSort merge sorting for slice
func MergeSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T {
if lowIndex < highIndex {
mid := (lowIndex + highIndex) / 2
MergeSort(slice, lowIndex, mid, comparator)
MergeSort(slice, mid+1, highIndex, comparator)
merge(slice, lowIndex, mid, highIndex, comparator)
}
return slice
}
func merge[T any](slice []T, lowIndex, midIndex, highIndex int, comparator lancetconstraints.Comparator) {
i := lowIndex
j := midIndex + 1
temp := []T{}
for i <= midIndex && j <= highIndex {
//slice[i] < slice[j]
if comparator.Compare(slice[i], slice[j]) == -1 {
temp = append(temp, slice[i])
i++
} else {
temp = append(temp, slice[j])
j++
}
}
if i <= midIndex {
temp = append(temp, slice[i:midIndex+1]...)
} else {
temp = append(temp, slice[j:highIndex+1]...)
}
for k := 0; k < len(temp); k++ {
slice[lowIndex+k] = temp[k]
}
}
// CountSort use count sorting for slice
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
size := len(slice)
out := make([]T, size)
for i := 0; i < size; i++ {
count := 0
for j := 0; j < size; j++ {
//slice[i] > slice[j]
if comparator.Compare(slice[i], slice[j]) == 1 {
count++
}
}
out[count] = slice[i]
}
return out
}
// swap two slice value at index i and j
func swap[T any](slice []T, i, j int) {
slice[i], slice[j] = slice[j], slice[i]
}

View File

@@ -1,177 +0,0 @@
package algorithm
import (
"fmt"
"testing"
"github.com/duke-git/lancet/v2/internal"
)
// People test mock data
type people struct {
Name string
Age int
}
// PeopleAageComparator sort people slice by age field
type peopleAgeComparator struct{}
// Compare implements github.com/duke-git/lancet/v2/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{
{Name: "a", Age: 20},
{Name: "b", Age: 10},
{Name: "c", Age: 17},
{Name: "d", Age: 8},
{Name: "e", Age: 28},
}
type intComparator struct{}
func (c *intComparator) Compare(v1 any, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
var intSlice = []int{2, 1, 5, 3, 6, 4}
func TestBubbleSortForStructSlice(t *testing.T) {
asssert := internal.NewAssert(t, "TestBubbleSortForStructSlice")
comparator := &peopleAgeComparator{}
sortedPeopleByAge := BubbleSort(peoples, comparator)
t.Log(sortedPeopleByAge)
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
actual := fmt.Sprintf("%v", sortedPeopleByAge)
asssert.Equal(expected, actual)
}
func TestBubbleSortForIntSlice(t *testing.T) {
asssert := internal.NewAssert(t, "TestBubbleSortForIntSlice")
comparator := &intComparator{}
sortedInt := BubbleSort(intSlice, comparator)
expected := []int{1, 2, 3, 4, 5, 6}
asssert.Equal(expected, sortedInt)
}
func TestInsertionSort(t *testing.T) {
asssert := internal.NewAssert(t, "TestInsertionSort")
comparator := &peopleAgeComparator{}
sortedPeopleByAge := InsertionSort(peoples, comparator)
t.Log(sortedPeopleByAge)
expected := "[{e 28} {a 20} {c 17} {b 10} {d 8}]"
actual := fmt.Sprintf("%v", sortedPeopleByAge)
asssert.Equal(expected, actual)
}
func TestSelectionSort(t *testing.T) {
asssert := internal.NewAssert(t, "TestSelectionSort")
comparator := &peopleAgeComparator{}
sortedPeopleByAge := SelectionSort(peoples, comparator)
t.Log(sortedPeopleByAge)
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
actual := fmt.Sprintf("%v", sortedPeopleByAge)
asssert.Equal(expected, actual)
}
func TestShellSort(t *testing.T) {
asssert := internal.NewAssert(t, "TestShellSort")
comparator := &peopleAgeComparator{}
sortedPeopleByAge := ShellSort(peoples, comparator)
t.Log(sortedPeopleByAge)
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
actual := fmt.Sprintf("%v", sortedPeopleByAge)
asssert.Equal(expected, actual)
}
func TestQuickSort(t *testing.T) {
asssert := internal.NewAssert(t, "TestQuickSort")
comparator := &peopleAgeComparator{}
sortedPeopleByAge := QuickSort(peoples, 0, len(peoples)-1, comparator)
t.Log(sortedPeopleByAge)
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
actual := fmt.Sprintf("%v", sortedPeopleByAge)
asssert.Equal(expected, actual)
}
func TestHeapSort(t *testing.T) {
asssert := internal.NewAssert(t, "TestHeapSort")
comparator := &peopleAgeComparator{}
sortedPeopleByAge := HeapSort(peoples, comparator)
t.Log(sortedPeopleByAge)
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
actual := fmt.Sprintf("%v", sortedPeopleByAge)
asssert.Equal(expected, actual)
}
func TestMergeSort(t *testing.T) {
asssert := internal.NewAssert(t, "TestMergeSort")
comparator := &peopleAgeComparator{}
sortedPeopleByAge := MergeSort(peoples, 0, len(peoples)-1, comparator)
t.Log(sortedPeopleByAge)
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
actual := fmt.Sprintf("%v", sortedPeopleByAge)
asssert.Equal(expected, actual)
}
func TestCountSort(t *testing.T) {
asssert := internal.NewAssert(t, "TestCountSort")
comparator := &peopleAgeComparator{}
sortedPeopleByAge := CountSort(peoples, comparator)
t.Log(sortedPeopleByAge)
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
actual := fmt.Sprintf("%v", sortedPeopleByAge)
asssert.Equal(expected, actual)
}

View File

@@ -22,7 +22,7 @@ func ToBool(s string) (bool, error) {
} }
// ToBytes convert interface to bytes // ToBytes convert interface to bytes
func ToBytes(value any) ([]byte, error) { func ToBytes(value interface{}) ([]byte, error) {
v := reflect.ValueOf(value) v := reflect.ValueOf(value)
switch value.(type) { switch value.(type) {
@@ -75,7 +75,7 @@ func ToChar(s string) []string {
} }
// ToString convert value to string // ToString convert value to string
func ToString(value any) string { func ToString(value interface{}) string {
res := "" res := ""
if value == nil { if value == nil {
return res return res
@@ -107,7 +107,7 @@ func ToString(value any) string {
} }
// ToJson convert value to a valid json string // ToJson convert value to a valid json string
func ToJson(value any) (string, error) { func ToJson(value interface{}) (string, error) {
res, err := json.Marshal(value) res, err := json.Marshal(value)
if err != nil { if err != nil {
return "", err return "", err
@@ -117,7 +117,7 @@ func ToJson(value any) (string, error) {
} }
// ToFloat convert value to a float64, if input is not a float return 0.0 and error // ToFloat convert value to a float64, if input is not a float return 0.0 and error
func ToFloat(value any) (float64, error) { func ToFloat(value interface{}) (float64, error) {
v := reflect.ValueOf(value) v := reflect.ValueOf(value)
res := 0.0 res := 0.0
@@ -144,7 +144,7 @@ func ToFloat(value any) (float64, error) {
} }
// ToInt convert value to a int64, if input is not a numeric format return 0 and error // ToInt convert value to a int64, if input is not a numeric format return 0 and error
func ToInt(value any) (int64, error) { func ToInt(value interface{}) (int64, error) {
v := reflect.ValueOf(value) v := reflect.ValueOf(value)
var res int64 var res int64
@@ -172,7 +172,7 @@ func ToInt(value any) (int64, error) {
// StructToMap convert struct to map, only convert exported struct field // StructToMap convert struct to map, only convert exported struct field
// map key is specified same as struct field tag `json` value // map key is specified same as struct field tag `json` value
func StructToMap(value any) (map[string]any, error) { func StructToMap(value interface{}) (map[string]interface{}, error) {
v := reflect.ValueOf(value) v := reflect.ValueOf(value)
t := reflect.TypeOf(value) t := reflect.TypeOf(value)
@@ -183,7 +183,7 @@ func StructToMap(value any) (map[string]any, error) {
return nil, fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", value) return nil, fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", value)
} }
res := make(map[string]any) res := make(map[string]interface{})
fieldNum := t.NumField() fieldNum := t.NumField()
pattern := `^[A-Z]` pattern := `^[A-Z]`

View File

@@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestToChar(t *testing.T) { func TestToChar(t *testing.T) {
@@ -36,7 +36,7 @@ func TestToBool(t *testing.T) {
func TestToBytes(t *testing.T) { func TestToBytes(t *testing.T) {
assert := internal.NewAssert(t, "TestToBytes") assert := internal.NewAssert(t, "TestToBytes")
cases := []any{ cases := []interface{}{
0, 0,
false, false,
"1", "1",
@@ -62,7 +62,7 @@ func TestToBytes(t *testing.T) {
func TestToInt(t *testing.T) { func TestToInt(t *testing.T) {
assert := internal.NewAssert(t, "TestToInt") assert := internal.NewAssert(t, "TestToInt")
cases := []any{"123", "-123", 123, cases := []interface{}{"123", "-123", 123,
uint(123), uint8(123), uint16(123), uint32(123), uint64(123), uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
float32(12.3), float64(12.3), float32(12.3), float64(12.3),
"abc", false, "111111111111111111111111111111111111111"} "abc", false, "111111111111111111111111111111111111111"}
@@ -78,7 +78,7 @@ func TestToInt(t *testing.T) {
func TestToFloat(t *testing.T) { func TestToFloat(t *testing.T) {
assert := internal.NewAssert(t, "TestToFloat") assert := internal.NewAssert(t, "TestToFloat")
cases := []any{ cases := []interface{}{
"", "-1", "-.11", "1.23e3", ".123e10", "abc", "", "-1", "-.11", "1.23e3", ".123e10", "abc",
int(0), int8(1), int16(-1), int32(123), int64(123), int(0), int8(1), int16(-1), int32(123), int64(123),
uint(123), uint8(123), uint16(123), uint32(123), uint64(123), uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
@@ -106,7 +106,7 @@ func TestToString(t *testing.T) {
} }
aStruct := TestStruct{Name: "TestStruct"} aStruct := TestStruct{Name: "TestStruct"}
cases := []any{ cases := []interface{}{
"", nil, "", nil,
int(0), int8(1), int16(-1), int32(123), int64(123), int(0), int8(1), int16(-1), int32(123), int64(123),
uint(123), uint8(123), uint16(123), uint32(123), uint64(123), uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
@@ -154,7 +154,7 @@ func TestStructToMap(t *testing.T) {
100, 100,
} }
pm, _ := StructToMap(p) pm, _ := StructToMap(p)
var expected = map[string]any{"name": "test"} var expected = map[string]interface{}{"name": "test"}
assert.Equal(expected, pm) assert.Equal(expected, pm)
} }

View File

@@ -3,7 +3,7 @@ package cryptor
import ( import (
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestAesEcbEncrypt(t *testing.T) { func TestAesEcbEncrypt(t *testing.T) {

View File

@@ -3,7 +3,7 @@ package cryptor
import ( import (
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestBase64StdEncode(t *testing.T) { func TestBase64StdEncode(t *testing.T) {

View File

@@ -3,7 +3,7 @@ package cryptor
import ( import (
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestDesEcbEncrypt(t *testing.T) { func TestDesEcbEncrypt(t *testing.T) {

View File

@@ -3,7 +3,7 @@ package cryptor
import ( import (
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestRsaEncrypt(t *testing.T) { func TestRsaEncrypt(t *testing.T) {

View File

@@ -1,241 +0,0 @@
package datastructure
import (
"errors"
"fmt"
"github.com/duke-git/lancet/v2/datastructure"
)
// DoublyLink is a linked list. Whose node has a generic Value, Pre pointer points to a previous node of the link, Next pointer points to a next node of the link.
type DoublyLink[T any] struct {
Head *datastructure.LinkNode[T]
length int
}
// NewDoublyLink return *DoublyLink instance
func NewDoublyLink[T any]() *DoublyLink[T] {
return &DoublyLink[T]{Head: nil}
}
// InsertAtHead insert value into doubly linklist at head index
func (link *DoublyLink[T]) InsertAtHead(value T) {
newNode := datastructure.NewLinkNode(value)
size := link.Size()
if size == 0 {
link.Head = newNode
link.length++
return
}
newNode.Next = link.Head
newNode.Pre = nil
link.Head.Pre = newNode
link.Head = newNode
link.length++
}
// InsertAtTail insert value into doubly linklist at tail index
func (link *DoublyLink[T]) InsertAtTail(value T) {
current := link.Head
if current == nil {
link.InsertAtHead(value)
return
}
for current.Next != nil {
current = current.Next
}
newNode := datastructure.NewLinkNode(value)
newNode.Next = nil
newNode.Pre = current
current.Next = newNode
link.length++
}
// InsertAt insert value into doubly linklist at index
func (link *DoublyLink[T]) InsertAt(index int, value T) error {
size := link.length
if index < 0 || index > size {
return errors.New("param index should between 0 and the length of doubly link.")
}
if index == 0 {
link.InsertAtHead(value)
return nil
}
if index == size {
link.InsertAtTail(value)
return nil
}
i := 0
current := link.Head
for current != nil {
if i == index-1 {
newNode := datastructure.NewLinkNode(value)
newNode.Next = current.Next
newNode.Pre = current
current.Next = newNode
link.length++
return nil
}
i++
current = current.Next
}
return errors.New("doubly link list no exist")
}
// DeleteAtHead delete value in doubly linklist at head index
func (link *DoublyLink[T]) DeleteAtHead() error {
if link.Head == nil {
return errors.New("doubly link list no exist")
}
current := link.Head
link.Head = current.Next
link.Head.Pre = nil
link.length--
return nil
}
// DeleteAtTail delete value in doubly linklist at tail index
func (link *DoublyLink[T]) DeleteAtTail() error {
if link.Head == nil {
return errors.New("doubly link list no exist")
}
current := link.Head
if current.Next == nil {
return link.DeleteAtHead()
}
for current.Next.Next != nil {
current = current.Next
}
current.Next = nil
link.length--
return nil
}
// DeleteAt delete value in doubly linklist at index
func (link *DoublyLink[T]) DeleteAt(index int) error {
if link.Head == nil {
return errors.New("doubly link list no exist")
}
current := link.Head
if current.Next == nil || index == 0 {
return link.DeleteAtHead()
}
if index == link.length-1 {
return link.DeleteAtTail()
}
if index < 0 || index > link.length-1 {
return errors.New("param index should between 0 and link size -1.")
}
i := 0
for current != nil {
if i == index-1 {
current.Next = current.Next.Next
link.length--
return nil
}
i++
current = current.Next
}
return errors.New("delete error")
}
// Reverse the linked list
func (link *DoublyLink[T]) Reverse() {
current := link.Head
var temp *datastructure.LinkNode[T]
for current != nil {
temp = current.Pre
current.Pre = current.Next
current.Next = temp
current = current.Pre
}
if temp != nil {
link.Head = temp.Pre
}
}
// GetMiddleNode return node at middle index of linked list
func (link *DoublyLink[T]) GetMiddleNode() *datastructure.LinkNode[T] {
if link.Head == nil {
return nil
}
if link.Head.Next == nil {
return link.Head
}
fast := link.Head
slow := link.Head
for fast != nil {
fast = fast.Next
if fast != nil {
fast = fast.Next
slow = slow.Next
} else {
return slow
}
}
return slow
}
// Size return the count of doubly linked list
func (link *DoublyLink[T]) Size() int {
return link.length
}
// Values return slice of all doubly linklist node value
func (link *DoublyLink[T]) Values() []T {
res := []T{}
current := link.Head
for current != nil {
res = append(res, current.Value)
current = current.Next
}
return res
}
// Print all nodes info of a linked list
func (link *DoublyLink[T]) Print() {
current := link.Head
info := "[ "
for current != nil {
info += fmt.Sprintf("%+v, ", current)
current = current.Next
}
info += " ]"
fmt.Println(info)
}
// IsEmpty checks if link is empty or not
func (link *DoublyLink[T]) IsEmpty() bool {
return link.length == 0
}
// Clear checks if link is empty or not
func (link *DoublyLink[T]) Clear() {
link.Head = nil
link.length = 0
}

View File

@@ -1,179 +0,0 @@
package datastructure
import (
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestDoublyLink_InsertAtFirst(t *testing.T) {
assert := internal.NewAssert(t, "TestDoublyLink_InsertAtFirst")
link := NewDoublyLink[int]()
link.InsertAtHead(1)
link.InsertAtHead(2)
link.InsertAtHead(3)
link.Print()
expected := []int{3, 2, 1}
values := link.Values()
assert.Equal(expected, values)
}
func TestDoublyLink_InsertAtTail(t *testing.T) {
assert := internal.NewAssert(t, "TestDoublyLink_InsertAtTail")
link := NewDoublyLink[int]()
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.Print()
expected := []int{1, 2, 3}
values := link.Values()
assert.Equal(expected, values)
}
func TestDoublyLink_InsertAt(t *testing.T) {
assert := internal.NewAssert(t, "TestDoublyLink_InsertAt")
link := NewDoublyLink[int]()
err := link.InsertAt(1, 1)
assert.IsNotNil(err)
link.InsertAt(0, 1)
link.InsertAt(1, 2)
link.InsertAt(2, 4)
link.InsertAt(2, 3)
link.Print()
expected := []int{1, 2, 3, 4}
values := link.Values()
assert.Equal(expected, values)
}
func TestDoublyLink_DeleteAtHead(t *testing.T) {
assert := internal.NewAssert(t, "TestDoublyLink_DeleteAtHead")
link := NewDoublyLink[int]()
err := link.DeleteAtHead()
assert.IsNotNil(err)
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.InsertAtTail(4)
link.DeleteAtHead()
link.Print()
expected := []int{2, 3, 4}
values := link.Values()
assert.Equal(expected, values)
}
func TestDoublyLink_DeleteAtTail(t *testing.T) {
assert := internal.NewAssert(t, "TestDoublyLink_DeleteAtTail")
link := NewDoublyLink[int]()
err := link.DeleteAtTail()
assert.IsNotNil(err)
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.InsertAtTail(4)
link.DeleteAtTail()
link.Print()
expected := []int{1, 2, 3}
values := link.Values()
assert.Equal(expected, values)
}
func TestDoublyLink_DeleteAt(t *testing.T) {
assert := internal.NewAssert(t, "TestDoublyLink_DeleteAt")
link := NewDoublyLink[int]()
err := link.DeleteAt(0)
assert.IsNotNil(err)
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.InsertAtTail(4)
link.InsertAtTail(5)
err = link.DeleteAt(5)
assert.IsNotNil(err)
err = link.DeleteAt(0)
assert.IsNil(err)
assert.Equal([]int{2, 3, 4, 5}, link.Values())
link.DeleteAt(3)
assert.Equal([]int{2, 3, 4}, link.Values())
link.DeleteAt(1)
assert.Equal(2, link.Size())
assert.Equal([]int{2, 4}, link.Values())
}
func TestDoublyLink_Reverse(t *testing.T) {
assert := internal.NewAssert(t, "TestDoublyLink_Reverse")
link := NewDoublyLink[int]()
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.InsertAtTail(4)
link.Reverse()
link.Print()
assert.Equal([]int{4, 3, 2, 1}, link.Values())
}
func TestDoublyLink_GetMiddleNode(t *testing.T) {
assert := internal.NewAssert(t, "TestDoublyLink_GetMiddleNode")
link := NewDoublyLink[int]()
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.InsertAtTail(4)
middle1 := link.GetMiddleNode()
assert.Equal(3, middle1.Value)
link.InsertAtTail(5)
link.InsertAtTail(6)
link.InsertAtTail(7)
middle2 := link.GetMiddleNode()
assert.Equal(4, middle2.Value)
}
func TestDoublyLink_Clear(t *testing.T) {
assert := internal.NewAssert(t, "TestDoublyLink_Clear")
link := NewDoublyLink[int]()
assert.Equal(true, link.IsEmpty())
assert.Equal(0, link.Size())
link.InsertAtTail(1)
assert.Equal(false, link.IsEmpty())
assert.Equal(1, link.Size())
link.Clear()
assert.Equal(true, link.IsEmpty())
assert.Equal(0, link.Size())
}

View File

@@ -1,246 +0,0 @@
package datastructure
import (
"errors"
"fmt"
"reflect"
"github.com/duke-git/lancet/v2/datastructure"
)
// SinglyLink is a linked list. Whose node has a Value generics and Next pointer points to a next node of the link.
type SinglyLink[T any] struct {
Head *datastructure.LinkNode[T]
length int
}
// NewSinglyLink return *SinglyLink instance
func NewSinglyLink[T any]() *SinglyLink[T] {
return &SinglyLink[T]{Head: nil}
}
// InsertAtHead insert value into singly linklist at head index
func (link *SinglyLink[T]) InsertAtHead(value T) {
newNode := datastructure.NewLinkNode(value)
newNode.Next = link.Head
link.Head = newNode
link.length++
}
// InsertAtTail insert value into singly linklist at tail index
func (link *SinglyLink[T]) InsertAtTail(value T) {
current := link.Head
if current == nil {
link.InsertAtHead(value)
return
}
for current.Next != nil {
current = current.Next
}
newNode := datastructure.NewLinkNode(value)
newNode.Next = nil
current.Next = newNode
link.length++
}
// InsertAt insert value into singly linklist at index
func (link *SinglyLink[T]) InsertAt(index int, value T) error {
size := link.length
if index < 0 || index > size {
return errors.New("param index should between 0 and the length of singly link.")
}
if index == 0 {
link.InsertAtHead(value)
return nil
}
if index == size {
link.InsertAtTail(value)
return nil
}
i := 0
current := link.Head
for current != nil {
if i == index-1 {
newNode := datastructure.NewLinkNode(value)
newNode.Next = current.Next
current.Next = newNode
link.length++
return nil
}
i++
current = current.Next
}
return errors.New("singly link list no exist")
}
// DeleteAtHead delete value in singly linklist at head index
func (link *SinglyLink[T]) DeleteAtHead() error {
if link.Head == nil {
return errors.New("singly link list no exist")
}
current := link.Head
link.Head = current.Next
link.length--
return nil
}
// DeleteAtTail delete value in singly linklist at tail index
func (link *SinglyLink[T]) DeleteAtTail() error {
if link.Head == nil {
return errors.New("singly link list no exist")
}
current := link.Head
if current.Next == nil {
return link.DeleteAtHead()
}
for current.Next.Next != nil {
current = current.Next
}
current.Next = nil
link.length--
return nil
}
// DeleteAt delete value in singly linklist at index
func (link *SinglyLink[T]) DeleteAt(index int) error {
if link.Head == nil {
return errors.New("singly link list no exist")
}
current := link.Head
if current.Next == nil || index == 0 {
return link.DeleteAtHead()
}
if index == link.length-1 {
return link.DeleteAtTail()
}
if index < 0 || index > link.length-1 {
return errors.New("param index should between 0 and link size -1.")
}
i := 0
for current != nil {
if i == index-1 {
current.Next = current.Next.Next
link.length--
return nil
}
i++
current = current.Next
}
return errors.New("delete error")
}
// DeleteValue delete value in singly linklist
func (link *SinglyLink[T]) DeleteValue(value T) {
if link.Head == nil {
return
}
dummyHead := datastructure.NewLinkNode(value)
dummyHead.Next = link.Head
current := dummyHead
for current.Next != nil {
if reflect.DeepEqual(current.Next.Value, value) {
current.Next = current.Next.Next
link.length--
} else {
current = current.Next
}
}
link.Head = dummyHead.Next
}
// Reverse the linked list
func (link *SinglyLink[T]) Reverse() {
var pre, next *datastructure.LinkNode[T]
current := link.Head
for current != nil {
next = current.Next
current.Next = pre
pre = current
current = next
}
link.Head = pre
}
// GetMiddleNode return node at middle index of linked list
func (link *SinglyLink[T]) GetMiddleNode() *datastructure.LinkNode[T] {
if link.Head == nil {
return nil
}
if link.Head.Next == nil {
return link.Head
}
fast := link.Head
slow := link.Head
for fast != nil {
fast = fast.Next
if fast != nil {
fast = fast.Next
slow = slow.Next
} else {
return slow
}
}
return slow
}
// Size return the count of singly linked list
func (link *SinglyLink[T]) Size() int {
return link.length
}
// Values return slice of all singly linklist node value
func (link *SinglyLink[T]) Values() []T {
res := []T{}
current := link.Head
for current != nil {
res = append(res, current.Value)
current = current.Next
}
return res
}
// IsEmpty checks if link is empty or not
func (link *SinglyLink[T]) IsEmpty() bool {
return link.length == 0
}
// Clear checks if link is empty or not
func (link *SinglyLink[T]) Clear() {
link.Head = nil
link.length = 0
}
// Print all nodes info of a linked list
func (link *SinglyLink[T]) Print() {
current := link.Head
info := "[ "
for current != nil {
info += fmt.Sprintf("%+v, ", current)
current = current.Next
}
info += " ]"
fmt.Println(info)
}

View File

@@ -1,208 +0,0 @@
package datastructure
import (
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestSinglyLink_InsertAtFirst(t *testing.T) {
assert := internal.NewAssert(t, "TestSinglyLink_InsertAtFirst")
link := NewSinglyLink[int]()
link.InsertAtHead(1)
link.InsertAtHead(2)
link.InsertAtHead(3)
link.Print()
expected := []int{3, 2, 1}
values := link.Values()
assert.Equal(expected, values)
}
func TestSinglyLink_InsertAtTail(t *testing.T) {
assert := internal.NewAssert(t, "TestSinglyLink_InsertAtTail")
link := NewSinglyLink[int]()
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.Print()
expected := []int{1, 2, 3}
values := link.Values()
assert.Equal(expected, values)
}
func TestSinglyLink_InsertAt(t *testing.T) {
assert := internal.NewAssert(t, "TestSinglyLink_InsertAt")
link := NewSinglyLink[int]()
err := link.InsertAt(1, 1)
assert.IsNotNil(err)
err = link.InsertAt(0, 1)
if err != nil {
t.FailNow()
}
err = link.InsertAt(1, 2)
if err != nil {
t.FailNow()
}
err = link.InsertAt(2, 4)
if err != nil {
t.FailNow()
}
err = link.InsertAt(2, 3)
if err != nil {
t.FailNow()
}
link.Print()
expected := []int{1, 2, 3, 4}
values := link.Values()
assert.Equal(expected, values)
}
func TestSinglyLink_DeleteAtHead(t *testing.T) {
assert := internal.NewAssert(t, "TestSinglyLink_DeleteAtHead")
link := NewSinglyLink[int]()
err := link.DeleteAtHead()
assert.IsNotNil(err)
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.InsertAtTail(4)
link.DeleteAtHead()
link.Print()
expected := []int{2, 3, 4}
values := link.Values()
assert.Equal(expected, values)
}
func TestSinglyLink_DeleteAtTail(t *testing.T) {
assert := internal.NewAssert(t, "TestSinglyLink_DeleteAtTail")
link := NewSinglyLink[int]()
err := link.DeleteAtTail()
assert.IsNotNil(err)
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.InsertAtTail(4)
link.DeleteAtTail()
link.Print()
expected := []int{1, 2, 3}
values := link.Values()
assert.Equal(expected, values)
}
func TestSinglyLink_DeleteValue(t *testing.T) {
assert := internal.NewAssert(t, "TestSinglyLink_DeleteValue")
link := NewSinglyLink[int]()
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.InsertAtTail(4)
link.DeleteValue(2)
assert.Equal([]int{1, 3, 4}, link.Values())
link.DeleteValue(1)
assert.Equal([]int{3, 4}, link.Values())
}
func TestSinglyLink_DeleteAt(t *testing.T) {
assert := internal.NewAssert(t, "TestSinglyLink_DeleteAt")
link := NewSinglyLink[int]()
err := link.DeleteAt(0)
assert.IsNotNil(err)
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.InsertAtTail(4)
link.InsertAtTail(5)
err = link.DeleteAt(5)
assert.IsNotNil(err)
err = link.DeleteAt(0)
assert.IsNil(err)
assert.Equal([]int{2, 3, 4, 5}, link.Values())
link.DeleteAt(3)
assert.Equal([]int{2, 3, 4}, link.Values())
link.DeleteAt(1)
assert.Equal(2, link.Size())
assert.Equal([]int{2, 4}, link.Values())
}
func TestSinglyLink_Reverse(t *testing.T) {
assert := internal.NewAssert(t, "TestSinglyLink_Reverse")
link := NewSinglyLink[int]()
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.InsertAtTail(4)
link.Reverse()
link.Print()
assert.Equal([]int{4, 3, 2, 1}, link.Values())
}
func TestSinglyLink_GetMiddleNode(t *testing.T) {
assert := internal.NewAssert(t, "TestSinglyLink_GetMiddleNode")
link := NewSinglyLink[int]()
link.InsertAtTail(1)
link.InsertAtTail(2)
link.InsertAtTail(3)
link.InsertAtTail(4)
middle1 := link.GetMiddleNode()
assert.Equal(3, middle1.Value)
link.InsertAtTail(5)
link.InsertAtTail(6)
link.InsertAtTail(7)
middle2 := link.GetMiddleNode()
assert.Equal(4, middle2.Value)
}
func TestSinglyLink_Clear(t *testing.T) {
assert := internal.NewAssert(t, "TestSinglyLink_Clear")
link := NewSinglyLink[int]()
assert.Equal(true, link.IsEmpty())
assert.Equal(0, link.Size())
link.InsertAtTail(1)
assert.Equal(false, link.IsEmpty())
assert.Equal(1, link.Size())
link.Clear()
assert.Equal(true, link.IsEmpty())
assert.Equal(0, link.Size())
}

View File

@@ -1,245 +0,0 @@
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
// Use of this source code is governed by MIT license
// Package datastructure implements some data structure. eg. list, linklist, stack, queue, tree, graph.
package datastructure
import (
"reflect"
)
// List is a linear table, implemented with slice
type List[T any] struct {
data []T
}
// NewList return a pointer of List
func NewList[T any](data []T) *List[T] {
return &List[T]{data: data}
}
// Data return list data
func (l *List[T]) Data() []T {
return l.data
}
// ValueOf return the value pointer at index of list data.
func (l *List[T]) ValueOf(index int) (*T, bool) {
if index < 0 || index >= len(l.data) {
return nil, false
}
return &l.data[index], true
}
// IndexOf reture the index of value. if not found return -1
func (l *List[T]) IndexOf(value T) int {
index := -1
data := l.data
for i, v := range data {
if reflect.DeepEqual(v, value) {
index = i
break
}
}
return index
}
// Contain checks if the value in the list or not
func (l *List[T]) Contain(value T) bool {
data := l.data
for _, v := range data {
if reflect.DeepEqual(v, value) {
return true
}
}
return false
}
// Push append value to the list data
func (l *List[T]) Push(value T) {
l.data = append(l.data, value)
}
// InsertAtFirst insert value into list at first index
func (l *List[T]) InsertAtFirst(value T) {
l.InsertAt(0, value)
}
// InsertAtLast insert value into list at last index
func (l *List[T]) InsertAtLast(value T) {
l.InsertAt(len(l.data), value)
}
// InsertAt insert value into list at index
func (l *List[T]) InsertAt(index int, value T) {
data := l.data
size := len(data)
if index < 0 || index > size {
return
}
l.data = append(data[:index], append([]T{value}, data[index:]...)...)
}
// PopFirst delete the first value of list and return it
func (l *List[T]) PopFirst() (*T, bool) {
if len(l.data) == 0 {
return nil, false
}
v := l.data[0]
l.DeleteAt(0)
return &v, true
}
// PopLast delete the last value of list and return it
func (l *List[T]) PopLast() (*T, bool) {
size := len(l.data)
if size == 0 {
return nil, false
}
v := l.data[size-1]
l.DeleteAt(size - 1)
return &v, true
}
// DeleteAt delete the value of list at index
func (l *List[T]) DeleteAt(index int) {
data := l.data
size := len(data)
if index < 0 || index > size-1 {
return
}
if index == size-1 {
data = append(data[:index])
} else {
data = append(data[:index], data[index+1:]...)
}
l.data = data
}
// UpdateAt update value of list at index, index shoud between 0 and list size -1
func (l *List[T]) UpdateAt(index int, value T) {
data := l.data
size := len(data)
if index < 0 || index >= size {
return
}
l.data = append(data[:index], append([]T{value}, data[index+1:]...)...)
}
// Equtal compare list to other list, use reflect.DeepEqual
func (l *List[T]) Equtal(other *List[T]) bool {
if len(l.data) != len(other.data) {
return false
}
for i := 0; i < len(l.data); i++ {
if !reflect.DeepEqual(l.data[i], other.data[i]) {
return false
}
}
return true
}
// IsEmpty check if the list is empty or not
func (l *List[T]) IsEmpty() bool {
return len(l.data) == 0
}
// Clear the data of list
func (l *List[T]) Clear() {
l.data = make([]T, 0, 0)
}
// Clone return a copy of list
func (l *List[T]) Clone() *List[T] {
cl := NewList(make([]T, len(l.data)))
copy(cl.data, l.data)
return cl
}
// Merge two list, return new list, don't change original list
func (l *List[T]) Merge(other *List[T]) *List[T] {
l1, l2 := len(l.data), len(other.data)
ml := NewList(make([]T, l1+l2, l1+l2))
data := append([]T{}, append(l.data, other.data...)...)
ml.data = data
return ml
}
// Size return number of list data items
func (l *List[T]) Size() int {
return len(l.data)
}
// Swap the value of index i and j in list
func (l *List[T]) Swap(i, j int) {
size := len(l.data)
if i < 0 || i >= size || j < 0 || j >= size {
return
}
l.data[i], l.data[j] = l.data[j], l.data[i]
}
// Reverse the item order of list
func (l *List[T]) Reverse() {
for i, j := 0, len(l.data)-1; i < j; i, j = i+1, j-1 {
l.data[i], l.data[j] = l.data[j], l.data[i]
}
}
// Unique remove duplicate items in list
func (l *List[T]) Unique() {
data := l.data
size := len(data)
uniqueData := make([]T, 0, 0)
for i := 0; i < size; i++ {
value := data[i]
skip := true
for _, v := range uniqueData {
if reflect.DeepEqual(value, v) {
skip = false
break
}
}
if skip {
uniqueData = append(uniqueData, value)
}
}
l.data = uniqueData
}
// Union creates a new list contain all element in list l and other, remove duplicate element.
func (l *List[T]) Union(other *List[T]) *List[T] {
res := NewList([]T{})
res.data = append(res.data, l.data...)
res.data = append(res.data, other.data...)
res.Unique()
return res
}
// Intersection creates a new list whose element both be contained in list l and other
func (l *List[T]) Intersection(other *List[T]) *List[T] {
res := NewList(make([]T, 0, 0))
for _, v := range l.data {
if other.Contain(v) {
res.data = append(res.data, v)
}
}
return res
}

View File

@@ -1,272 +0,0 @@
package datastructure
import (
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestListData(t *testing.T) {
assert := internal.NewAssert(t, "TestListData")
list := NewList([]int{1, 2, 3})
assert.Equal([]int{1, 2, 3}, list.Data())
}
func TestValueOf(t *testing.T) {
assert := internal.NewAssert(t, "TestValueOf")
list := NewList([]int{1, 2, 3})
v, ok := list.ValueOf(0)
assert.Equal(1, *v)
assert.Equal(true, ok)
_, ok = list.ValueOf(3)
assert.Equal(false, ok)
}
func TestIndexOf(t *testing.T) {
assert := internal.NewAssert(t, "TestIndexOf")
list := NewList([]int{1, 2, 3})
i := list.IndexOf(1)
assert.Equal(0, i)
i = list.IndexOf(4)
assert.Equal(-1, i)
}
func TestContain(t *testing.T) {
assert := internal.NewAssert(t, "TestContain")
list := NewList([]int{1, 2, 3})
assert.Equal(true, list.Contain(1))
assert.Equal(false, list.Contain(0))
}
func TestPush(t *testing.T) {
assert := internal.NewAssert(t, "TestPush")
list := NewList([]int{1, 2, 3})
list.Push(4)
assert.Equal([]int{1, 2, 3, 4}, list.Data())
}
func TestInsertAtFirst(t *testing.T) {
assert := internal.NewAssert(t, "TestInsertAtFirst")
list := NewList([]int{1, 2, 3})
list.InsertAtFirst(0)
assert.Equal([]int{0, 1, 2, 3}, list.Data())
}
func TestInsertAtLast(t *testing.T) {
assert := internal.NewAssert(t, "TestInsertAtLast")
list := NewList([]int{1, 2, 3})
list.InsertAtLast(4)
assert.Equal([]int{1, 2, 3, 4}, list.Data())
}
func TestInsertAt(t *testing.T) {
assert := internal.NewAssert(t, "TestInsertAt")
list := NewList([]int{1, 2, 3})
list.InsertAt(-1, 0)
assert.Equal([]int{1, 2, 3}, list.Data())
list.InsertAt(4, 0)
assert.Equal([]int{1, 2, 3}, list.Data())
list.InsertAt(0, 0)
assert.Equal([]int{0, 1, 2, 3}, list.Data())
list.InsertAt(4, 4)
assert.Equal([]int{0, 1, 2, 3, 4}, list.Data())
}
func TestPopFirst(t *testing.T) {
assert := internal.NewAssert(t, "TestPopFirst")
list := NewList([]int{1, 2, 3})
v, ok := list.PopFirst()
assert.Equal(1, *v)
assert.Equal(true, ok)
assert.Equal([]int{2, 3}, list.Data())
list2 := NewList([]int{})
_, ok = list2.PopFirst()
assert.Equal(false, ok)
assert.Equal([]int{}, list2.Data())
}
func TestPopLast(t *testing.T) {
assert := internal.NewAssert(t, "TestPopLast")
list := NewList([]int{1, 2, 3})
v, ok := list.PopLast()
assert.Equal(3, *v)
assert.Equal(true, ok)
assert.Equal([]int{1, 2}, list.Data())
list2 := NewList([]int{})
_, ok = list2.PopLast()
assert.Equal(false, ok)
assert.Equal([]int{}, list2.Data())
}
func TestDeleteAt(t *testing.T) {
assert := internal.NewAssert(t, "TestDeleteAt")
list := NewList([]int{1, 2, 3, 4})
list.DeleteAt(-1)
assert.Equal([]int{1, 2, 3, 4}, list.Data())
list.DeleteAt(4)
assert.Equal([]int{1, 2, 3, 4}, list.Data())
list.DeleteAt(0)
assert.Equal([]int{2, 3, 4}, list.Data())
list.DeleteAt(2)
assert.Equal([]int{2, 3}, list.Data())
}
func TestUpdateAt(t *testing.T) {
assert := internal.NewAssert(t, "TestUpdateAt")
list := NewList([]int{1, 2, 3, 4})
list.UpdateAt(-1, 0)
assert.Equal([]int{1, 2, 3, 4}, list.Data())
list.UpdateAt(4, 0)
assert.Equal([]int{1, 2, 3, 4}, list.Data())
list.UpdateAt(0, 5)
assert.Equal([]int{5, 2, 3, 4}, list.Data())
list.UpdateAt(3, 1)
assert.Equal([]int{5, 2, 3, 1}, list.Data())
}
func TestEqutal(t *testing.T) {
assert := internal.NewAssert(t, "TestEqutal")
list1 := NewList([]int{1, 2, 3, 4})
list2 := NewList([]int{1, 2, 3, 4})
list3 := NewList([]int{1, 2, 3})
assert.Equal(true, list1.Equtal(list2))
assert.Equal(false, list1.Equtal(list3))
}
func TestIsEmpty(t *testing.T) {
assert := internal.NewAssert(t, "TestIsEmpty")
list1 := NewList([]int{1, 2, 3, 4})
list2 := NewList([]int{})
assert.Equal(false, list1.IsEmpty())
assert.Equal(true, list2.IsEmpty())
}
func TestIsClear(t *testing.T) {
assert := internal.NewAssert(t, "TestIsClear")
list1 := NewList([]int{1, 2, 3, 4})
list1.Clear()
empty := NewList([]int{})
assert.Equal(empty, list1)
}
func TestClone(t *testing.T) {
assert := internal.NewAssert(t, "TestClone")
list1 := NewList([]int{1, 2, 3, 4})
list2 := list1.Clone()
assert.Equal(true, list1.Equtal(list2))
}
func TestMerge(t *testing.T) {
assert := internal.NewAssert(t, "TestMerge")
list1 := NewList([]int{1, 2, 3, 4})
list2 := NewList([]int{4, 5, 6})
expected := NewList([]int{1, 2, 3, 4, 4, 5, 6})
list3 := list1.Merge(list2)
assert.Equal(true, expected.Equtal(list3))
}
func TestSize(t *testing.T) {
assert := internal.NewAssert(t, "TestSize")
list := NewList([]int{1, 2, 3, 4})
empty := NewList([]int{})
assert.Equal(4, list.Size())
assert.Equal(0, empty.Size())
}
func TestSwap(t *testing.T) {
assert := internal.NewAssert(t, "TestSwap")
list := NewList([]int{1, 2, 3, 4})
expected := NewList([]int{4, 2, 3, 1})
list.Swap(0, 3)
assert.Equal(true, expected.Equtal(list))
}
func TestReverse(t *testing.T) {
assert := internal.NewAssert(t, "TestReverse")
list := NewList([]int{1, 2, 3, 4})
expected := NewList([]int{4, 3, 2, 1})
list.Reverse()
assert.Equal(true, expected.Equtal(list))
}
func TestUnique(t *testing.T) {
assert := internal.NewAssert(t, "TestUnique")
list := NewList([]int{1, 2, 2, 3, 4})
expected := NewList([]int{1, 2, 3, 4})
list.Unique()
assert.Equal(true, expected.Equtal(list))
}
func TestUnion(t *testing.T) {
assert := internal.NewAssert(t, "TestUnion")
list1 := NewList([]int{1, 2, 3, 4})
list2 := NewList([]int{4, 5, 6})
expected := NewList([]int{1, 2, 3, 4, 5, 6})
list3 := list1.Union(list2)
assert.Equal(true, expected.Equtal(list3))
}
func TestIntersection(t *testing.T) {
assert := internal.NewAssert(t, "TestIntersection")
list1 := NewList([]int{1, 2, 3, 4})
list2 := NewList([]int{4, 5, 6})
expected := NewList([]int{4})
list3 := list1.Intersection(list2)
assert.Equal(true, expected.Equtal(list3))
}

View File

@@ -1,51 +0,0 @@
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
// Use of this source code is governed by MIT license
// Package datastructure implements some data structure. eg. list, linklist, stack, queue, tree, graph.
package datastructure
// LinkNode is a linkedlist node, which have a Value and Pre points to previous node, Next points to a next node of the link.
type LinkNode[T any] struct {
Value T
Pre *LinkNode[T]
Next *LinkNode[T]
}
// NewLinkNode return a LinkNode pointer
func NewLinkNode[T any](value T) *LinkNode[T] {
return &LinkNode[T]{value, nil, nil}
}
// StackNode is a node in stack, which have a Value and Next pointer points to next node in the stack.
type StackNode[T any] struct {
Value T
Next *StackNode[T]
}
// NewStackNode return a StackNode pointer
func NewStackNode[T any](value T) *StackNode[T] {
return &StackNode[T]{value, nil}
}
// QueueNode is a node in a queue, which have a Value and Next pointer points to next node in the queue.
type QueueNode[T any] struct {
Value T
Next *QueueNode[T]
}
// NewQueueNode return a QueueNode pointer
func NewQueueNode[T any](value T) *QueueNode[T] {
return &QueueNode[T]{value, nil}
}
// TreeNode is node of tree
type TreeNode[T any] struct {
Data T
Left *TreeNode[T]
Right *TreeNode[T]
}
// NewTreeNode return a TreeNode pointer
func NewTreeNode[T any](data T) *TreeNode[T] {
return &TreeNode[T]{data, nil, nil}
}

View File

@@ -1,92 +0,0 @@
package datastructure
import (
"errors"
"fmt"
"reflect"
)
// ArrayQueue implements queue with slice
type ArrayQueue[T any] struct {
data []T
length int
}
// NewArrayQueue return a empty ArrayQueue pointer
func NewArrayQueue[T any](values ...T) *ArrayQueue[T] {
data := make([]T, len(values))
for i, v := range values {
data[i] = v
}
return &ArrayQueue[T]{data: data, length: len(values)}
}
// Data return queue data
func (q *ArrayQueue[T]) Data() []T {
return q.data
}
// Size return length of queue data
func (q *ArrayQueue[T]) Size() int {
return q.length
}
// IsEmpty checks if queue is empty or not
func (q *ArrayQueue[T]) IsEmpty() bool {
return q.length == 0
}
// Front return front value of queue
func (q *ArrayQueue[T]) Front() T {
return q.data[0]
}
// Back return back value of queue
func (q *ArrayQueue[T]) Back() T {
return q.data[q.length-1]
}
// EnQueue put element into queue
func (q *ArrayQueue[T]) EnQueue(value T) {
q.data = append(q.data, value)
q.length++
}
// DeQueue remove head element of queue and return it, if queue is empty, return nil and error
func (q *ArrayQueue[T]) DeQueue() (*T, error) {
if q.IsEmpty() {
return nil, errors.New("queue is empty")
}
headItem := q.data[0]
q.data = q.data[1:]
q.length--
return &headItem, nil
}
// Clear the queue data
func (q *ArrayQueue[T]) Clear() {
q.data = []T{}
q.length = 0
}
// Contain checks if the value is in queue or not
func (q *ArrayQueue[T]) Contain(value T) bool {
for _, v := range q.data {
if reflect.DeepEqual(v, value) {
return true
}
}
return false
}
// Print queue data
func (q *ArrayQueue[T]) Print() {
info := "["
for _, v := range q.data {
info += fmt.Sprintf("%+v, ", v)
}
info += "]"
fmt.Println(info)
}

View File

@@ -1,90 +0,0 @@
package datastructure
import (
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestArrayQueue_EnQueue(t *testing.T) {
assert := internal.NewAssert(t, "TestArrayQueue_EnQueue")
queue := NewArrayQueue[int]()
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
expected := []int{1, 2, 3}
data := queue.Data()
size := queue.Size()
queue.Print()
assert.Equal(expected, data)
assert.Equal(3, size)
}
func TestArrayQueue_DeQueue(t *testing.T) {
assert := internal.NewAssert(t, "TestArrayQueue_DeQueue")
queue := NewArrayQueue(1, 2, 3)
val, err := queue.DeQueue()
if err != nil {
t.Fail()
}
queue.Print()
assert.Equal(1, *val)
assert.Equal([]int{2, 3}, queue.Data())
}
func TestArrayQueue_Front(t *testing.T) {
assert := internal.NewAssert(t, "TestArrayQueue_Front")
queue := NewArrayQueue(1, 2, 3)
val := queue.Front()
queue.Print()
assert.Equal(1, val)
assert.Equal([]int{1, 2, 3}, queue.Data())
}
func TestArrayQueue_Back(t *testing.T) {
assert := internal.NewAssert(t, "TestArrayQueue_Back")
queue := NewArrayQueue(1, 2, 3)
val := queue.Back()
queue.Print()
assert.Equal(3, val)
assert.Equal([]int{1, 2, 3}, queue.Data())
}
func TestArrayQueue_Contain(t *testing.T) {
assert := internal.NewAssert(t, "TestArrayQueue_Contain")
queue := NewArrayQueue(1, 2, 3)
assert.Equal(true, queue.Contain(1))
assert.Equal(false, queue.Contain(4))
}
func TestArrayQueue_Clear(t *testing.T) {
assert := internal.NewAssert(t, "TestArrayQueue_Clear")
queue := NewArrayQueue[int]()
assert.Equal(true, queue.IsEmpty())
assert.Equal(0, queue.Size())
queue.EnQueue(1)
assert.Equal(false, queue.IsEmpty())
assert.Equal(1, queue.Size())
queue.Clear()
assert.Equal(true, queue.IsEmpty())
assert.Equal(0, queue.Size())
}

View File

@@ -1,118 +0,0 @@
package datastructure
import (
"errors"
"fmt"
"reflect"
)
// CircularQueue implements circular queue with slice,
// last index of CircularQueue don't contain value, so acturl capacity is size - 1
type CircularQueue[T any] struct {
data []T
front int
rear int
size int
}
// NewCircularQueue return a empty CircularQueue pointer
func NewCircularQueue[T any](size int) *CircularQueue[T] {
data := make([]T, size)
return &CircularQueue[T]{data: data, front: 0, rear: 0, size: size}
}
// Data return queue data
func (q *CircularQueue[T]) Data() []T {
data := []T{}
front := q.front
rear := q.rear
if front <= rear {
return q.data[front:rear]
}
data = append(data, q.data[front:]...)
data = append(data, q.data[0:rear]...)
return data
}
// Length return current data length of queue
func (q *CircularQueue[T]) Length() int {
if q.size == 0 {
return 0
}
return (q.rear - q.front + q.size) % q.size
}
// IsEmpty checks if queue is empty or not
func (q *CircularQueue[T]) IsEmpty() bool {
return q.front == q.rear
}
// IsFull checks if queue is full or not
func (q *CircularQueue[T]) IsFull() bool {
return (q.rear+1)%q.size == q.front
}
// Front return front value of queue
func (q *CircularQueue[T]) Front() T {
return q.data[q.front]
}
// Back return back value of queue
func (q *CircularQueue[T]) Back() T {
if q.rear-1 >= 0 {
return q.data[q.rear-1]
}
return q.data[q.size-1]
}
// EnQueue put element into queue
func (q *CircularQueue[T]) EnQueue(value T) error {
if q.IsFull() {
return errors.New("queue is full!")
}
q.data[q.rear] = value
q.rear = (q.rear + 1) % q.size
return nil
}
// DeQueue remove head element of queue and return it, if queue is empty, return nil and error
func (q *CircularQueue[T]) DeQueue() (*T, error) {
if q.IsEmpty() {
return nil, errors.New("queue is empty")
}
headItem := q.data[q.front]
var t T
q.data[q.front] = t
q.front = (q.front + 1) % q.size
return &headItem, nil
}
// Clear the queue data
func (q *CircularQueue[T]) Clear() {
q.data = []T{}
q.front = 0
q.rear = 0
q.size = 0
}
// Contain checks if the value is in queue or not
func (q *CircularQueue[T]) Contain(value T) bool {
for _, v := range q.data {
if reflect.DeepEqual(v, value) {
return true
}
}
return false
}
// Print queue data
func (q *CircularQueue[T]) Print() {
fmt.Printf("%+v\n", q)
}

View File

@@ -1,148 +0,0 @@
package datastructure
import (
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestCircularQueue_EnQueue(t *testing.T) {
assert := internal.NewAssert(t, "TestCircularQueue_EnQueue")
queue := NewCircularQueue[int](6)
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
queue.EnQueue(4)
queue.EnQueue(5)
queue.Print()
// assert.Equal([]int{1, 2, 3, 4, 5}, queue.Data())
assert.Equal(5, queue.Length())
err := queue.EnQueue(6)
assert.IsNotNil(err)
}
func TestCircularQueue_DeQueue(t *testing.T) {
assert := internal.NewAssert(t, "TestCircularQueue_DeQueue")
queue := NewCircularQueue[int](6)
assert.Equal(true, queue.IsEmpty())
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
queue.EnQueue(4)
queue.EnQueue(5)
val, err := queue.DeQueue()
assert.IsNil(err)
assert.Equal(1, *val)
assert.Equal(false, queue.IsFull())
val, _ = queue.DeQueue()
queue.Print()
assert.Equal(2, *val)
queue.EnQueue(6)
queue.Print()
assert.Equal(false, queue.IsFull())
}
func TestCircularQueue_Front(t *testing.T) {
assert := internal.NewAssert(t, "TestCircularQueue_Front")
queue := NewCircularQueue[int](6)
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
queue.EnQueue(4)
queue.EnQueue(5)
queue.Print()
queue.DeQueue()
queue.DeQueue()
queue.EnQueue(6)
queue.EnQueue(7)
queue.Print()
val := queue.Front()
assert.Equal(3, val)
assert.Equal(5, queue.Length())
}
func TestCircularQueue_Back(t *testing.T) {
assert := internal.NewAssert(t, "TestCircularQueue_Back")
queue := NewCircularQueue[int](6)
assert.Equal(true, queue.IsEmpty())
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
queue.EnQueue(4)
queue.EnQueue(5)
queue.Print()
assert.Equal(5, queue.Back())
queue.DeQueue()
queue.DeQueue()
queue.EnQueue(6)
queue.EnQueue(7)
queue.Print()
assert.Equal(7, queue.Back())
}
func TestCircularQueue_Contain(t *testing.T) {
assert := internal.NewAssert(t, "TestCircularQueue_Contain")
queue := NewCircularQueue[int](2)
queue.EnQueue(1)
assert.Equal(true, queue.Contain(1))
assert.Equal(false, queue.Contain(2))
}
func TestCircularQueue_Clear(t *testing.T) {
assert := internal.NewAssert(t, "TestCircularQueue_Clear")
queue := NewCircularQueue[int](3)
assert.Equal(true, queue.IsEmpty())
assert.Equal(0, queue.Length())
queue.EnQueue(1)
assert.Equal(false, queue.IsEmpty())
assert.Equal(1, queue.Length())
queue.Clear()
assert.Equal(true, queue.IsEmpty())
assert.Equal(0, queue.Length())
}
func TestCircularQueue_Data(t *testing.T) {
assert := internal.NewAssert(t, "TestCircularQueue_Data")
queue := NewCircularQueue[int](6)
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
queue.EnQueue(4)
queue.EnQueue(5)
queue.Print()
assert.Equal([]int{1, 2, 3, 4, 5}, queue.Data())
queue.DeQueue()
queue.DeQueue()
queue.EnQueue(6)
queue.EnQueue(7)
queue.Print()
assert.Equal([]int{3, 4, 5, 6, 7}, queue.Data())
}

View File

@@ -1,104 +0,0 @@
package datastructure
import (
"errors"
"fmt"
"github.com/duke-git/lancet/v2/datastructure"
)
// LinkedQueue implements queue with link list
type LinkedQueue[T any] struct {
head *datastructure.QueueNode[T]
tail *datastructure.QueueNode[T]
length int
}
// NewLinkedQueue return a empty LinkedQueue pointer
func NewLinkedQueue[T any]() *LinkedQueue[T] {
return &LinkedQueue[T]{head: nil, tail: nil, length: 0}
}
// Data return queue data
func (q *LinkedQueue[T]) Data() []T {
res := []T{}
current := q.head
for current != nil {
res = append(res, current.Value)
current = current.Next
}
return res
}
// Size return length of queue data
func (q *LinkedQueue[T]) Size() int {
return q.length
}
// IsEmpty checks if queue is empty or not
func (q *LinkedQueue[T]) IsEmpty() bool {
return q.length == 0
}
// EnQueue add element into queue
func (q *LinkedQueue[T]) EnQueue(value T) {
newNode := datastructure.NewQueueNode(value)
if q.IsEmpty() {
q.head = newNode
q.tail = newNode
} else {
q.tail.Next = newNode
q.tail = newNode
}
q.length++
}
// DeQueue delete head element of queue then return it, if queue is empty, return nil and error
func (q *LinkedQueue[T]) DeQueue() (*T, error) {
if q.IsEmpty() {
return nil, errors.New("queue is empty")
}
head := q.head
q.head = q.head.Next
q.length--
return &head.Value, nil
}
// Front return front value of queue
func (q *LinkedQueue[T]) Front() (*T, error) {
if q.IsEmpty() {
return nil, errors.New("queue is empty")
}
return &q.head.Value, nil
}
// Back return back value of queue
func (q *LinkedQueue[T]) Back() (*T, error) {
if q.IsEmpty() {
return nil, errors.New("queue is empty")
}
return &q.tail.Value, nil
}
// Clear clear the queue data
func (q *LinkedQueue[T]) Clear() {
q.head = nil
q.tail = nil
q.length = 0
}
// Print all nodes info of queue link
func (q *LinkedQueue[T]) Print() {
current := q.head
info := "[ "
for current != nil {
info += fmt.Sprintf("%+v, ", current)
current = current.Next
}
info += " ]"
fmt.Println(info)
}

View File

@@ -1,84 +0,0 @@
package datastructure
import (
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestLinkedQueue_EnQueue(t *testing.T) {
assert := internal.NewAssert(t, "TestLinkedQueue_EnQueue")
queue := NewLinkedQueue[int]()
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
queue.Print()
assert.Equal([]int{1, 2, 3}, queue.Data())
assert.Equal(3, queue.Size())
}
func TestLinkedQueue_DeQueue(t *testing.T) {
assert := internal.NewAssert(t, "TestLinkedQueue_DeQueue")
queue := NewLinkedQueue[int]()
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
val, _ := queue.DeQueue()
queue.Print()
assert.Equal([]int{2, 3}, queue.Data())
assert.Equal(1, *val)
}
func TestLinkedQueue_Front(t *testing.T) {
assert := internal.NewAssert(t, "TestLinkedQueue_Front")
queue := NewLinkedQueue[int]()
_, err := queue.Front()
assert.IsNotNil(err)
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
val, err := queue.Front()
assert.Equal(1, *val)
assert.IsNil(err)
}
func TestLinkedQueue_Back(t *testing.T) {
assert := internal.NewAssert(t, "TestLinkedQueue_Back")
queue := NewLinkedQueue[int]()
_, err := queue.Back()
assert.IsNotNil(err)
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
val, err := queue.Back()
assert.Equal(3, *val)
assert.IsNil(err)
}
func TestLinkedQueue_Clear(t *testing.T) {
assert := internal.NewAssert(t, "TestLinkedQueue_Back")
queue := NewLinkedQueue[int]()
assert.Equal(true, queue.IsEmpty())
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
assert.Equal(false, queue.IsEmpty())
queue.Clear()
assert.Equal(true, queue.IsEmpty())
}

View File

@@ -1,136 +0,0 @@
package datastructure
// Set is a data container, like slice, but element of set is not duplicate
type Set[T comparable] map[T]bool
// NewSet return a instance of set
func NewSet[T comparable](values ...T) Set[T] {
set := make(Set[T])
set.Add(values...)
return set
}
// Add value to set
func (s Set[T]) Add(values ...T) {
for _, v := range values {
s[v] = true
}
}
// Contain checks if set contains value or not
func (s Set[T]) Contain(value T) bool {
_, ok := s[value]
return ok
}
// Contain checks if set contains other set
func (s Set[T]) ContainAll(other Set[T]) bool {
for k := range other {
_, ok := s[k]
if !ok {
return false
}
}
return true
}
// Clone return a copy of set
func (s Set[T]) Clone() Set[T] {
set := NewSet[T]()
set.Add(s.Values()...)
return set
}
// Delete value of set
func (s Set[T]) Delete(values ...T) {
for _, v := range values {
delete(s, v)
}
}
// Equal checks if two set has same elements or not
func (s Set[T]) Equal(other Set[T]) bool {
if s.Size() != other.Size() {
return false
}
return s.ContainAll(other) && other.ContainAll(s)
}
// Iterate call function by every element of set
func (s Set[T]) Iterate(fn func(value T)) {
for v := range s {
fn(v)
}
}
// IsEmpty checks the set is empty or not
func (s Set[T]) IsEmpty() bool {
return len(s) == 0
}
// Size get the number of elements in set
func (s Set[T]) Size() int {
return len(s)
}
// Values return all values of set
func (s Set[T]) Values() []T {
values := make([]T, 0, 0)
s.Iterate(func(value T) {
values = append(values, value)
})
return values
}
// Union creates a new set contain all element of set s and other
func (s Set[T]) Union(other Set[T]) Set[T] {
set := s.Clone()
set.Add(other.Values()...)
return set
}
// Intersection creates a new set whose element both be contained in set s and other
func (s Set[T]) Intersection(other Set[T]) Set[T] {
set := NewSet[T]()
s.Iterate(func(value T) {
if other.Contain(value) {
set.Add(value)
}
})
return set
}
// SymmetricDifference creates a new set whose element is in set1 or set2, but not in both sets
func (s Set[T]) SymmetricDifference(other Set[T]) Set[T] {
set := NewSet[T]()
s.Iterate(func(value T) {
if !other.Contain(value) {
set.Add(value)
}
})
other.Iterate(func(value T) {
if !s.Contain(value) {
set.Add(value)
}
})
return set
}
// Minus creates an set of whose element in origin set but not in compared set
func (s Set[T]) Minus(comparedSet Set[T]) Set[T] {
set := NewSet[T]()
s.Iterate(func(value T) {
if !comparedSet.Contain(value) {
set.Add(value)
}
})
return set
}

View File

@@ -1,149 +0,0 @@
package datastructure
import (
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestSet_Add(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_Add")
set := NewSet[int]()
set.Add(1, 2, 3)
expected := NewSet(1, 2, 3)
assert.Equal(true, set.Equal(expected))
}
func TestSet_Contain(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_Contain")
set := NewSet[int]()
set.Add(1, 2, 3)
assert.Equal(true, set.Contain(1))
assert.Equal(false, set.Contain(4))
}
func TestSet_ContainAll(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_ContainAll")
set1 := NewSet(1, 2, 3)
set2 := NewSet(1, 2)
set3 := NewSet(1, 2, 3, 4)
assert.Equal(true, set1.ContainAll(set2))
assert.Equal(false, set1.ContainAll(set3))
}
func TestSet_Clone(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_Clone")
set1 := NewSet(1, 2, 3)
set2 := set1.Clone()
assert.Equal(true, set1.Size() == set2.Size())
assert.Equal(true, set1.ContainAll(set2))
}
func TestSet_Delete(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_Delete")
set := NewSet[int]()
set.Add(1, 2, 3)
set.Delete(3)
expected := NewSet(1, 2)
assert.Equal(true, set.Equal(expected))
}
func TestSet_Equal(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_Equal")
set1 := NewSet(1, 2, 3)
set2 := NewSet(1, 2, 3)
set3 := NewSet(1, 2, 3, 4)
assert.Equal(true, set1.Equal(set2))
assert.Equal(false, set1.Equal(set3))
}
func TestSet_Iterate(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_Iterate")
set := NewSet(1, 2, 3)
arr := []int{}
set.Iterate(func(value int) {
arr = append(arr, value)
})
assert.Equal(3, len(arr))
}
func TestSet_IsEmpty(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_IsEmpty")
set := NewSet[int]()
assert.Equal(true, set.IsEmpty())
}
func TestSet_Size(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_Size")
set := NewSet(1, 2, 3)
assert.Equal(3, set.Size())
}
func TestSet_Values(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_Values")
set := NewSet(1, 2, 3)
values := set.Values()
assert.Equal(3, len(values))
}
func TestSet_Union(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_Union")
set1 := NewSet(1, 2, 3)
set2 := NewSet(2, 3, 4, 5)
expected := NewSet(1, 2, 3, 4, 5)
unionSet := set1.Union(set2)
assert.Equal(expected, unionSet)
}
func TestSet_Intersection(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_Intersection")
set1 := NewSet(1, 2, 3)
set2 := NewSet(2, 3, 4, 5)
expected := NewSet(2, 3)
intersectionSet := set1.Intersection(set2)
assert.Equal(expected, intersectionSet)
}
func TestSet_SymmetricDifference(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_SymmetricDifference")
set1 := NewSet(1, 2, 3)
set2 := NewSet(2, 3, 4, 5)
assert.Equal(NewSet(1, 4, 5), set1.SymmetricDifference(set2))
}
func TestSet_Minus(t *testing.T) {
assert := internal.NewAssert(t, "TestSet_Minus")
set1 := NewSet(1, 2, 3)
set2 := NewSet(2, 3, 4, 5)
set3 := NewSet(2, 3)
assert.Equal(NewSet(1), set1.Minus(set2))
assert.Equal(NewSet(4, 5), set2.Minus(set3))
}

View File

@@ -1,62 +0,0 @@
package datastructure
import "errors"
// ArrayStack implements stack with slice
type ArrayStack[T any] struct {
data []T
length int
}
// NewArrayStack return a empty ArrayStack pointer
func NewArrayStack[T any]() *ArrayStack[T] {
return &ArrayStack[T]{data: []T{}, length: 0}
}
// Data return stack data
func (s *ArrayStack[T]) Data() []T {
return s.data
}
// Size return length of stack data
func (s *ArrayStack[T]) Size() int {
return s.length
}
// IsEmpty checks if stack is empty or not
func (s *ArrayStack[T]) IsEmpty() bool {
return s.length == 0
}
// Push element into stack
func (s *ArrayStack[T]) Push(value T) {
s.data = append([]T{value}, s.data...)
s.length++
}
// Pop delete the top element of stack then return it, if stack is empty, return nil and error
func (s *ArrayStack[T]) Pop() (*T, error) {
if s.IsEmpty() {
return nil, errors.New("stack is empty")
}
topItem := s.data[0]
s.data = s.data[1:]
s.length--
return &topItem, nil
}
// Peak return the top element of stack then return it
func (s *ArrayStack[T]) Peak() (*T, error) {
if s.IsEmpty() {
return nil, errors.New("stack is empty")
}
return &s.data[0], nil
}
// Clear the stack data
func (s *ArrayStack[T]) Clear() {
s.data = []T{}
s.length = 0
}

View File

@@ -1,77 +0,0 @@
package datastructure
import (
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestArrayStack_Push(t *testing.T) {
assert := internal.NewAssert(t, "TestArrayStack_Push")
stack := NewArrayStack[int]()
stack.Push(1)
stack.Push(2)
stack.Push(3)
expected := []int{3, 2, 1}
values := stack.Data()
length := stack.Size()
assert.Equal(expected, values)
assert.Equal(3, length)
}
func TestArrayStack_Pop(t *testing.T) {
assert := internal.NewAssert(t, "TestArrayStack_Pop")
stack := NewArrayStack[int]()
_, err := stack.Pop()
assert.IsNotNil(err)
stack.Push(1)
stack.Push(2)
stack.Push(3)
topItem, err := stack.Pop()
assert.IsNil(err)
assert.Equal(3, *topItem)
expected := []int{2, 1}
assert.Equal(expected, stack.Data())
}
func TestArrayStack_Peak(t *testing.T) {
assert := internal.NewAssert(t, "TestArrayStack_Peak")
stack := NewArrayStack[int]()
_, err := stack.Peak()
assert.IsNotNil(err)
stack.Push(1)
stack.Push(2)
stack.Push(3)
topItem, err := stack.Peak()
assert.IsNil(err)
assert.Equal(3, *topItem)
expected := []int{3, 2, 1}
assert.Equal(expected, stack.Data())
}
func TestArrayStack_Clear(t *testing.T) {
assert := internal.NewAssert(t, "TestArrayStack_Clear")
stack := NewArrayStack[int]()
assert.Equal(true, stack.IsEmpty())
assert.Equal(0, stack.Size())
stack.Push(1)
assert.Equal(false, stack.IsEmpty())
assert.Equal(1, stack.Size())
stack.Clear()
assert.Equal(true, stack.IsEmpty())
assert.Equal(0, stack.Size())
}

View File

@@ -1,94 +0,0 @@
package datastructure
import (
"errors"
"fmt"
"github.com/duke-git/lancet/v2/datastructure"
)
// LinkedStack implements stack with link list
type LinkedStack[T any] struct {
top *datastructure.StackNode[T]
length int
}
// NewLinkedStack return a empty LinkedStack pointer
func NewLinkedStack[T any]() *LinkedStack[T] {
return &LinkedStack[T]{top: nil, length: 0}
}
// Data return stack data
func (s *LinkedStack[T]) Data() []T {
res := []T{}
current := s.top
for current != nil {
res = append(res, current.Value)
current = current.Next
}
return res
}
// Size return length of stack data
func (s *LinkedStack[T]) Size() int {
return s.length
}
// IsEmpty checks if stack is empty or not
func (s *LinkedStack[T]) IsEmpty() bool {
return s.length == 0
}
// Push element into stack
func (s *LinkedStack[T]) Push(value T) {
newNode := datastructure.NewStackNode(value)
top := s.top
if top == nil {
s.top = newNode
} else {
newNode.Next = top
s.top = newNode
}
s.length++
}
// Pop delete the top element of stack then return it, if stack is empty, return nil and error
func (s *LinkedStack[T]) Pop() (*T, error) {
if s.IsEmpty() {
return nil, errors.New("stack is empty")
}
top := s.top
s.top = s.top.Next
s.length--
return &top.Value, nil
}
// Peak return the top element of stack then return it
func (s *LinkedStack[T]) Peak() (*T, error) {
if s.IsEmpty() {
return nil, errors.New("stack is empty")
}
return &s.top.Value, nil
}
// Clear clear the stack data
func (s *LinkedStack[T]) Clear() {
s.top = nil
s.length = 0
}
// Print all nodes info of stack link
func (s *LinkedStack[T]) Print() {
current := s.top
info := "[ "
for current != nil {
info += fmt.Sprintf("%+v, ", current)
current = current.Next
}
info += " ]"
fmt.Println(info)
}

View File

@@ -1,80 +0,0 @@
package datastructure
import (
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestLinkedStack_Push(t *testing.T) {
assert := internal.NewAssert(t, "TestLinkedStack_Push")
stack := NewLinkedStack[int]()
stack.Push(1)
stack.Push(2)
stack.Push(3)
stack.Print()
expected := []int{3, 2, 1}
values := stack.Data()
size := stack.Size()
assert.Equal(expected, values)
assert.Equal(3, size)
}
func TestLinkedStack_Pop(t *testing.T) {
assert := internal.NewAssert(t, "TestLinkedStack_Pop")
stack := NewLinkedStack[int]()
_, err := stack.Pop()
assert.IsNotNil(err)
stack.Push(1)
stack.Push(2)
stack.Push(3)
topItem, err := stack.Pop()
assert.IsNil(err)
assert.Equal(3, *topItem)
expected := []int{2, 1}
stack.Print()
assert.Equal(expected, stack.Data())
}
func TestLinkedStack_Peak(t *testing.T) {
assert := internal.NewAssert(t, "TestLinkedStack_Peak")
stack := NewLinkedStack[int]()
_, err := stack.Peak()
assert.IsNotNil(err)
stack.Push(1)
stack.Push(2)
stack.Push(3)
topItem, err := stack.Peak()
assert.IsNil(err)
assert.Equal(3, *topItem)
expected := []int{3, 2, 1}
assert.Equal(expected, stack.Data())
}
func TestLinkedStack_Empty(t *testing.T) {
assert := internal.NewAssert(t, "TestLinkedStack_Empty")
stack := NewLinkedStack[int]()
assert.Equal(true, stack.IsEmpty())
assert.Equal(0, stack.Size())
stack.Push(1)
assert.Equal(false, stack.IsEmpty())
assert.Equal(1, stack.Size())
stack.Clear()
assert.Equal(true, stack.IsEmpty())
assert.Equal(0, stack.Size())
}

View File

@@ -1,83 +0,0 @@
package datastructure
import (
"math"
"github.com/duke-git/lancet/v2/datastructure"
"github.com/duke-git/lancet/v2/lancetconstraints"
)
// BSTree is a binary search tree data structure in which each node has at most two children,
// which are referred to as the left child and the right child.
// In BSTree: leftNode < rootNode < rightNode
// type T should implements Compare function in lancetconstraints.Comparator interface.
type BSTree[T any] struct {
root *datastructure.TreeNode[T]
}
// NewBSTree create a BSTree pointer
func NewBSTree[T any](rootData T) *BSTree[T] {
root := datastructure.NewTreeNode(rootData)
return &BSTree[T]{root}
}
// InsertNode insert data into BSTree
func (t *BSTree[T]) InsertNode(data T, comparator lancetconstraints.Comparator) {
root := t.root
newNode := datastructure.NewTreeNode(data)
if root == nil {
t.root = newNode
} else {
insertTreeNode(root, newNode, comparator)
}
}
// DeletetNode delete data into BSTree
func (t *BSTree[T]) DeletetNode(data T, comparator lancetconstraints.Comparator) {
deleteTreeNode(t.root, data, comparator)
}
// NodeLevel get node level in BSTree
func (t *BSTree[T]) NodeLevel(node *datastructure.TreeNode[T]) int {
if node == nil {
return 0
}
left := float64(t.NodeLevel(node.Left))
right := float64(t.NodeLevel(node.Right))
return int(math.Max(left, right)) + 1
}
// PreOrderTraverse traverse tree node in pre order
func (t *BSTree[T]) PreOrderTraverse() []T {
return preOrderTraverse(t.root)
}
// PostOrderTraverse traverse tree node in post order
func (t *BSTree[T]) PostOrderTraverse() []T {
return postOrderTraverse(t.root)
}
// InOrderTraverse traverse tree node in mid order
func (t *BSTree[T]) InOrderTraverse() []T {
return inOrderTraverse(t.root)
}
// LevelOrderTraverse traverse tree node in level order
func (t *BSTree[T]) LevelOrderTraverse() []T {
traversal := make([]T, 0)
levelOrderTraverse(t.root, &traversal)
return traversal
}
// Depth returns the calculated depth of a binary saerch tree
func (t *BSTree[T]) Depth() int {
return calculateDepth(t.root, 0)
}
// Print the bstree structure
func (t *BSTree[T]) Print() {
maxLevel := t.NodeLevel(t.root)
nodes := []*datastructure.TreeNode[T]{t.root}
printTreeNodes(nodes, 1, maxLevel)
}

View File

@@ -1,142 +0,0 @@
package datastructure
import (
"testing"
"github.com/duke-git/lancet/v2/internal"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func TestBSTree_InsertNode(t *testing.T) {
bstree := NewBSTree(6)
comparator := &intComparator{}
bstree.InsertNode(7, comparator)
bstree.InsertNode(5, comparator)
bstree.InsertNode(2, comparator)
bstree.InsertNode(4, comparator)
bstree.Print()
}
func TestBSTree_PreOrderTraverse(t *testing.T) {
assert := internal.NewAssert(t, "TestBSTree_PreOrderTraverse")
bstree := NewBSTree(6)
comparator := &intComparator{}
bstree.InsertNode(7, comparator)
bstree.InsertNode(5, comparator)
bstree.InsertNode(2, comparator)
bstree.InsertNode(4, comparator)
acturl := bstree.PreOrderTraverse()
t.Log(acturl)
assert.Equal([]int{6, 5, 2, 4, 7}, acturl)
}
func TestBSTree_PostOrderTraverse(t *testing.T) {
assert := internal.NewAssert(t, "TestBSTree_PostOrderTraverse")
bstree := NewBSTree(6)
comparator := &intComparator{}
bstree.InsertNode(7, comparator)
bstree.InsertNode(5, comparator)
bstree.InsertNode(2, comparator)
bstree.InsertNode(4, comparator)
acturl := bstree.PostOrderTraverse()
t.Log(acturl)
assert.Equal([]int{5, 2, 4, 7, 6}, acturl)
}
func TestBSTree_InOrderTraverse(t *testing.T) {
assert := internal.NewAssert(t, "TestBSTree_InOrderTraverse")
bstree := NewBSTree(6)
comparator := &intComparator{}
bstree.InsertNode(7, comparator)
bstree.InsertNode(5, comparator)
bstree.InsertNode(2, comparator)
bstree.InsertNode(4, comparator)
acturl := bstree.InOrderTraverse()
t.Log(acturl)
assert.Equal([]int{2, 4, 5, 6, 7}, acturl)
}
func TestBSTree_LevelOrderTraverse(t *testing.T) {
assert := internal.NewAssert(t, "TestBSTree_LevelOrderTraverse")
bstree := NewBSTree(6)
comparator := &intComparator{}
bstree.InsertNode(7, comparator)
bstree.InsertNode(5, comparator)
bstree.InsertNode(2, comparator)
bstree.InsertNode(4, comparator)
bstree.Print()
acturl := bstree.LevelOrderTraverse()
t.Log(acturl)
assert.Equal([]int{6, 5, 7, 2, 4}, acturl)
}
func TestBSTree_DeletetNode(t *testing.T) {
assert := internal.NewAssert(t, "TestBSTree_DeletetNode")
bstree := NewBSTree(6)
comparator := &intComparator{}
bstree.InsertNode(7, comparator)
bstree.InsertNode(5, comparator)
bstree.InsertNode(2, comparator)
bstree.InsertNode(4, comparator)
bstree.Print()
bstree.DeletetNode(4, comparator)
bstree.Print()
acturl1 := bstree.InOrderTraverse()
t.Log(acturl1)
assert.Equal([]int{2, 5, 6, 7}, acturl1)
//todo
// bstree.DeletetNode(6, comparator)
// bstree.Print()
// acturl2 := bstree.InOrderTraverse()
// t.Log(acturl2)
// assert.Equal([]int{2, 5, 7}, acturl2)
}
func TestBSTree_Depth(t *testing.T) {
assert := internal.NewAssert(t, "TestBSTree_Depth")
bstree := NewBSTree(6)
comparator := &intComparator{}
bstree.InsertNode(7, comparator)
bstree.InsertNode(5, comparator)
bstree.InsertNode(2, comparator)
bstree.InsertNode(4, comparator)
bstree.Print()
assert.Equal(bstree.Depth(), 4)
}

View File

@@ -1,224 +0,0 @@
package datastructure
import (
"fmt"
"math"
"github.com/duke-git/lancet/v2/datastructure"
"github.com/duke-git/lancet/v2/lancetconstraints"
)
func preOrderTraverse[T any](node *datastructure.TreeNode[T]) []T {
data := []T{}
if node != nil {
data = append(data, node.Data)
data = append(data, preOrderTraverse(node.Left)...)
data = append(data, preOrderTraverse(node.Right)...)
}
return data
}
func postOrderTraverse[T any](node *datastructure.TreeNode[T]) []T {
data := []T{}
if node != nil {
data = append(data, preOrderTraverse(node.Left)...)
data = append(data, preOrderTraverse(node.Right)...)
data = append(data, node.Data)
}
return data
}
func inOrderTraverse[T any](node *datastructure.TreeNode[T]) []T {
data := []T{}
if node != nil {
data = append(data, inOrderTraverse(node.Left)...)
data = append(data, node.Data)
data = append(data, inOrderTraverse(node.Right)...)
}
return data
}
func preOrderPrint[T any](node *datastructure.TreeNode[T]) {
if node == nil {
return
}
fmt.Printf("%v, ", node.Data)
preOrderPrint(node.Left)
preOrderPrint(node.Right)
}
func postOrderPrint[T any](node *datastructure.TreeNode[T]) {
if node == nil {
return
}
preOrderPrint(node.Left)
preOrderPrint(node.Right)
fmt.Printf("%v, ", node.Data)
}
func inOrderPrint[T any](node *datastructure.TreeNode[T]) {
if node == nil {
return
}
inOrderPrint(node.Left)
fmt.Printf("%v, ", node.Data)
inOrderPrint(node.Right)
}
func levelOrderTraverse[T any](root *datastructure.TreeNode[T], traversal *[]T) {
var q []*datastructure.TreeNode[T] // queue
var n *datastructure.TreeNode[T] // temp node
q = append(q, root)
for len(q) != 0 {
n, q = q[0], q[1:]
*traversal = append(*traversal, n.Data)
if n.Left != nil {
q = append(q, n.Left)
}
if n.Right != nil {
q = append(q, n.Right)
}
}
}
func insertTreeNode[T any](rootNode, newNode *datastructure.TreeNode[T], comparator lancetconstraints.Comparator) {
if comparator.Compare(newNode.Data, rootNode.Data) == -1 {
if rootNode.Left == nil {
rootNode.Left = newNode
} else {
insertTreeNode(rootNode.Left, newNode, comparator)
}
} else {
if rootNode.Right == nil {
rootNode.Right = newNode
} else {
insertTreeNode(rootNode.Right, newNode, comparator)
}
}
}
// todo, delete root node failed
func deleteTreeNode[T any](node *datastructure.TreeNode[T], data T, comparator lancetconstraints.Comparator) *datastructure.TreeNode[T] {
if node == nil {
return nil
}
if comparator.Compare(data, node.Data) == -1 {
node.Left = deleteTreeNode(node.Left, data, comparator)
} else if comparator.Compare(data, node.Data) == 1 {
node.Right = deleteTreeNode(node.Right, data, comparator)
} else {
if node.Left == nil {
node = node.Right
} else if node.Right == nil {
node = node.Left
} else {
l := node.Right
d := inOrderSuccessor(l)
d.Left = node.Left
return node.Right
}
}
return node
}
func inOrderSuccessor[T any](root *datastructure.TreeNode[T]) *datastructure.TreeNode[T] {
cur := root
for cur.Left != nil {
cur = cur.Left
}
return cur
}
func printTreeNodes[T any](nodes []*datastructure.TreeNode[T], level, maxLevel int) {
if len(nodes) == 0 || isAllNil(nodes) {
return
}
floor := maxLevel - level
endgeLines := int(math.Pow(float64(2), (math.Max(float64(floor)-1, 0))))
firstSpaces := int(math.Pow(float64(2), float64(floor))) - 1
betweenSpaces := int(math.Pow(float64(2), float64(floor)+1)) - 1
printSpaces(firstSpaces)
newNodes := []*datastructure.TreeNode[T]{}
for _, node := range nodes {
if node != nil {
fmt.Printf("%v", node.Data)
newNodes = append(newNodes, node.Left)
newNodes = append(newNodes, node.Right)
} else {
newNodes = append(newNodes, nil)
newNodes = append(newNodes, nil)
printSpaces(1)
}
printSpaces(betweenSpaces)
}
fmt.Println("")
for i := 1; i <= endgeLines; i++ {
for j := 0; j < len(nodes); j++ {
printSpaces(firstSpaces - i)
if nodes[j] == nil {
printSpaces(endgeLines + endgeLines + i + 1)
continue
}
if nodes[j].Left != nil {
fmt.Print("/")
} else {
printSpaces(1)
}
printSpaces(i + i - 1)
if nodes[j].Right != nil {
fmt.Print("\\")
} else {
printSpaces(1)
}
printSpaces(endgeLines + endgeLines - 1)
}
fmt.Println("")
}
printTreeNodes(newNodes, level+1, maxLevel)
}
// printSpaces
func printSpaces(n int) {
for i := 0; i < n; i++ {
fmt.Print(" ")
}
}
func isAllNil[T any](nodes []*datastructure.TreeNode[T]) bool {
for _, v := range nodes {
if v != nil {
return false
}
}
return true
}
func calculateDepth[T any](node *datastructure.TreeNode[T], depth int) int {
if node == nil {
return depth
}
return max(calculateDepth(node.Left, depth+1), calculateDepth(node.Right, depth+1))
}
func max(a, b int) int {
if a > b {
return a
}
return b
}

View File

@@ -3,7 +3,7 @@ package datetime
import ( import (
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestToUnix(t *testing.T) { func TestToUnix(t *testing.T) {
@@ -19,10 +19,10 @@ func TestToUnix(t *testing.T) {
func TestToFormat(t *testing.T) { func TestToFormat(t *testing.T) {
assert := internal.NewAssert(t, "TestToFormat") assert := internal.NewAssert(t, "TestToFormat")
_, err := NewFormat("2022/03/18 17:04:05") tm, err := NewFormat("2022/03/18 17:04:05")
assert.IsNotNil(err) assert.IsNotNil(err)
tm, err := NewFormat("2022-03-18 17:04:05") tm, err = NewFormat("2022-03-18 17:04:05")
assert.IsNil(err) assert.IsNil(err)
t.Log("ToFormat -> ", tm.ToFormat()) t.Log("ToFormat -> ", tm.ToFormat())
@@ -31,22 +31,23 @@ func TestToFormat(t *testing.T) {
func TestToFormatForTpl(t *testing.T) { func TestToFormatForTpl(t *testing.T) {
assert := internal.NewAssert(t, "TestToFormatForTpl") assert := internal.NewAssert(t, "TestToFormatForTpl")
_, err := NewFormat("2022/03/18 17:04:05") tm, err := NewFormat("2022/03/18 17:04:05")
assert.IsNotNil(err) assert.IsNotNil(err)
tm, err := NewFormat("2022-03-18 17:04:05") tm, err = NewFormat("2022-03-18 17:04:05")
assert.IsNil(err) assert.IsNil(err)
t.Log("ToFormatForTpl -> ", tm.ToFormatForTpl("2006/01/02 15:04:05")) t.Log("ToFormatForTpl -> ", tm.ToFormatForTpl("2006/01/02 15:04:05"))
} }
func TestToIso8601(t *testing.T) { func TestToIso8601(t *testing.T) {
assert := internal.NewAssert(t, "TestToIso8601") assert := internal.NewAssert(t, "TestToIso8601")
_, err := NewISO8601("2022-03-18 17:04:05") tm, err := NewISO8601("2022-03-18 17:04:05")
assert.IsNotNil(err) assert.IsNotNil(err)
tm, err := NewISO8601("2006-01-02T15:04:05.999Z") tm, err = NewISO8601("2006-01-02T15:04:05.999Z")
assert.IsNil(err) assert.IsNil(err)
t.Log("ToIso8601 -> ", tm.ToIso8601()) t.Log("ToIso8601 -> ", tm.ToIso8601())

View File

@@ -4,7 +4,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestAddDay(t *testing.T) { func TestAddDay(t *testing.T) {

View File

@@ -1,593 +0,0 @@
# 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/sorter.go](https://github.com/duke-git/lancet/blob/main/algorithm/sorter.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"
)
```
<div STYLE="page-break-after: always;"></div>
## Index
- [BubbleSort](#BubbleSort)
- [CountSort](#CountSort)
- [HeapSort](#HeapSort)
- [InsertionSort](#InsertionSort)
- [MergeSort](#MergeSort)
- [QuickSort](#QuickSort)
- [SelectionSort](#SelectionSort)
- [ShellSort](#ShellSort)
- [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>
```go
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.BubbleSort(intSlice, comparator)
fmt.Println(sortedSlice) //[]int{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>
```go
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/algorithm"
)
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{
{Name: "a", Age: 20},
{Name: "b", Age: 10},
{Name: "c", Age: 17},
{Name: "d", Age: 8},
{Name: "e", Age: 28},
}
comparator := &peopleAgeComparator{}
sortedPeople := algorithm.InsertionSort(peoples, comparator)
fmt.Println(sortedSlice) //[{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>
```go
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.SelectionSort(intSlice, comparator)
fmt.Println(sortedSlice) //[]int{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>
```go
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.ShellSort(intSlice, comparator)
fmt.Println(sortedSlice) //[]int{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>
```go
func QuickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.QuickSort(intSlice, 0, len(intSlice)-1, comparator)
fmt.Println(sortedSlice) //[]int{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>
```go
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.HeapSort(intSlice, comparator)
fmt.Println(sortedSlice) //[]int{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>
```go
func MergeSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.MergeSort(intSlice, 0, len(intSlice)-1, comparator)
fmt.Println(sortedSlice) //[]int{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>
```go
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.CountSort(intSlice, comparator)
fmt.Println(sortedSlice) //[]int{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>
```go
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//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}
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
}
```
### <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>
```go
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//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}
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
}
```
### <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>
<b>Signature:</b>
```go
func LinearSearch[T any](slice []T, target T, comparator lancetconstraints.Comparator) int
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
foundIndex := algorithm.LinearSearch(intSlice, 5, comparator)
fmt.Println(foundIndex) //2
notFoundIndex := algorithm.LinearSearch(sortedNumbers, 0, comparator)
fmt.Println(notFoundIndex) //-1
}
```
### <span id="LRUCache">LRUCache</span>
<p>LRUCache implements mem cache with lru.</p>
<b>Signature:</b>
```go
func NewLRUCache[K comparable, V any](capacity int) *LRUCache[K, V]
func (l *LRUCache[K, V]) Get(key K) (V, bool)
func (l *LRUCache[K, V]) Put(key K, value V)
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
cache := algorithm.NewLRUCache[int, int](2)
cache.Put(1, 1)
cache.Put(2, 2)
_, ok := cache.Get(0) // ok -> false
v, ok := cache.Get(1) // v->1, ok->true
}
```

View File

@@ -1,593 +0,0 @@
# Algorithm
algorithm算法包实现一些基本算法sortsearchlrucache。
<div STYLE="page-break-after: always;"></div>
## 源码
- [https://github.com/duke-git/lancet/blob/main/algorithm/sorter.go](https://github.com/duke-git/lancet/blob/main/algorithm/sorter.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"
)
```
<div STYLE="page-break-after: always;"></div>
## 目录
- [BubbleSort](#BubbleSort)
- [CountSort](#CountSort)
- [HeapSort](#HeapSort)
- [InsertionSort](#InsertionSort)
- [MergeSort](#MergeSort)
- [QuickSort](#QuickSort)
- [SelectionSort](#SelectionSort)
- [ShellSort](#ShellSort)
- [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>
<b>函数签名:</b>
```go
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.BubbleSort(intSlice, comparator)
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
}
```
### <span id="InsertionSort">InsertionSort</span>
<p>插入排序参数comparator需要实现包lancetconstraints.Comparator</p>
<b>函数签名:</b>
```go
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/algorithm"
)
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{
{Name: "a", Age: 20},
{Name: "b", Age: 10},
{Name: "c", Age: 17},
{Name: "d", Age: 8},
{Name: "e", Age: 28},
}
comparator := &peopleAgeComparator{}
sortedPeople := algorithm.InsertionSort(peoples, comparator)
fmt.Println(sortedSlice) //[{d 8} {b 10} {c 17} {a 20} {e 28}]
}
```
### <span id="SelectionSort">SelectionSort</span>
<p>选择排序参数comparator需要实现包lancetconstraints.Comparator</p>
<b>函数签名:</b>
```go
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.SelectionSort(intSlice, comparator)
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
}
```
### <span id="ShellSort">ShellSort</span>
<p>希尔排序参数comparator需要实现包lancetconstraints.Comparator</p>
<b>函数签名:</b>
```go
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.ShellSort(intSlice, comparator)
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
}
```
### <span id="QuickSort">QuickSort</span>
<p>快速排序参数comparator需要实现包lancetconstraints.Comparator</p>
<b>函数签名:</b>
```go
func QuickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.QuickSort(intSlice, 0, len(intSlice)-1, comparator)
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
}
```
### <span id="HeapSort">HeapSort</span>
<p>堆排序参数comparator需要实现包lancetconstraints.Comparator</p>
<b>函数签名:</b>
```go
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.HeapSort(intSlice, comparator)
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
}
```
### <span id="MergeSort">MergeSort</span>
<p>归并排序参数comparator需要实现包lancetconstraints.Comparator</p>
<b>函数签名:</b>
```go
func MergeSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.MergeSort(intSlice, 0, len(intSlice)-1, comparator)
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
}
```
### <span id="CountSort">CountSort</span>
<p>计数排序参数comparator需要实现包lancetconstraints.Comparator</p>
<b>函数签名:</b>
```go
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
sortedSlice := algorithm.CountSort(intSlice, comparator)
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
}
```
### <span id="BinarySearch">BinarySearch</span>
<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>
```go
package main
import (
"fmt"
"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)
//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}
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
}
```
### <span id="BinaryIterativeSearch">BinaryIterativeSearch</span>
<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>
```go
package main
import (
"fmt"
"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)
//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}
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
}
```
### <span id="LinearSearch">LinearSearch</span>
<p>线性查找,返回元素索引,未找到元素返回-1参数comparator需要实现包lancetconstraints.Comparator</p>
<b>函数签名:</b>
```go
func LinearSearch[T any](slice []T, target T, comparator lancetconstraints.Comparator) int
```
<b>Example:</b>
```go
package main
import (
"fmt"
"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)
//ascending order
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
intSlice := []int{2, 1, 5, 3, 6, 4}
comparator := &intComparator{}
foundIndex := algorithm.LinearSearch(intSlice, 5, comparator)
fmt.Println(foundIndex) //2
notFoundIndex := algorithm.LinearSearch(sortedNumbers, 0, comparator)
fmt.Println(notFoundIndex) //-1
}
```
### <span id="LRUCache">LRUCache</span>
<p>lru实现缓存</p>
<b>函数签名:</b>
```go
func NewLRUCache[K comparable, V any](capacity int) *LRUCache[K, V]
func (l *LRUCache[K, V]) Get(key K) (V, bool)
func (l *LRUCache[K, V]) Put(key K, value V)
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/algorithm"
)
func main() {
cache := algorithm.NewLRUCache[int, int](2)
cache.Put(1, 1)
cache.Put(2, 2)
_, ok := cache.Get(0) // ok -> false
v, ok := cache.Get(1) // v->1, ok->true
}
```

View File

@@ -5,14 +5,14 @@ Package convertor contains some functions for data type convertion.
## Source: ## Source:
- [https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go) [https://github.com/duke-git/lancet/blob/v1/convertor/convertor.go](https://github.com/duke-git/lancet/blob/v1/convertor/convertor.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
``` ```
@@ -50,12 +50,12 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
colorHex := "#003366" colorHex := "#003366"
r, g, b := convertor.ColorHexToRGB(colorHex) r, g, b := ColorHexToRGB(colorHex)
fmt.Println(r, g, b) //0,51,102 fmt.Println(r, g, b) //0,51,102
} }
``` ```
@@ -78,14 +78,14 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
r := 0 r := 0
g := 51 g := 51
b := 102 b := 102
colorHex := convertor.ColorRGBToHex(r, g, b) colorHex := ColorRGBToHex(r, g, b)
fmt.Println(colorHex) //#003366 fmt.Println(colorHex) //#003366
} }
@@ -109,7 +109,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -136,7 +136,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ToBytes(data any) ([]byte, error) func ToBytes(data interface{}) ([]byte, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -145,7 +145,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -175,7 +175,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -199,7 +199,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ToFloat(value any) (float64, error) func ToFloat(value interface{}) (float64, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -208,7 +208,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -232,7 +232,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ToInt(value any) (int64, error) func ToInt(value interface{}) (int64, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -241,7 +241,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -265,7 +265,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ToJson(value any) (string, error) func ToJson(value interface{}) (string, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -274,7 +274,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -293,7 +293,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ToString(value any) string func ToString(value interface{}) string
``` ```
<b>Example:</b> <b>Example:</b>
@@ -302,7 +302,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -321,7 +321,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func StructToMap(value any) (map[string]any, error) func StructToMap(value interface{}) (map[string]interface{}, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -330,7 +330,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {

View File

@@ -5,7 +5,7 @@ convertor转换器包支持一些常见的数据类型转换
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go) [https://github.com/duke-git/lancet/blob/v1/convertor/convertor.go](https://github.com/duke-git/lancet/blob/v1/convertor/convertor.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ convertor转换器包支持一些常见的数据类型转换
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
``` ```
@@ -52,12 +52,12 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
colorHex := "#003366" colorHex := "#003366"
r, g, b := convertor.ColorHexToRGB(colorHex) r, g, b := ColorHexToRGB(colorHex)
fmt.Println(r, g, b) //0,51,102 fmt.Println(r, g, b) //0,51,102
} }
``` ```
@@ -80,14 +80,14 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
r := 0 r := 0
g := 51 g := 51
b := 102 b := 102
colorHex := convertor.ColorRGBToHex(r, g, b) colorHex := ColorRGBToHex(r, g, b)
fmt.Println(colorHex) //#003366 fmt.Println(colorHex) //#003366
} }
@@ -111,7 +111,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -138,7 +138,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ToBytes(data any) ([]byte, error) func ToBytes(data interface{}) ([]byte, error)
``` ```
<b>列子:</b> <b>列子:</b>
@@ -147,7 +147,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -177,7 +177,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -201,7 +201,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ToFloat(value any) (float64, error) func ToFloat(value interface{}) (float64, error)
``` ```
<b>列子:</b> <b>列子:</b>
@@ -210,7 +210,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -234,7 +234,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ToInt(value any) (int64, error) func ToInt(value interface{}) (int64, error)
``` ```
<b>例子:</b> <b>例子:</b>
@@ -243,7 +243,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -267,7 +267,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ToJson(value any) (string, error) func ToJson(value interface{}) (string, error)
``` ```
<b>列子:</b> <b>列子:</b>
@@ -276,7 +276,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -295,7 +295,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ToString(value any) string func ToString(value interface{}) string
``` ```
<b>例子:</b> <b>例子:</b>
@@ -304,7 +304,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {
@@ -323,7 +323,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func StructToMap(value any) (map[string]any, error) func StructToMap(value interface{}) (map[string]interface{}, error)
``` ```
<b>列子:</b> <b>列子:</b>
@@ -332,7 +332,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/convertor"
) )
func main() { func main() {

View File

@@ -5,17 +5,17 @@ Package cryptor contains some functions for data encryption and decryption. Supp
## Source: ## Source:
- [https://github.com/duke-git/lancet/blob/main/cryptor/aes.go](https://github.com/duke-git/lancet/blob/main/cryptor/aes.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go](https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/des.go](https://github.com/duke-git/lancet/blob/main/cryptor/des.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/des.go](https://github.com/duke-git/lancet/blob/v1/cryptor/des.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/basic.go](https://github.com/duke-git/lancet/blob/main/cryptor/basic.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go](https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
``` ```
@@ -80,7 +80,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -110,7 +110,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -140,7 +140,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -171,7 +171,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -202,7 +202,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -234,7 +234,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -264,7 +264,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -295,7 +295,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -325,7 +325,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -356,7 +356,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -384,7 +384,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -412,7 +412,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -443,7 +443,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -475,7 +475,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -506,7 +506,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -538,7 +538,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -570,7 +570,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -600,7 +600,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -631,7 +631,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -661,7 +661,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -693,7 +693,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -721,7 +721,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -749,7 +749,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -777,7 +777,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -806,7 +806,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -834,7 +834,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -862,7 +862,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -890,7 +890,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -918,7 +918,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -946,7 +946,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -976,7 +976,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -1012,7 +1012,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {

View File

@@ -5,17 +5,17 @@ cryptor加密包支持数据加密和解密获取md5hash值。支持base64
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/main/cryptor/aes.go](https://github.com/duke-git/lancet/blob/main/cryptor/aes.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go](https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/des.go](https://github.com/duke-git/lancet/blob/main/cryptor/des.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/des.go](https://github.com/duke-git/lancet/blob/v1/cryptor/des.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/basic.go](https://github.com/duke-git/lancet/blob/main/cryptor/basic.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go](https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
``` ```
@@ -80,7 +80,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -110,7 +110,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -140,7 +140,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -171,7 +171,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -203,7 +203,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -235,7 +235,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -265,7 +265,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -296,7 +296,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -326,7 +326,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -356,7 +356,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -384,7 +384,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -412,7 +412,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -443,7 +443,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -475,7 +475,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -506,7 +506,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -538,7 +538,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -570,7 +570,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -600,7 +600,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -631,7 +631,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -661,7 +661,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -692,7 +692,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -720,7 +720,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -748,7 +748,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -776,7 +776,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -805,7 +805,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -833,7 +833,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -861,7 +861,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -889,7 +889,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -917,7 +917,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -945,7 +945,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -975,7 +975,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {
@@ -1009,7 +1009,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/cryptor" "github.com/duke-git/lancet/cryptor"
) )
func main() { func main() {

View File

@@ -5,15 +5,14 @@ Package datetime supports date and time format and compare.
## Source: ## 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/v1/datetime/datetime.go](https://github.com/duke-git/lancet/blob/v1/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> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
``` ```
@@ -29,6 +28,7 @@ import (
- [BeginOfWeek](#BeginOfWeek) - [BeginOfWeek](#BeginOfWeek)
- [BeginOfMonth](#BeginOfMonth) - [BeginOfMonth](#BeginOfMonth)
- [BeginOfYear](#BeginOfYear) - [BeginOfYear](#BeginOfYear)
- [EndOfMinute](#EndOfMinute) - [EndOfMinute](#EndOfMinute)
- [EndOfHour](#EndOfHour) - [EndOfHour](#EndOfHour)
- [EndOfDay](#EndOfDay) - [EndOfDay](#EndOfDay)
@@ -41,8 +41,8 @@ import (
- [GetZeroHourTimestamp](#GetZeroHourTimestamp) - [GetZeroHourTimestamp](#GetZeroHourTimestamp)
- [GetNightTimestamp](#GetNightTimestamp) - [GetNightTimestamp](#GetNightTimestamp)
- [FormatTimeToStr](#FormatTimeToStr) - [FormatTimeToStr](#FormatTimeToStr)
- [FormatStrToTime](#FormatStrToTime)
- [FormatStrToTime](#FormatStrToTime)
- [NewUnixNow](#NewUnixNow) - [NewUnixNow](#NewUnixNow)
- [NewUnix](#NewUnix) - [NewUnix](#NewUnix)
- [NewFormat](#NewFormat) - [NewFormat](#NewFormat)
@@ -52,8 +52,6 @@ import (
- [ToFormatForTpl](#ToFormatForTpl) - [ToFormatForTpl](#ToFormatForTpl)
- [ToIso8601](#ToIso8601) - [ToIso8601](#ToIso8601)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation ## Documentation
@@ -96,7 +94,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -125,7 +123,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -153,7 +151,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -181,7 +179,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -207,7 +205,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -233,7 +231,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -261,7 +259,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -289,7 +287,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -316,7 +314,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -344,7 +342,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -370,7 +368,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -396,7 +394,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -424,7 +422,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -452,7 +450,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -479,7 +477,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -506,7 +504,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -533,7 +531,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -560,7 +558,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -587,7 +585,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -614,7 +612,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -640,7 +638,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -666,7 +664,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {

View File

@@ -5,14 +5,14 @@ datetime日期时间处理包格式化日期比较日期。
## 源码: ## 源码:
- [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/v1/datetime/datetime.go](https://github.com/duke-git/lancet/blob/v1/datetime/datetime.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
``` ```
@@ -28,6 +28,7 @@ import (
- [BeginOfWeek](#BeginOfWeek) - [BeginOfWeek](#BeginOfWeek)
- [BeginOfMonth](#BeginOfMonth) - [BeginOfMonth](#BeginOfMonth)
- [BeginOfYear](#BeginOfYear) - [BeginOfYear](#BeginOfYear)
- [EndOfMinute](#EndOfMinute) - [EndOfMinute](#EndOfMinute)
- [EndOfHour](#EndOfHour) - [EndOfHour](#EndOfHour)
- [EndOfDay](#EndOfDay) - [EndOfDay](#EndOfDay)
@@ -41,7 +42,6 @@ import (
- [GetNightTimestamp](#GetNightTimestamp) - [GetNightTimestamp](#GetNightTimestamp)
- [FormatTimeToStr](#FormatTimeToStr) - [FormatTimeToStr](#FormatTimeToStr)
- [FormatStrToTime](#FormatStrToTime) - [FormatStrToTime](#FormatStrToTime)
- [NewUnixNow](#NewUnixNow) - [NewUnixNow](#NewUnixNow)
- [NewUnix](#NewUnix) - [NewUnix](#NewUnix)
- [NewFormat](#NewFormat) - [NewFormat](#NewFormat)
@@ -93,7 +93,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -122,7 +122,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -150,7 +150,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -178,7 +178,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -204,7 +204,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -230,7 +230,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -258,7 +258,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -286,7 +286,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -313,7 +313,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -341,7 +341,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -367,7 +367,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -393,7 +393,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -421,7 +421,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -449,7 +449,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -476,7 +476,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -503,7 +503,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -530,7 +530,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -557,7 +557,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -584,7 +584,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -611,7 +611,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -637,7 +637,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -663,7 +663,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/datetime" "github.com/duke-git/lancet/datetime"
) )
func main() { func main() {
@@ -673,6 +673,7 @@ func main() {
``` ```
### <span id="NewUnixNow">NewUnixNow</span> ### <span id="NewUnixNow">NewUnixNow</span>
<p>创建一个当前时间的unix时间戳</p> <p>创建一个当前时间的unix时间戳</p>
@@ -891,3 +892,4 @@ func main() {
fmt.Println(ts) //"2006-01-02T23:04:05+08:00" fmt.Println(ts) //"2006-01-02T23:04:05+08:00"
} }
``` ```

View File

@@ -5,14 +5,14 @@ Package fileutil implements some basic functions for file operations.
## Source: ## 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/v1/fileutil/file.go](https://github.com/duke-git/lancet/blob/v1/fileutil/file.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
``` ```
@@ -21,6 +21,8 @@ import (
## Index ## Index
- [ClearFile](#ClearFile) - [ClearFile](#ClearFile)
- [CreateFile](#CreateFile) - [CreateFile](#CreateFile)
- [CreateDir](#CreateDir)
- [CopyFile](#CopyFile) - [CopyFile](#CopyFile)
- [FileMode](#FileMode) - [FileMode](#FileMode)
- [MiMeType](#MiMeType) - [MiMeType](#MiMeType)
@@ -32,7 +34,6 @@ import (
- [ReadFileToString](#ReadFileToString) - [ReadFileToString](#ReadFileToString)
- [ReadFileByLine](#ReadFileByLine) - [ReadFileByLine](#ReadFileByLine)
- [Zip](#Zip) - [Zip](#Zip)
- [UnZip](#UnZip) - [UnZip](#UnZip)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -56,7 +57,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -67,6 +68,34 @@ func main() {
} }
``` ```
### <span id="CreateDir">CreateDir</span>
<p>Create directory in absolute path. param `absPath` like /a/, /a/b/.</p>
<b>Signature:</b>
```go
func CreateDir(absPath string) error
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/fileutil"
)
func main() {
err := fileutil.CreateDir("/a/")
fmt.Println(err)
}
```
### <span id="CreateFile">CreateFile</span> ### <span id="CreateFile">CreateFile</span>
<p>Create file in path. return true if create succeed.</p> <p>Create file in path. return true if create succeed.</p>
@@ -82,7 +111,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -107,7 +136,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -135,7 +164,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -155,7 +184,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func MiMeType(file any) string func MiMeType(file interface{}) string
``` ```
<b>Example:</b> <b>Example:</b>
@@ -165,7 +194,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -196,7 +225,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -223,7 +252,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -249,7 +278,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -278,7 +307,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -304,7 +333,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -332,7 +361,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -365,7 +394,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -398,7 +427,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -427,7 +456,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {

View File

@@ -5,14 +5,14 @@ fileutil包支持文件基本操作。
## 源码: ## 源码:
- [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/v1/fileutil/file.go](https://github.com/duke-git/lancet/blob/v1/fileutil/file.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
``` ```
@@ -21,6 +21,7 @@ import (
## 目录 ## 目录
- [ClearFile](#ClearFile) - [ClearFile](#ClearFile)
- [CreateFile](#CreateFile) - [CreateFile](#CreateFile)
- [CreateDir](#CreateDir)
- [CopyFile](#CopyFile) - [CopyFile](#CopyFile)
- [FileMode](#FileMode) - [FileMode](#FileMode)
- [MiMeType](#MiMeType) - [MiMeType](#MiMeType)
@@ -56,7 +57,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -67,6 +68,33 @@ func main() {
} }
``` ```
### <span id="CreateDir">CreateDir</span>
<p>使用绝对路径创建嵌套目录,例如/a/, /a/b/</p>
<b>函数签名:</b>
```go
func CreateDir(absPath string) error
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/fileutil"
)
func main() {
err := fileutil.CreateDir("/a/")
fmt.Println(err)
}
```
### <span id="CreateFile">CreateFile</span> ### <span id="CreateFile">CreateFile</span>
<p>创建文件创建成功返回true, 否则返回false</p> <p>创建文件创建成功返回true, 否则返回false</p>
@@ -82,7 +110,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -107,7 +135,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -135,7 +163,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -155,7 +183,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func MiMeType(file any) string func MiMeType(file interface{}) string
``` ```
<b>例子:</b> <b>例子:</b>
@@ -165,7 +193,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -196,7 +224,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -223,7 +251,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -249,7 +277,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -278,7 +306,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -304,7 +332,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -332,7 +360,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -365,7 +393,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -398,7 +426,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {
@@ -427,7 +455,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/fileutil" "github.com/duke-git/lancet/fileutil"
) )
func main() { func main() {

View File

@@ -5,14 +5,14 @@ formatter contains some functions for data formatting.
## Source: ## 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/v1/formatter/formatter.go](https://github.com/duke-git/lancet/blob/v1/formatter/formatter.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/formatter" "github.com/duke-git/lancet/formatter"
) )
``` ```
@@ -34,7 +34,7 @@ Param should be number or numberic string.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Comma(v any, symbol string) string func Comma(v interface{}, symbol string) string
``` ```
<b>Example:</b> <b>Example:</b>
@@ -43,7 +43,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/formatter" "github.com/duke-git/lancet/formatter"
) )
func main() { func main() {

View File

@@ -5,14 +5,14 @@ formatter格式化器包含一些数据格式化处理方法。
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go) [https://github.com/duke-git/lancet/blob/v1/formatter/formatter.go](https://github.com/duke-git/lancet/blob/v1/formatter/formatter.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/formatter" "github.com/duke-git/lancet/formatter"
) )
``` ```
@@ -33,7 +33,7 @@ import (
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Comma(v any, symbol string) string func Comma(v interface{}, symbol string) string
``` ```
<b>例子:</b> <b>例子:</b>
@@ -42,7 +42,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/formatter" "github.com/duke-git/lancet/formatter"
) )
func main() { func main() {

View File

@@ -5,15 +5,15 @@ Package function can control the flow of function execution and support part of
## Source: ## 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/v1/function/function.go](https://github.com/duke-git/lancet/blob/v1/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/v1/function/watcher.go](https://github.com/duke-git/lancet/blob/v1/function/watcher.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
``` ```
@@ -40,7 +40,7 @@ import (
<b>Signature:</b> <b>Signature:</b>
```go ```go
func After(n int, fn any) func(args ...any) []reflect.Value func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value
``` ```
<b>Example:</b> <b>Example:</b>
@@ -49,7 +49,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {
@@ -59,7 +59,7 @@ func main() {
return i return i
}) })
type cb func(args ...any) []reflect.Value type cb func(args ...interface{}) []reflect.Value
print := func(i int, s string, fn cb) { print := func(i int, s string, fn cb) {
fmt.Printf("arr[%d] is %s \n", i, s) fmt.Printf("arr[%d] is %s \n", i, s)
fn(i) fn(i)
@@ -87,7 +87,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Before(n int, fn any) func(args ...any) []reflect.Value func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value
``` ```
<b>Example:</b> <b>Example:</b>
@@ -96,8 +96,8 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func main() { func main() {
@@ -109,7 +109,7 @@ func main() {
}) })
var res []int64 var res []int64
type cb func(args ...any) []reflect.Value type cb func(args ...interface{}) []reflect.Value
appendStr := func(i int, s string, fn cb) { appendStr := func(i int, s string, fn cb) {
v := fn(i) v := fn(i)
res = append(res, v[0].Int()) res = append(res, v[0].Int())
@@ -133,8 +133,8 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
type Fn func(...any) any type Fn func(...interface{}) interface{}
func (f Fn) Curry(i any) func(...any) any func (f Fn) Curry(i interface{}) func(...interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
@@ -143,14 +143,14 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {
add := func(a, b int) int { add := func(a, b int) int {
return a + b return a + b
} }
var addCurry function.Fn = func(values ...any) any { var addCurry function.Fn = func(values ...interface{}) interface{} {
return add(values[0].(int), values[1].(int)) return add(values[0].(int), values[1].(int))
} }
add1 := addCurry.Curry(1) add1 := addCurry.Curry(1)
@@ -168,7 +168,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Compose(fnList ...func(...any) any) func(...any) any func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
@@ -177,14 +177,14 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {
add1 := func(v ...any) any { add1 := func(v ...interface{}) interface{} {
return v[0].(int) + 1 return v[0].(int) + 1
} }
add2 := func(v ...any) any { add2 := func(v ...interface{}) interface{} {
return v[0].(int) + 2 return v[0].(int) + 2
} }
@@ -213,7 +213,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {
@@ -246,7 +246,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Delay(delay time.Duration, fn any, args ...any) func Delay(delay time.Duration, fn interface{}, args ...interface{})
``` ```
<b>Example:</b> <b>Example:</b>
@@ -255,7 +255,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {
@@ -275,7 +275,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Schedule(d time.Duration, fn any, args ...any) chan bool func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool
``` ```
<b>Example:</b> <b>Example:</b>
@@ -284,7 +284,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {
@@ -327,7 +327,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {

View File

@@ -5,15 +5,15 @@ function函数包控制函数执行流程包含部分函数式编程。
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go) [https://github.com/duke-git/lancet/blob/v1/function/function.go](https://github.com/duke-git/lancet/blob/v1/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/v1/function/watcher.go](https://github.com/duke-git/lancet/blob/v1/function/watcher.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
``` ```
@@ -40,7 +40,7 @@ import (
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func After(n int, fn any) func(args ...any) []reflect.Value func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value
``` ```
<b>例子:</b> <b>例子:</b>
@@ -49,7 +49,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {
@@ -59,7 +59,7 @@ func main() {
return i return i
}) })
type cb func(args ...any) []reflect.Value type cb func(args ...interface{}) []reflect.Value
print := func(i int, s string, fn cb) { print := func(i int, s string, fn cb) {
fmt.Printf("arr[%d] is %s \n", i, s) fmt.Printf("arr[%d] is %s \n", i, s)
fn(i) fn(i)
@@ -87,7 +87,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Before(n int, fn any) func(args ...any) []reflect.Value func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value
``` ```
<b>例子:</b> <b>例子:</b>
@@ -96,8 +96,8 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func main() { func main() {
@@ -109,7 +109,7 @@ func main() {
}) })
var res []int64 var res []int64
type cb func(args ...any) []reflect.Value type cb func(args ...interface{}) []reflect.Value
appendStr := func(i int, s string, fn cb) { appendStr := func(i int, s string, fn cb) {
v := fn(i) v := fn(i)
res = append(res, v[0].Int()) res = append(res, v[0].Int())
@@ -133,8 +133,8 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
type Fn func(...any) any type Fn func(...interface{}) interface{}
func (f Fn) Curry(i any) func(...any) any func (f Fn) Curry(i interface{}) func(...interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
@@ -143,14 +143,14 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {
add := func(a, b int) int { add := func(a, b int) int {
return a + b return a + b
} }
var addCurry function.Fn = func(values ...any) any { var addCurry function.Fn = func(values ...interface{}) interface{} {
return add(values[0].(int), values[1].(int)) return add(values[0].(int), values[1].(int))
} }
add1 := addCurry.Curry(1) add1 := addCurry.Curry(1)
@@ -168,7 +168,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Compose(fnList ...func(...any) any) func(...any) any func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
@@ -177,14 +177,14 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {
add1 := func(v ...any) any { add1 := func(v ...interface{}) interface{} {
return v[0].(int) + 1 return v[0].(int) + 1
} }
add2 := func(v ...any) any { add2 := func(v ...interface{}) interface{} {
return v[0].(int) + 2 return v[0].(int) + 2
} }
@@ -213,7 +213,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {
@@ -246,7 +246,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Delay(delay time.Duration, fn any, args ...any) func Delay(delay time.Duration, fn interface{}, args ...interface{})
``` ```
<b>例子:</b> <b>例子:</b>
@@ -255,7 +255,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {
@@ -275,7 +275,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Schedule(d time.Duration, fn any, args ...any) chan bool func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool
``` ```
<b>例子:</b> <b>例子:</b>
@@ -284,7 +284,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {
@@ -327,7 +327,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/function"
) )
func main() { func main() {

View File

@@ -1,304 +0,0 @@
# 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/maputil.go](https://github.com/duke-git/lancet/blob/main/maputil/maputil.go)
<div STYLE="page-break-after: always;"></div>
## Example:
```go
import (
"github.com/duke-git/lancet/v2/maputil"
)
```
<div STYLE="page-break-after: always;"></div>
## Index
- [ForEach](#ForEach)
- [Filter](#Filter)
- [Intersect](#Intersect)
- [Keys](#Keys)
- [Merge](#Merge)
- [Minus](#Minus)
- [Values](#Values)
<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>
```go
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V))
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
}
var sum int
maputil.ForEach(m, func(_ string, value int) {
sum += value
})
fmt.Println(sum) // 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>
```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
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
}
isEven := func(_ string, value int) bool {
return value%2 == 0
}
maputil.Filter(m, func(_ string, value int) {
sum += value
})
res := maputil.Filter(m, isEven)
fmt.Println(res) // map[string]int{"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>
```go
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"a": 1,
"b": 2,
"c": 6,
"d": 7,
}
m3 := map[string]int{
"a": 1,
"b": 9,
"e": 9,
}
fmt.Println(maputil.Intersect(m1)) // map[string]int{"a": 1, "b": 2, "c": 3}
fmt.Println(maputil.Intersect(m1, m2)) // map[string]int{"a": 1, "b": 2}
fmt.Println(maputil.Intersect(m1, m2, m3)) // map[string]int{"a": 1}
}
```
### <span id="Keys">Keys</span>
<p>Returns a slice of the map's keys.</p>
<b>Signature:</b>
```go
func Keys[K comparable, V any](m map[K]V) []K
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
keys := maputil.Keys(m)
sort.Ints(keys)
fmt.Println(keys) // []int{1, 2, 3, 4, 5}
}
```
### <span id="Merge">Merge</span>
<p>Merge maps, next key will overwrite previous key.</p>
<b>Signature:</b>
```go
func Merge[K comparable, V any](maps ...map[K]V) map[K]V
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m1 := map[int]string{
1: "a",
2: "b",
}
m2 := map[int]string{
1: "1",
3: "2",
}
fmt.Println(maputil.Merge(m1, m2)) // map[int]string{1:"1", 2:"b", 3:"2",}
}
```
### <span id="Minus">Minus</span>
<p>Creates an map of whose key in mapA but not in mapB.</p>
<b>Signature:</b>
```go
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"a": 11,
"b": 22,
"d": 33,
}
fmt.Println(maputil.Minus(m1, m2)) //map[string]int{"c": 3}
}
```
### <span id="Values">Values</span>
<p>Returns a slice of the map's values.</p>
<b>Signature:</b>
```go
func Values[K comparable, V any](m map[K]V) []V
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
values := maputil.Values(m)
sort.Strings(values)
fmt.Println(values) // []string{"a", "a", "b", "c", "d"}
}
```

View File

@@ -1,304 +0,0 @@
# Maputil
maputil包包括一些操作map的函数。
<div STYLE="page-break-after: always;"></div>
## 源码:
- [https://github.com/duke-git/lancet/blob/main/maputil/maputil.go](https://github.com/duke-git/lancet/blob/main/maputil/maputil.go)
<div STYLE="page-break-after: always;"></div>
## 用法:
```go
import (
"github.com/duke-git/lancet/v2/maputil"
)
```
<div STYLE="page-break-after: always;"></div>
## 目录:
- [ForEach](#ForEach)
- [Filter](#Filter)
- [Intersect](#Intersect)
- [Keys](#Keys)
- [Merge](#Merge)
- [Minus](#Minus)
- [Values](#Values)
<div STYLE="page-break-after: always;"></div>
## API文档:
### <span id="ForEach">ForEach</span>
<p>对map中的每对key和value执行iteratee函数</p>
<b>函数签名:</b>
```go
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V))
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
}
var sum int
maputil.ForEach(m, func(_ string, value int) {
sum += value
})
fmt.Println(sum) // 10
}
```
### <span id="Filter">Filter</span>
<p>迭代map中的每对key和value, 返回符合predicate函数的key, value</p>
<b>函数签名:</b>
```go
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
}
isEven := func(_ string, value int) bool {
return value%2 == 0
}
maputil.Filter(m, func(_ string, value int) {
sum += value
})
res := maputil.Filter(m, isEven)
fmt.Println(res) // map[string]int{"b": 2, "d": 4,}
}
```
### <span id="Intersect">Intersect</span>
<p>多个map的交集操作</p>
<b>函数签名:</b>
```go
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"a": 1,
"b": 2,
"c": 6,
"d": 7,
}
m3 := map[string]int{
"a": 1,
"b": 9,
"e": 9,
}
fmt.Println(maputil.Intersect(m1)) // map[string]int{"a": 1, "b": 2, "c": 3}
fmt.Println(maputil.Intersect(m1, m2)) // map[string]int{"a": 1, "b": 2}
fmt.Println(maputil.Intersect(m1, m2, m3)) // map[string]int{"a": 1}
}
```
### <span id="Keys">Keys</span>
<p>返回map中所有key的切片</p>
<b>函数签名:</b>
```go
func Keys[K comparable, V any](m map[K]V) []K
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
keys := maputil.Keys(m)
sort.Ints(keys)
fmt.Println(keys) // []int{1, 2, 3, 4, 5}
}
```
### <span id="Merge">Merge</span>
<p>合并多个maps, 相同的key会被后来的key覆盖</p>
<b>函数签名:</b>
```go
func Merge[K comparable, V any](maps ...map[K]V) map[K]V
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m1 := map[int]string{
1: "a",
2: "b",
}
m2 := map[int]string{
1: "1",
3: "2",
}
fmt.Println(maputil.Merge(m1, m2)) // map[int]string{1:"1", 2:"b", 3:"2",}
}
```
### <span id="Minus">Minus</span>
<p>返回一个map其中的key存在于mapA不存在于mapB.</p>
<b>函数签名:</b>
```go
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"a": 11,
"b": 22,
"d": 33,
}
fmt.Println(maputil.Minus(m1, m2)) //map[string]int{"c": 3}
}
```
### <span id="Values">Values</span>
<p>返回map中所有value的切片</p>
<b>函数签名:</b>
```go
func Values[K comparable, V any](m map[K]V) []V
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
values := maputil.Values(m)
sort.Strings(values)
fmt.Println(values) // []string{"a", "a", "b", "c", "d"}
}
```

View File

@@ -5,7 +5,7 @@ Package mathutil implements some functions for math calculation.
## Source: ## 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/v1/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,20 +13,16 @@ Package mathutil implements some functions for math calculation.
## Example: ## Example:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
``` ```
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Index ## Index
- [Average](#Average)
- [Exponent](#Exponent) - [Exponent](#Exponent)
- [Fibonacci](#Fibonacci) - [Fibonacci](#Fibonacci)
- [Factorial](#Factorial) - [Factorial](#Factorial)
- [Max](#Max)
- [Min](#Min)
- [Percent](#Percent) - [Percent](#Percent)
- [RoundToFloat](#RoundToFloat) - [RoundToFloat](#RoundToFloat)
- [RoundToString](#RoundToString) - [RoundToString](#RoundToString)
@@ -37,35 +33,6 @@ import (
## Documentation ## Documentation
### <span id="Average">Average</span>
<p>Return average value of numbers. Maybe call RoundToFloat to round result.</p>
<b>Signature:</b>
```go
func Average[T lancetconstraints.Number](numbers ...T) T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/mathutil"
)
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
}
```
### <span id="Exponent">Exponent</span> ### <span id="Exponent">Exponent</span>
<p>Calculate x to the nth power.</p> <p>Calculate x to the nth power.</p>
@@ -81,7 +48,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {
@@ -108,7 +75,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {
@@ -137,7 +104,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {
@@ -150,60 +117,6 @@ func main() {
### <span id="Max">Max</span>
<p>Return max value of numbers.</p>
<b>Signature:</b>
```go
func Max[T lancetconstraints.Number](numbers ...T) T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/mathutil"
)
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
}
```
### <span id="Min">Min</span>
<p>Return min value of numbers.</p>
<b>Signature:</b>
```go
func Min[T lancetconstraints.Number](numbers ...T) T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/mathutil"
)
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
}
```
### <span id="Percent">Percent</span> ### <span id="Percent">Percent</span>
<p>calculate the percentage of val to total, retain n decimal places.</p> <p>calculate the percentage of val to total, retain n decimal places.</p>
@@ -219,7 +132,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {
@@ -245,7 +158,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {
@@ -275,7 +188,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {
@@ -304,7 +217,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {

View File

@@ -5,7 +5,7 @@ mathutil包实现了一些数学计算的函数.
## 源码: ## 源码:
- [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/v1/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,19 +13,16 @@ mathutil包实现了一些数学计算的函数.
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
``` ```
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 目录 ## 目录
- [Average](#Average)
- [Exponent](#Exponent) - [Exponent](#Exponent)
- [Fibonacci](#Fibonacci) - [Fibonacci](#Fibonacci)
- [Factorial](#Factorial) - [Factorial](#Factorial)
- [Max](#Max)
- [Min](#Min)
- [Percent](#Percent) - [Percent](#Percent)
- [RoundToFloat](#RoundToFloat) - [RoundToFloat](#RoundToFloat)
@@ -37,33 +34,6 @@ import (
## Documentation ## Documentation
### <span id="Average">Average</span>
<p>计算平均数. 可能需要对结果调用RoundToFloat方法四舍五入</p>
<b>函数签名:</b>
```go
func Average[T lancetconstraints.Number](numbers ...T) T
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/mathutil"
)
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
}
```
### <span id="Exponent">Exponent</span> ### <span id="Exponent">Exponent</span>
<p>指数计算x的n次方</p> <p>指数计算x的n次方</p>
@@ -79,7 +49,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {
@@ -106,7 +76,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {
@@ -135,7 +105,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {
@@ -147,59 +117,6 @@ func main() {
``` ```
### <span id="Max">Max</span>
<p>返回参数中的最大数</p>
<b>函数签名:</b>
```go
func Max[T lancetconstraints.Number](numbers ...T) T
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/mathutil"
)
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
}
```
### <span id="Min">Min</span>
<p>返回参数中的最小数</p>
<b>函数签名:</b>
```go
func Min[T lancetconstraints.Number](numbers ...T) T
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/mathutil"
)
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
}
```
### <span id="Percent">Percent</span> ### <span id="Percent">Percent</span>
<p>计算百分比保留n位小数</p> <p>计算百分比保留n位小数</p>
@@ -216,7 +133,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {
@@ -242,7 +159,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {
@@ -272,7 +189,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {
@@ -301,7 +218,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/mathutil" "github.com/duke-git/lancet/mathutil"
) )
func main() { func main() {

View File

@@ -5,16 +5,16 @@ Package netutil contains functions to get net information and send http request.
## Source: ## Source:
- [https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go) [https://github.com/duke-git/lancet/blob/v1/netutil/net.go](https://github.com/duke-git/lancet/blob/v1/netutil/net.go)
- [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go) [https://github.com/duke-git/lancet/blob/v1/netutil/http.go](https://github.com/duke-git/lancet/blob/v1/netutil/http.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
``` ```
@@ -46,7 +46,7 @@ import (
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ConvertMapToQueryString(param map[string]any) string func ConvertMapToQueryString(param map[string]interface{}) string
``` ```
<b>Example:</b> <b>Example:</b>
@@ -55,11 +55,11 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
var m = map[string]any{ var m = map[string]interface{}{
"c": 3, "c": 3,
"a": 1, "a": 1,
"b": 2, "b": 2,
@@ -88,7 +88,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -117,7 +117,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -144,7 +144,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -184,7 +184,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -215,7 +215,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -237,10 +237,10 @@ func main() {
```go ```go
// params[0] is header which type should be http.Header or map[string]string, // params[0] is header which type should be http.Header or map[string]string,
// params[1] is query param which type should be url.Values or map[string]any, // params[1] is query param which type should be url.Values or map[string]interface{},
// params[2] is post body which type should be []byte. // params[2] is post body which type should be []byte.
// params[3] is http client which type should be http.Client. // params[3] is http client which type should be http.Client.
func HttpGet(url string, params ...any) (*http.Response, error) func HttpGet(url string, params ...interface{}) (*http.Response, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -251,7 +251,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -279,10 +279,10 @@ func main() {
```go ```go
// params[0] is header which type should be http.Header or map[string]string, // params[0] is header which type should be http.Header or map[string]string,
// params[1] is query param which type should be url.Values or map[string]any, // params[1] is query param which type should be url.Values or map[string]interface{},
// params[2] is post body which type should be []byte. // params[2] is post body which type should be []byte.
// params[3] is http client which type should be http.Client. // params[3] is http client which type should be http.Client.
func HttpPost(url string, params ...any) (*http.Response, error) func HttpPost(url string, params ...interface{}) (*http.Response, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -294,7 +294,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -328,10 +328,10 @@ func main() {
```go ```go
// params[0] is header which type should be http.Header or map[string]string, // params[0] is header which type should be http.Header or map[string]string,
// params[1] is query param which type should be url.Values or map[string]any, // params[1] is query param which type should be url.Values or map[string]interface{},
// params[2] is post body which type should be []byte. // params[2] is post body which type should be []byte.
// params[3] is http client which type should be http.Client. // params[3] is http client which type should be http.Client.
func HttpPut(url string, params ...any) (*http.Response, error) func HttpPut(url string, params ...interface{}) (*http.Response, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -343,7 +343,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -378,10 +378,10 @@ func main() {
```go ```go
// params[0] is header which type should be http.Header or map[string]string, // params[0] is header which type should be http.Header or map[string]string,
// params[1] is query param which type should be url.Values or map[string]any, // params[1] is query param which type should be url.Values or map[string]interface{},
// params[2] is post body which type should be []byte. // params[2] is post body which type should be []byte.
// params[3] is http client which type should be http.Client. // params[3] is http client which type should be http.Client.
func HttpDelete(url string, params ...any) (*http.Response, error) func HttpDelete(url string, params ...interface{}) (*http.Response, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -393,7 +393,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -417,10 +417,10 @@ func main() {
```go ```go
// params[0] is header which type should be http.Header or map[string]string, // params[0] is header which type should be http.Header or map[string]string,
// params[1] is query param which type should be url.Values or map[string]any, // params[1] is query param which type should be url.Values or map[string]interface{},
// params[2] is post body which type should be []byte. // params[2] is post body which type should be []byte.
// params[3] is http client which type should be http.Client. // params[3] is http client which type should be http.Client.
func HttpPatch(url string, params ...any) (*http.Response, error) func HttpPatch(url string, params ...interface{}) (*http.Response, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -432,7 +432,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -466,7 +466,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ParseHttpResponse(resp *http.Response, obj any) error func ParseHttpResponse(resp *http.Response, obj interface{}) error
``` ```
<b>Example:</b> <b>Example:</b>
@@ -478,7 +478,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {

View File

@@ -5,15 +5,16 @@ netutil网络包支持获取ip地址发送http请求。
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go) [https://github.com/duke-git/lancet/blob/v1/netutil/net.go](https://github.com/duke-git/lancet/blob/v1/netutil/net.go)
- [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go)
[https://github.com/duke-git/lancet/blob/v1/netutil/http.go](https://github.com/duke-git/lancet/blob/v1/netutil/http.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
``` ```
@@ -45,7 +46,7 @@ import (
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ConvertMapToQueryString(param map[string]any) string func ConvertMapToQueryString(param map[string]interface{}) string
``` ```
<b>例子:</b> <b>例子:</b>
@@ -54,11 +55,11 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
var m = map[string]any{ var m = map[string]interface{}{
"c": 3, "c": 3,
"a": 1, "a": 1,
"b": 2, "b": 2,
@@ -87,7 +88,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -115,7 +116,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -142,7 +143,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -182,7 +183,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -213,7 +214,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -235,10 +236,10 @@ func main() {
```go ```go
// params[0] http请求header类型必须是http.Header或者map[string]string // params[0] http请求header类型必须是http.Header或者map[string]string
// params[1] http查询字符串类型必须是url.Values或者map[string]any // params[1] http查询字符串类型必须是url.Values或者map[string]interface{}
// params[2] post请求体类型必须是[]byte // params[2] post请求体类型必须是[]byte
// params[3] http client类型必须是http.Client // params[3] http client类型必须是http.Client
func HttpGet(url string, params ...any) (*http.Response, error) func HttpGet(url string, params ...interface{}) (*http.Response, error)
``` ```
<b>例子:</b> <b>例子:</b>
@@ -249,7 +250,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -277,10 +278,10 @@ func main() {
```go ```go
// params[0] http请求header类型必须是http.Header或者map[string]string // params[0] http请求header类型必须是http.Header或者map[string]string
// params[1] http查询字符串类型必须是url.Values或者map[string]any // params[1] http查询字符串类型必须是url.Values或者map[string]interface{}
// params[2] post请求体类型必须是[]byte // params[2] post请求体类型必须是[]byte
// params[3] http client类型必须是http.Client // params[3] http client类型必须是http.Client
func HttpPost(url string, params ...any) (*http.Response, error) func HttpPost(url string, params ...interface{}) (*http.Response, error)
``` ```
<b>例子:</b> <b>例子:</b>
@@ -292,7 +293,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -326,10 +327,10 @@ func main() {
```go ```go
// params[0] http请求header类型必须是http.Header或者map[string]string // params[0] http请求header类型必须是http.Header或者map[string]string
// params[1] http查询字符串类型必须是url.Values或者map[string]any // params[1] http查询字符串类型必须是url.Values或者map[string]interface{}
// params[2] post请求体类型必须是[]byte // params[2] post请求体类型必须是[]byte
// params[3] http client类型必须是http.Client // params[3] http client类型必须是http.Client
func HttpPut(url string, params ...any) (*http.Response, error) func HttpPut(url string, params ...interface{}) (*http.Response, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -341,7 +342,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -376,10 +377,10 @@ func main() {
```go ```go
// params[0] http请求header类型必须是http.Header或者map[string]string // params[0] http请求header类型必须是http.Header或者map[string]string
// params[1] http查询字符串类型必须是url.Values或者map[string]any // params[1] http查询字符串类型必须是url.Values或者map[string]interface{}
// params[2] post请求体类型必须是[]byte // params[2] post请求体类型必须是[]byte
// params[3] http client类型必须是http.Client // params[3] http client类型必须是http.Client
func HttpDelete(url string, params ...any) (*http.Response, error) func HttpDelete(url string, params ...interface{}) (*http.Response, error)
``` ```
<b>例子:</b> <b>例子:</b>
@@ -391,7 +392,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -415,10 +416,10 @@ func main() {
```go ```go
// params[0] http请求header类型必须是http.Header或者map[string]string // params[0] http请求header类型必须是http.Header或者map[string]string
// params[1] http查询字符串类型必须是url.Values或者map[string]any // params[1] http查询字符串类型必须是url.Values或者map[string]interface{}
// params[2] post请求体类型必须是[]byte // params[2] post请求体类型必须是[]byte
// params[3] http client类型必须是http.Client // params[3] http client类型必须是http.Client
func HttpPatch(url string, params ...any) (*http.Response, error) func HttpPatch(url string, params ...interface{}) (*http.Response, error)
``` ```
<b>例子:</b> <b>例子:</b>
@@ -430,7 +431,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {
@@ -464,7 +465,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ParseHttpResponse(resp *http.Response, obj any) error func ParseHttpResponse(resp *http.Response, obj interface{}) error
``` ```
<b>例子:</b> <b>例子:</b>
@@ -476,7 +477,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/v2/netutil" "github.com/duke-git/lancet/netutil"
) )
func main() { func main() {

View File

@@ -5,7 +5,7 @@ Package random implements some basic functions to generate random int and string
## Source: ## Source:
- [https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go) [https://github.com/duke-git/lancet/blob/v1/random/random.go](https://github.com/duke-git/lancet/blob/v1/random/random.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ Package random implements some basic functions to generate random int and string
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/random" "github.com/duke-git/lancet/random"
) )
``` ```
@@ -45,7 +45,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/random" "github.com/duke-git/lancet/random"
) )
func main() { func main() {
@@ -70,7 +70,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/random" "github.com/duke-git/lancet/random"
) )
func main() { func main() {
@@ -96,7 +96,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/random" "github.com/duke-git/lancet/random"
) )
func main() { func main() {
@@ -123,7 +123,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/random" "github.com/duke-git/lancet/random"
) )
func main() { func main() {

View File

@@ -5,7 +5,7 @@ random随机数生成器包可以生成随机[]bytes, int, string。
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go) [https://github.com/duke-git/lancet/blob/v1/random/random.go](https://github.com/duke-git/lancet/blob/v1/random/random.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ random随机数生成器包可以生成随机[]bytes, int, string。
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/random" "github.com/duke-git/lancet/random"
) )
``` ```
@@ -46,7 +46,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/random" "github.com/duke-git/lancet/random"
) )
func main() { func main() {
@@ -71,7 +71,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/random" "github.com/duke-git/lancet/random"
) )
func main() { func main() {
@@ -97,7 +97,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/random" "github.com/duke-git/lancet/random"
) )
func main() { func main() {
@@ -123,7 +123,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/random" "github.com/duke-git/lancet/random"
) )
func main() { func main() {

View File

@@ -5,7 +5,7 @@ Package retry is for executing a function repeatedly until it was successful or
## Source: ## 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/v1/retry/retry.go](https://github.com/duke-git/lancet/blob/v1/retry/retry.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ Package retry is for executing a function repeatedly until it was successful or
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/retry" "github.com/duke-git/lancet/retry"
) )
``` ```
@@ -46,7 +46,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"github.com/duke-git/lancet/v2/retry" "github.com/duke-git/lancet/retry"
"time" "time"
) )
@@ -92,7 +92,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/v2/retry" "github.com/duke-git/lancet/retry"
) )
func main() { func main() {
@@ -134,7 +134,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/v2/retry" "github.com/duke-git/lancet/retry"
) )
func main() { func main() {
@@ -173,7 +173,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/v2/retry" "github.com/duke-git/lancet/retry"
) )
func main() { func main() {
@@ -213,7 +213,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/v2/retry" "github.com/duke-git/lancet/retry"
) )
func main() { func main() {

View File

@@ -5,7 +5,7 @@ retry重试执行函数直到函数运行成功或被context cancel。
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go) [https://github.com/duke-git/lancet/blob/v1/retry/retry.go](https://github.com/duke-git/lancet/blob/v1/retry/retry.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ retry重试执行函数直到函数运行成功或被context cancel。
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/retry" "github.com/duke-git/lancet/retry"
) )
``` ```
@@ -94,7 +94,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/v2/retry" "github.com/duke-git/lancet/retry"
) )
func main() { func main() {
@@ -136,7 +136,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/v2/retry" "github.com/duke-git/lancet/retry"
) )
func main() { func main() {
@@ -175,7 +175,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/v2/retry" "github.com/duke-git/lancet/retry"
) )
func main() { func main() {
@@ -215,7 +215,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/v2/retry" "github.com/duke-git/lancet/retry"
) )
func main() { func main() {

View File

@@ -5,7 +5,7 @@ Package slice implements some functions to manipulate slice.
## Source: ## Source:
- [https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go) [https://github.com/duke-git/lancet/blob/v1/slice/slice.go](https://github.com/duke-git/lancet/blob/v1/slice/slice.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ Package slice implements some functions to manipulate slice.
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
``` ```
@@ -28,9 +28,10 @@ import (
- [Count](#Count) - [Count](#Count)
- [Difference](#Difference) - [Difference](#Difference)
- [DifferenceBy](#DifferenceBy) - [DifferenceBy](#DifferenceBy)
- [DifferenceWith](#DifferenceWith) - [DeleteByIndex](#DeleteByIndex)
- [DeleteAt](#DeleteAt)
- [Drop](#Drop) - [Drop](#Drop)
- [Equal](#Equal)
- [EqualWith](#EqualWith)
- [Every](#Every) - [Every](#Every)
- [Filter](#Filter) - [Filter](#Filter)
- [Find](#Find) - [Find](#Find)
@@ -39,42 +40,46 @@ import (
- [ForEach](#ForEach) - [ForEach](#ForEach)
- [GroupBy](#GroupBy) - [GroupBy](#GroupBy)
- [GroupWith](#GroupWith)
- [IntSlice](#IntSlice) - [IntSlice](#IntSlice)
- [InterfaceSlice](#InterfaceSlice) - [InterfaceSlice](#InterfaceSlice)
- [Intersection](#Intersection) - [Intersection](#Intersection)
- [InsertAt](#InsertAt) - [InsertByIndex](#InsertByIndex)
- [IndexOf](#IndexOf)
- [LastIndexOf](#LastIndexOf)
- [Map](#Map) - [Map](#Map)
- [Reverse](#Reverse) - [ReverseSlice](#ReverseSlice)
- [Reduce](#Reduce) - [Reduce](#Reduce)
- [Shuffle](#Shuffle) - [Shuffle](#Shuffle)
- [SortByField](#SortByField) - [SortByField](#SortByField)
- [Some](#Some) - [Some](#Some)
- [StringSlice](#StringSlice) - [StringSlice](#StringSlice)
- [SymmetricDifference](#SymmetricDifference)
- [Unique](#Unique) - [Unique](#Unique)
- [UniqueBy](#UniqueBy)
- [Union](#Union) - [Union](#Union)
- [UpdateAt](#UpdateAt) - [UpdateByIndex](#UpdateByIndex)
- [Without](#Without) - [Without](#Without)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation ## Documentation
## Note:
1. param which type is interface{} in below functions should be slice.
### <span id="Contain">Contain</span> ### <span id="Contain">Contain</span>
<p>Check if the value is in the slice or not.</p> <p>Check if the value is in the slice or not. iterableType param can be string, map or slice.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Contain[T any](slice []T, value T) bool func Contain(iterableType interface{}, value interface{}) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -90,14 +95,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ContainSubSlice[T any](slice, subslice []T) bool func ContainSubSlice(slice interface{}, subslice interface{}) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -115,20 +120,20 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Chunk[T any](slice []T, size int) [][]T func Chunk(slice []interface{}, size int) [][]interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
arr := []string{"a", "b", "c", "d", "e"} arr := []string{"a", "b", "c", "d", "e"}
res := slice.Chunk(InterfaceSlice(arr), 3) res := slice.Chunk(InterfaceSlice(arr), 3)
fmt.Println(res) //[][]any{{"a", "b", "c"}, {"d", "e"}} fmt.Println(res) //[][]interface{}{{"a", "b", "c"}, {"d", "e"}}
} }
``` ```
@@ -140,14 +145,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Compact[T any](slice []T) []T func Compact(slice interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -163,14 +168,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Concat[T any](slice []T, values ...[]T) []T func Concat(slice interface{}, values ...interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -185,19 +190,19 @@ func main() {
### <span id="Count">Count</span> ### <span id="Count">Count</span>
<p>Count iterates over elements of slice, returns a count of all matched elements.</p> <p>Count iterates over elements of slice, returns a count of all matched elements. The function signature should be func(index int, value interface{}) bool.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Count[T any](slice []T, predicate func(index int, t T) bool) int func Count(slice, function interface{}) int
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -220,14 +225,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Difference[T comparable](slice, comparedSlice []T) []T func Difference(slice1, slice2 interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -248,14 +253,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, t T) T) []T func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -271,55 +276,29 @@ func main() {
``` ```
### <span id="DifferenceWith">DifferenceWith</span>
<p>DifferenceWith accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice.</p>
<b>Signature:</b>
```go ### <span id="DeleteByIndex">DeleteByIndex</span>
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
s1 := []int{1, 2, 3, 4, 5}
s2 := []int{4, 5, 6, 7, 8}
isDouble := func(v1, v2 int) bool {
return v2 == 2*v1
}
res := slice.DifferenceWith(s1, s2, isDouble)
fmt.Println(res) //[]int{1, 5}
}
```
### <span id="DeleteAt">DeleteAt</span>
<p>Delete the element of slice from start index to end index - 1.</p> <p>Delete the element of slice from start index to end index - 1.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func DeleteAt[T any](slice []T, start int, end ...int) func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
res1 := slice.DeleteAt([]string{"a", "b", "c", "d", "e"}, 3) res1 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 3)
fmt.Println(res1) //[]string{"a", "b", "c", "e"} fmt.Println(res1) //[]string{"a", "b", "c", "e"}
res2 := slice.DeleteAt([]string{"a", "b", "c", "d", "e"}, 0, 2) res2 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 0, 2)
fmt.Println(res2) //[]string{"c", "d", "e"} fmt.Println(res2) //[]string{"c", "d", "e"}
} }
@@ -334,14 +313,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Drop[T any](slice []T, n int) []T func Drop(slice interface{}, n int) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -358,21 +337,83 @@ func main() {
### <span id="Equal">Equal</span>
### <span id="Every">Every</span> <p>Check if two slices are equal: the same length and all elements' order and value are equal.</p>
<p>Return true if all of the values in the slice pass the predicate function.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Every[T any](slice []T, predicate func(index int, t T) bool) bool func Equal(slice1, slice2 interface{}) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}
slice3 := []int{3, 2, 1}
res1 := slice.Equal(slice1, slice2)
res2 := slice.Equal(slice1, slice3)
fmt.Println(res1) //true
fmt.Println(res2) //false
}
```
### <span id="EqualWith">EqualWith</span>
<p>Check if two slices are equal with comparator funcation.comparator signature: func(a interface{}, b interface{}) bool</p>
<b>Signature:</b>
```go
func EqualWith(slice1, slice2 interface{}, comparator interface{}) bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{2, 4, 6}
isDouble := func(a, b int) bool {
return b == a*2
}
res := slice.EqualWith(slice1, slice2, isDouble)
fmt.Println(res) //true
}
```
### <span id="Every">Every</span>
<p>Return true if all of the values in the slice pass the predicate function. The function signature should be func(index int, value interface{}) bool.</p>
<b>Signature:</b>
```go
func Every(slice, function interface{}) bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -390,19 +431,19 @@ func main() {
### <span id="Filter">Filter</span> ### <span id="Filter">Filter</span>
<p>Return all elements which match the function.</p> <p>Return all elements which match the function. Function signature should be func(index int, value interface{}) bool.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Filter[T any](slice []T, predicate func(index int, t T) bool) []T func Filter(slice, function interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -419,19 +460,19 @@ func main() {
### <span id="Find">Find</span> ### <span id="Find">Find</span>
<p>Iterates over elements of slice, returning the first one that passes a truth test on function.</p> <p>Iterates over elements of slice, returning the first one that passes a truth test on function.function signature should be func(index int, value interface{}) bool.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Find[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) func Find(slice, function interface{}) (interface{}, bool)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -450,19 +491,19 @@ func main() {
### <span id="FindLast">FindLast</span> ### <span id="FindLast">FindLast</span>
<p>iterates over elements of slice from end to begin, returning the last one that passes a truth test on function.</p> <p>iterates over elements of slice from end to begin, returning the last one that passes a truth test on function. The function signature should be func(index int, value interface{}) bool.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func FindLast[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) func FindLast(slice, function interface{}) (interface{}, bool)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -485,14 +526,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func FlattenDeep(slice any) any func FlattenDeep(slice interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -504,22 +545,20 @@ func main() {
### <span id="ForEach">ForEach</span> ### <span id="ForEach">ForEach</span>
<p>Iterates over elements of slice and invokes function for each element.</p> <p>Iterates over elements of slice and invokes function for each element, function signature should be func(index int, value interface{}).</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ForEach[T any](slice []T, iteratee func(index int, t T)) func ForEach(slice, function interface{})
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -536,19 +575,19 @@ func main() {
### <span id="GroupBy">GroupBy</span> ### <span id="GroupBy">GroupBy</span>
<p>Iterates over elements of the slice, each element will be group by criteria, returns two slices.</p> <p>Iterates over elements of the slice, each element will be group by criteria, returns two slices. The function signature should be func(index int, value interface{}) bool.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func GroupBy[T any](slice []T, groupFn func(index int, t T) bool) ([]T, []T) func GroupBy(slice, function interface{}) (interface{}, interface{})
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -566,52 +605,24 @@ func main() {
### <span id="GroupWith">GroupWith</span>
<p>Return a map composed of keys generated from the results of running each element of slice thru iteratee.</p>
<b>Signature:</b>
```go
func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []float64{6.1, 4.2, 6.3}
floor := func(num float64) float64 {
return math.Floor(num)
}
res := slice.GroupWith(nums, floor)
fmt.Println(res) //map[float64][]float64{ 4: {4.2}, 6: {6.1, 6.3},}
}
```
### <span id="IntSlice">IntSlice</span> ### <span id="IntSlice">IntSlice</span>
<p>Convert interface slice to int slice.</p> <p>Convert interface slice to int slice.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func IntSlice(slice any) []int func IntSlice(slice interface{}) []int
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
var nums = []any{1, 2, 3} var nums = []interface{}{1, 2, 3}
res := slice.IntSlice(nums) res := slice.IntSlice(nums)
fmt.Println(res) //[]int{1, 2, 3} fmt.Println(res) //[]int{1, 2, 3}
} }
@@ -626,20 +637,20 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func InterfaceSlice(slice any) []any func InterfaceSlice(slice interface{}) []interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
var nums = []int{}{1, 2, 3} var nums = []int{}{1, 2, 3}
res := slice.InterfaceSlice(nums) res := slice.InterfaceSlice(nums)
fmt.Println(res) //[]any{1, 2, 3} fmt.Println(res) //[]interface{}{1, 2, 3}
} }
``` ```
@@ -652,14 +663,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Intersection[T any](slices ...[]T) []T func Intersection(slices ...interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -673,30 +684,84 @@ func main() {
### <span id="IndexOf">IndexOf</span>
### <span id="InsertAt">InsertAt</span> <p>Returns the index at which the first occurrence of a value is found in a slice or return -1 if the value cannot be found.</p>
<p>insert the element into slice at index.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func InsertAt[T any](slice []T, index int, value any) []T func IndexOf(slice, value interface{}) int
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
)
func main() {
arr := []string{"a", "a", "b", "c"}
res1 := slice.IndexOf(arr, "a")
fmt.Println(res1) //0
res2 := slice.IndexOf(arr, "d")
fmt.Println(res2) //-1
}
```
### <span id="LastIndexOf">LastIndexOf</span>
<p>Returns the index at which the last occurrence of a value is found in a slice or return -1 if the value cannot be found.</p>
<b>Signature:</b>
```go
func LastIndexOf(slice, value interface{}) int
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
arr := []string{"a", "a", "b", "c"}
res1 := slice.LastIndexOf(arr, "a")
fmt.Println(res1) //1
res2 := slice.LastIndexOf(arr, "d")
fmt.Println(res2) //-1
}
```
### <span id="InsertByIndex">InsertByIndex</span>
<p>insert the element into slice at index.</p>
<b>Signature:</b>
```go
func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error)
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
) )
func main() { func main() {
s := []string{"a", "b", "c"} s := []string{"a", "b", "c"}
res1, _ := slice.InsertAt(s, 0, "1") res1, _ := slice.InsertByIndex(s, 0, "1")
fmt.Println(res1) //[]string{"1", "a", "b", "c"} fmt.Println(res1) //[]string{"1", "a", "b", "c"}
res2, _ := slice.InsertAt(s, 3, []string{"1", "2", "3"}) res2, _ := slice.InsertByIndex(s, 3, []string{"1", "2", "3"})
fmt.Println(res2) //[]string{"a", "b", "c", "1", "2", "3"} fmt.Println(res2) //[]string{"a", "b", "c", "1", "2", "3"}
} }
``` ```
@@ -705,19 +770,19 @@ func main() {
### <span id="Map">Map</span> ### <span id="Map">Map</span>
<p>Creates an slice of values by running each element in slice thru function.</p> <p>Creates an slice of values by running each element in slice thru function, function signature should be func(index int, value interface{}) interface{}.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Map[T any, U any](slice []T, iteratee func(index int, t T) U) []U func Map(slice, function interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -733,25 +798,25 @@ func main() {
### <span id="Reverse">Reverse</span> ### <span id="ReverseSlice">ReverseSlice</span>
<p>Reverse the elements order in slice.</p> <p>Reverse the elements order in slice.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Reverse[T any](slice []T) func ReverseSlice(slice interface{})
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
nums := []int{1, 2, 3, 4} nums := []int{1, 2, 3, 4}
slice.Reverse(nums) slice.ReverseSlice(nums)
fmt.Println(res) //[]int{4, 3, 2, 1} fmt.Println(res) //[]int{4, 3, 2, 1}
} }
``` ```
@@ -759,19 +824,19 @@ func main() {
### <span id="Reduce">Reduce</span> ### <span id="Reduce">Reduce</span>
<p>Reduce slice.</p> <p>Reduce slice, function signature should be func(index int, value1, value2 interface{}) interface{}.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Reduce[T any](slice []T, iteratee func(index int, t1, t2 T) T, initial T) T func Reduce(slice, function, zero interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -793,14 +858,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Shuffle[T any](slice []T) []T func Shuffle(slice interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -818,14 +883,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func SortByField(slice any, field string, sortType ...string) error func SortByField(slice interface{}, field string, sortType ...string) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -856,19 +921,19 @@ func main() {
### <span id="Some">Some</span> ### <span id="Some">Some</span>
<p>Return true if any of the values in the list pass the predicate function.</p> <p>Return true if any of the values in the list pass the predicate function, function signature should be func(index int, value interface{}) bool.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Some[T any](slice []T, predicate func(index int, t T) bool) bool func Some(slice, function interface{}) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -890,18 +955,18 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func StringSlice(slice any) []string func StringSlice(slice interface{}) []string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
var s = []any{"a", "b", "c"} var s = []interface{}{"a", "b", "c"}
res := slice.StringSlice(s) res := slice.StringSlice(s)
fmt.Println(res) //[]string{"a", "b", "c"} fmt.Println(res) //[]string{"a", "b", "c"}
} }
@@ -910,49 +975,20 @@ func main() {
### <span id="SymmetricDifference">SymmetricDifference</span>
<p>Create a slice whose element is in given slices, but not in both slices.</p>
<b>Signature:</b>
```go
func SymmetricDifference[T any](slices ...[]T) []T
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
s1 := []int{1, 2, 3}
s2 := []int{1, 2, 4}
s3 := []int{1, 2, 3, 5}
fmt.Println(slice.SymmetricDifference(s1)) //[]int{1, 2, 3}
fmt.Println(slice.SymmetricDifference(s1, s2)) //[]int{3, 4}
fmt.Println(slice.SymmetricDifference(s1, s2, s3)) //[]int{3, 4, 5}
}
```
### <span id="Unique">Unique</span> ### <span id="Unique">Unique</span>
<p>Remove duplicate elements in slice.</p> <p>Remove duplicate elements in slice.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Unique[T any](slice []T) []T func Unique(slice interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -963,20 +999,46 @@ func main() {
### <span id="Union">Unique</span> ### <span id="UniqueBy">UniqueBy</span>
<p>Creates a slice of unique values, in order, from all given slices. using == for equality comparisons.</p> <p>Call iteratee func with every item of slice, then remove duplicated.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Union[T any](slices ...[]T) []T func UniqueBy(slice, iteratee interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
)
func main() {
res := slice.UniqueBy([]int{1, 2, 3, 4, 5, 6}, func(val int) int {
return val % 4
})
fmt.Println(res) //[]int{1, 2, 3, 0}
}
```
### <span id="Union">Union</span>
<p>Creates a slice of unique values, in order, from all given slices. using == for equality comparisons.</p>
<b>Signature:</b>
```go
func Union(slices ...interface{}) interface{}
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -990,26 +1052,26 @@ func main() {
### <span id="UpdateAt">UpdateAt</span> ### <span id="UpdateByIndex">UpdateByIndex</span>
<p>Update the slice element at index. if param index < 0 or index >= len(slice), will return error. </p> <p>Update the slice element at index. if param index < 0 or index >= len(slice), will return error. </p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func UpdateAt[T any](slice []T, index int, value T) []T func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
s := []string{"a", "b", "c"} s := []string{"a", "b", "c"}
res1, _ := slice.UpdateAt(s, 0, "1") res1, _ := slice.UpdateByIndex(s, 0, "1")
fmt.Println(res1) //[]string{"1", "b", "c"} fmt.Println(res1) //[]string{"1", "b", "c"}
} }
``` ```
@@ -1023,14 +1085,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Without[T any](slice []T, values ...T) []T func Without(slice interface{}, values ...interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {

View File

@@ -5,7 +5,7 @@ slice包包含操作切片的方法集合。
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go) [https://github.com/duke-git/lancet/blob/v1/slice/slice.go](https://github.com/duke-git/lancet/blob/v1/slice/slice.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ slice包包含操作切片的方法集合。
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
``` ```
@@ -28,9 +28,10 @@ import (
- [Count](#Count) - [Count](#Count)
- [Difference](#Difference) - [Difference](#Difference)
- [DifferenceBy](#DifferenceBy) - [DifferenceBy](#DifferenceBy)
- [DifferenceWith](#DifferenceWith) - [DeleteByIndex](#DeleteByIndex)
- [DeleteAt](#DeleteAt)
- [Drop](#Drop) - [Drop](#Drop)
- [Equal](#Equal)
- [EqualWith](#EqualWith)
- [Every](#Every) - [Every](#Every)
- [Filter](#Filter) - [Filter](#Filter)
- [Find](#Find) - [Find](#Find)
@@ -39,22 +40,23 @@ import (
- [ForEach](#ForEach) - [ForEach](#ForEach)
- [GroupBy](#GroupBy) - [GroupBy](#GroupBy)
- [GroupWith](#GroupWith)
- [IntSlice](#IntSlice) - [IntSlice](#IntSlice)
- [InterfaceSlice](#InterfaceSlice) - [InterfaceSlice](#InterfaceSlice)
- [Intersection](#Intersection) - [Intersection](#Intersection)
- [InsertAt](#InsertAt) - [InsertByIndex](#InsertByIndex)
- [IndexOf](#IndexOf)
- [LastIndexOf](#LastIndexOf)
- [Map](#Map) - [Map](#Map)
- [Reverse](#Reverse) - [ReverseSlice](#ReverseSlice)
- [Reduce](#Reduce) - [Reduce](#Reduce)
- [Shuffle](#Shuffle) - [Shuffle](#Shuffle)
- [SortByField](#SortByField) - [SortByField](#SortByField)
- [Some](#Some) - [Some](#Some)
- [StringSlice](#StringSlice) - [StringSlice](#StringSlice)
- [SymmetricDifference](#SymmetricDifference)
- [Unique](#Unique) - [Unique](#Unique)
- [UniqueBy](#UniqueBy)
- [Union](#Union) - [Union](#Union)
- [UpdateAt](#UpdateAt) - [UpdateByIndex](#UpdateByIndex)
- [Without](#Without) - [Without](#Without)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -67,14 +69,14 @@ import (
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Contain[T any](slice []T, value T) bool func Contain(iterableType interface{}, value interface{}) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -90,14 +92,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ContainSubSlice[T any](slice, subslice []T) bool func ContainSubSlice(slice interface{}, subslice interface{}) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -115,20 +117,20 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Chunk[T any](slice []T, size int) [][]T func Chunk(slice []interface{}, size int) [][]interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
arr := []string{"a", "b", "c", "d", "e"} arr := []string{"a", "b", "c", "d", "e"}
res := slice.Chunk(InterfaceSlice(arr), 3) res := slice.Chunk(InterfaceSlice(arr), 3)
fmt.Println(res) //[][]any{{"a", "b", "c"}, {"d", "e"}} fmt.Println(res) //[][]interface{}{{"a", "b", "c"}, {"d", "e"}}
} }
``` ```
@@ -140,14 +142,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Compact[T any](slice []T) []T func Compact(slice interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -163,14 +165,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Concat[T any](slice []T, values ...[]T) []T func Concat(slice interface{}, values ...interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -185,19 +187,19 @@ func main() {
### <span id="Count">Count</span> ### <span id="Count">Count</span>
<p>遍历切片对每个元素执行函数function. 返回符合函数返回值为true的元素的个数</p> <p>遍历切片对每个元素执行函数function. 返回符合函数返回值为true的元素的个数函数签名必须是func(index int, value interface{}) bool</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Count[T any](slice []T, predicate func(index int, t T) bool) int func Count(slice, function interface{}) int
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -220,14 +222,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Difference[T comparable](slice, comparedSlice []T) []T func Difference(slice1, slice2 interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -248,14 +250,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, t T) T) []T func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -272,56 +274,28 @@ func main() {
### <span id="DifferenceWith">DifferenceWith</span>
<p>DifferenceWith 接受比较器,该比较器被调用以将切片的元素与值进行比较。 结果值的顺序和引用由第一个切片确定</p>
<b>函数签名:</b> ### <span id="DeleteByIndex">DeleteByIndex</span>
```go
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
s1 := []int{1, 2, 3, 4, 5}
s2 := []int{4, 5, 6, 7, 8}
isDouble := func(v1, v2 int) bool {
return v2 == 2*v1
}
res := slice.DifferenceWith(s1, s2, isDouble)
fmt.Println(res) //[]int{1, 5}
}
```
### <span id="DeleteAt">DeleteAt</span>
<p>删除切片中从开始索引到结束索引-1的元素</p> <p>删除切片中从开始索引到结束索引-1的元素</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func DeleteAt[T any](slice []T, start int, end ...int) func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
res1 := slice.DeleteAt([]string{"a", "b", "c", "d", "e"}, 3) res1 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 3)
fmt.Println(res1) //[]string{"a", "b", "c", "e"} fmt.Println(res1) //[]string{"a", "b", "c", "e"}
res2 := slice.DeleteAt([]string{"a", "b", "c", "d", "e"}, 0, 2) res2 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 0, 2)
fmt.Println(res2) //[]string{"c", "d", "e"} fmt.Println(res2) //[]string{"c", "d", "e"}
} }
@@ -336,14 +310,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Drop[T any](slice []T, n int) []T func Drop(slice interface{}, n int) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -360,21 +334,83 @@ func main() {
### <span id="Equal">Equal</span>
### <span id="Every">Every</span> <p>检查两个切片是否相等,相等条件:切片长度相同,元素顺序和值都相同</p>
<p>如果切片中的所有值都通过谓词函数则返回true。 函数签名应该是func(index int, value any) bool</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Every[T any](slice []T, predicate func(index int, t T) bool) bool func Equal(slice1, slice2 interface{}) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}
slice3 := []int{3, 2, 1}
res1 := slice.Equal(slice1, slice2)
res2 := slice.Equal(slice1, slice3)
fmt.Println(res1) //true
fmt.Println(res2) //false
}
```
### <span id="EqualWith">EqualWith</span>
<p>检查两个切片是否相等相等条件对两个切片的元素调用比较函数comparator返回true。 comparator函数签名: func(a interface{}, b interface{}) bool</p>
<b>函数签名:</b>
```go
func EqualWith(slice1, slice2 interface{}, comparator interface{}) bool
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{2, 4, 6}
isDouble := func(a, b int) bool {
return b == a*2
}
res := slice.EqualWith(slice1, slice2, isDouble)
fmt.Println(res) //true
}
```
### <span id="Every">Every</span>
<p>如果切片中的所有值都通过谓词函数则返回true。 函数签名应该是func(index int, value interface{}) bool</p>
<b>函数签名:</b>
```go
func Every(slice, function interface{}) bool
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -392,19 +428,19 @@ func main() {
### <span id="Filter">Filter</span> ### <span id="Filter">Filter</span>
<p>返回与函数匹配的所有元素。 函数签名应该是 func(index int, value any) bool</p> <p>返回与函数匹配的所有元素。 函数签名应该是 func(index int, value interface{}) bool</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Filter[T any](slice []T, predicate func(index int, t T) bool) []T func Filter(slice, function interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -421,19 +457,19 @@ func main() {
### <span id="Find">Find</span> ### <span id="Find">Find</span>
<p>遍历slice的元素返回第一个通过function真值测试的元素</p> <p>遍历slice的元素返回第一个通过function真值测试的元素。函数签名应该是 func(index int, value interface{}) bool</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Find[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) func Find(slice, function interface{}) (interface{}, bool)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -452,19 +488,19 @@ func main() {
### <span id="FindLast">FindLast</span> ### <span id="FindLast">FindLast</span>
<p>从头到尾遍历 slice 的元素,返回最后一个通过函数真值测试的元素。</p> <p>从头到尾遍历 slice 的元素,返回最后一个通过函数真值测试的元素。 函数签名应该是 func(index int, value interface{}) bool。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func FindLast[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) func FindLast(slice, function interface{}) (interface{}, bool)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -487,14 +523,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func FlattenDeep(slice any) any func FlattenDeep(slice interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -509,19 +545,19 @@ func main() {
### <span id="ForEach">ForEach</span> ### <span id="ForEach">ForEach</span>
<p>遍历slice的元素并为每个元素调用函数</p> <p>遍历slice的元素并为每个元素调用函数函数签名应该是func(index int, value interface{})</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ForEach[T any](slice []T, iteratee func(index int, t T)) func ForEach(slice, function interface{})
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -538,19 +574,19 @@ func main() {
### <span id="GroupBy">GroupBy</span> ### <span id="GroupBy">GroupBy</span>
<p>迭代切片的元素,每个元素将按条件分组,返回两个切片</p> <p>迭代切片的元素,每个元素将按条件分组,返回两个切片。 函数签名应该是func(index int, value interface{}) bool</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func GroupBy[T any](slice []T, groupFn func(index int, t T) bool) ([]T, []T) func GroupBy(slice, function interface{}) (interface{}, interface{})
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -567,32 +603,6 @@ func main() {
### <span id="GroupWith">GroupWith</span>
<p>创建一个mapkey是iteratee遍历slice中的每个元素返回的结果。 分组值的顺序是由他们出现在slice中的顺序确定的。每个键对应的值负责生成key的元素组成的数组。iteratee调用1个参数 (value)</p>
<b>函数签名:</b>
```go
func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []float64{6.1, 4.2, 6.3}
floor := func(num float64) float64 {
return math.Floor(num)
}
res := slice.GroupWith(nums, floor)
fmt.Println(res) //map[float64][]float64{ 4: {4.2}, 6: {6.1, 6.3},}
}
```
### <span id="IntSlice">IntSlice</span> ### <span id="IntSlice">IntSlice</span>
<p>将接口切片转换为int切片</p> <p>将接口切片转换为int切片</p>
@@ -600,18 +610,18 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func IntSlice(slice any) []int func IntSlice(slice interface{}) []int
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
var nums = []any{1, 2, 3} var nums = []interface{}{1, 2, 3}
res := slice.IntSlice(nums) res := slice.IntSlice(nums)
fmt.Println(res) //[]int{1, 2, 3} fmt.Println(res) //[]int{1, 2, 3}
} }
@@ -626,20 +636,20 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func InterfaceSlice(slice any) []any func InterfaceSlice(slice interface{}) []interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
var nums = []int{}{1, 2, 3} var nums = []int{}{1, 2, 3}
res := slice.InterfaceSlice(nums) res := slice.InterfaceSlice(nums)
fmt.Println(res) //[]any{1, 2, 3} fmt.Println(res) //[]interface{}{1, 2, 3}
} }
``` ```
@@ -652,14 +662,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Intersection[T any](slices ...[]T) []T func Intersection(slices ...interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -673,30 +683,85 @@ func main() {
### <span id="IndexOf">IndexOf</span>
### <span id="InsertAt">InsertAt</span> <p>返回在切片中找到值的第一个匹配项的索引,如果找不到值,则返回-1</p>
<p>将元素插入到索引处的切片中</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func InsertAt[T any](slice []T, index int, value any) []T func IndexOf(slice, value interface{}) int
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
)
func main() {
arr := []string{"a", "a", "b", "c"}
res1 := slice.IndexOf(arr, "a")
fmt.Println(res1) //0
res2 := slice.IndexOf(arr, "d")
fmt.Println(res2) //-1
}
```
### <span id="LastIndexOf">LastIndexOf</span>
<p>返回在切片中找到最后一个值的索引,如果找不到该值,则返回-1</p>
<b>函数签名:</b>
```go
func LastIndexOf(slice, value interface{}) int
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
arr := []string{"a", "a", "b", "c"}
res1 := slice.LastIndexOf(arr, "a")
fmt.Println(res1) //1
res2 := slice.LastIndexOf(arr, "d")
fmt.Println(res2) //-1
}
```
### <span id="InsertByIndex">InsertByIndex</span>
<p>将元素插入到索引处的切片中</p>
<b>函数签名:</b>
```go
func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error)
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
) )
func main() { func main() {
s := []string{"a", "b", "c"} s := []string{"a", "b", "c"}
res1, _ := slice.InsertAt(s, 0, "1") res1, _ := slice.InsertByIndex(s, 0, "1")
fmt.Println(res1) //[]string{"1", "a", "b", "c"} fmt.Println(res1) //[]string{"1", "a", "b", "c"}
res2, _ := slice.InsertAt(s, 3, []string{"1", "2", "3"}) res2, _ := slice.InsertByIndex(s, 3, []string{"1", "2", "3"})
fmt.Println(res2) //[]string{"a", "b", "c", "1", "2", "3"} fmt.Println(res2) //[]string{"a", "b", "c", "1", "2", "3"}
} }
``` ```
@@ -705,19 +770,19 @@ func main() {
### <span id="Map">Map</span> ### <span id="Map">Map</span>
<p>通过运行函数slice中的每个元素来创建一个切片</p> <p>通过运行函数slice中的每个元素来创建一个切片函数签名应该是func(index int, value interface{}) interface{}。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Map[T any, U any](slice []T, iteratee func(index int, t T) U) []U func Map(slice, function interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -733,25 +798,25 @@ func main() {
### <span id="Reverse">Reverse</span> ### <span id="ReverseSlice">ReverseSlice</span>
<p>反转切片中的元素顺序</p> <p>反转切片中的元素顺序</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Reverse[T any](slice []T) func ReverseSlice(slice interface{})
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
nums := []int{1, 2, 3, 4} nums := []int{1, 2, 3, 4}
slice.Reverse(nums) slice.ReverseSlice(nums)
fmt.Println(res) //[]int{4, 3, 2, 1} fmt.Println(res) //[]int{4, 3, 2, 1}
} }
``` ```
@@ -759,19 +824,19 @@ func main() {
### <span id="Reduce">Reduce</span> ### <span id="Reduce">Reduce</span>
<p>将slice中的元素依次运行函数,返回运行结果</p> <p>将slice中的元素运行函数返回运行结果。函数签名应该是func(index int, value1, value2 interface{}) interface{}。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Reduce[T any](slice []T, iteratee func(index int, t1, t2 T) T, initial T) T func Reduce(slice, function, zero interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -793,14 +858,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Shuffle[T any](slice []T) []T func Shuffle(slice interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -818,14 +883,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func SortByField(slice any, field string, sortType ...string) error func SortByField(slice interface{}, field string, sortType ...string) error
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -856,19 +921,19 @@ func main() {
### <span id="Some">Some</span> ### <span id="Some">Some</span>
<p>如果列表中的任何值通过谓词函数则返回true</p> <p>如果列表中的任何值通过谓词函数则返回true函数签名应该是func(index int, value interface{}) bool .</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Some[T any](slice []T, predicate func(index int, t T) bool) bool func Some(slice, function interface{}) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -890,18 +955,18 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func StringSlice(slice any) []string func StringSlice(slice interface{}) []string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
var s = []any{"a", "b", "c"} var s = []interface{}{"a", "b", "c"}
res := slice.StringSlice(s) res := slice.StringSlice(s)
fmt.Println(res) //[]string{"a", "b", "c"} fmt.Println(res) //[]string{"a", "b", "c"}
} }
@@ -910,48 +975,20 @@ func main() {
### <span id="SymmetricDifference">SymmetricDifference</span>
<p>返回一个切片,其中的元素存在于参数切片中,但不同时存储在于参数切片中(交集取反)</p>
<b>函数签名:</b>
```go
func SymmetricDifference[T any](slices ...[]T) []T
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
s1 := []int{1, 2, 3}
s2 := []int{1, 2, 4}
s3 := []int{1, 2, 3, 5}
fmt.Println(slice.SymmetricDifference(s1)) //[]int{1, 2, 3}
fmt.Println(slice.SymmetricDifference(s1, s2)) //[]int{3, 4}
fmt.Println(slice.SymmetricDifference(s1, s2, s3)) //[]int{3, 4, 5}
}
```
### <span id="Unique">Unique</span> ### <span id="Unique">Unique</span>
<p>删除切片中的重复元素</p> <p>删除切片中的重复元素</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Unique[T any](slice []T) []T func Unique(slice interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -962,20 +999,45 @@ func main() {
### <span id="Union">Unique</span> ### <span id="UniqueBy">UniqueBy</span>
<p>从所有给定的切片按顺序创建一个唯一值切片。 使用 == 进行相等比较。</p> <p>对切片的每个项目调用iteratee函数然后删除重复的</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Union[T any](slices ...[]T) []T func UniqueBy(slice, iteratee interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
)
func main() {
res := slice.UniqueBy([]int{1, 2, 3, 4, 5, 6}, func(val int) int {
return val % 4
})
fmt.Println(res) //[]int{1, 2, 3, 0}
}
```
### <span id="Union">Union</span>
<p>从所有给定的切片按顺序创建一个唯一值切片。 使用 == 进行相等比较。</p>
<b>函数签名:</b>
```go
func Union(slices ...interface{}) interface{}
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
) )
func main() { func main() {
@@ -989,26 +1051,26 @@ func main() {
### <span id="UpdateAt">UpdateAt</span> ### <span id="UpdateByIndex">UpdateByIndex</span>
<p>更新索引处的切片元素。 如果 param index < 0 或 index >= len(slice),将返回错误</p> <p>更新索引处的切片元素。 如果 param index < 0 或 index >= len(slice),将返回错误</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func UpdateAt[T any](slice []T, index int, value T) []T func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {
s := []string{"a", "b", "c"} s := []string{"a", "b", "c"}
res1, _ := slice.UpdateAt(s, 0, "1") res1, _ := slice.UpdateByIndex(s, 0, "1")
fmt.Println(res1) //[]string{"1", "b", "c"} fmt.Println(res1) //[]string{"1", "b", "c"}
} }
``` ```
@@ -1022,14 +1084,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Without[T any](slice []T, values ...T) []T func Without(slice interface{}, values ...interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/slice"
) )
func main() { func main() {

View File

@@ -5,7 +5,7 @@ Package strutil contains some functions to manipulate string.
## Source: ## Source:
- [https://github.com/duke-git/lancet/blob/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/strutil/string.go) [https://github.com/duke-git/lancet/blob/v1/strutil/string.go](https://github.com/duke-git/lancet/blob/v1/strutil/string.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ Package strutil contains some functions to manipulate string.
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
``` ```
@@ -37,6 +37,7 @@ import (
- [Wrap](#Wrap) - [Wrap](#Wrap)
- [Unwrap](#Unwrap) - [Unwrap](#Unwrap)
- [SplitEx](#SplitEx)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -57,7 +58,7 @@ func After(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -87,7 +88,7 @@ func AfterLast(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -118,7 +119,7 @@ func Before(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -149,7 +150,7 @@ func BeforeLast(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -180,7 +181,7 @@ func CamelCase(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -214,7 +215,7 @@ func Capitalize(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -237,14 +238,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func IsString(v any) bool func IsString(v interface{}) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -272,7 +273,7 @@ func KebabCase(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -306,7 +307,7 @@ func LowerFirst(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -340,7 +341,7 @@ func UpperFirst(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -374,7 +375,7 @@ func PadEnd(source string, size int, padStr string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -408,7 +409,7 @@ func PadStart(source string, size int, padStr string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -442,7 +443,7 @@ func ReverseStr(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -469,7 +470,7 @@ func SnakeCase(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -506,7 +507,7 @@ func Wrap(str string, wrapWith string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -543,7 +544,7 @@ func Unwrap(str string, wrapToken string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -566,7 +567,39 @@ func main() {
### <span id="SplitEx">SplitEx</span>
<p>Split a given string whether the result contains empty string.</p>
<b>Signature:</b>
```go
func SplitEx(s, sep string, removeEmptyString bool) []string
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/strutil"
)
func main() {
arr1 := strutil.SplitEx(" a b c ", "", true)
fmt.Println(arr1) //[]string{}
arr2 := strutil.SplitEx(" a b c ", " ", false)
fmt.Println(arr2) //[]string{"", "a", "b", "c", ""}
arr3 := strutil.SplitEx(" a b c ", " ", true)
fmt.Println(arr3) //[]string{"a", "b", "c"}
arr4 := strutil.SplitEx(" a = b = c = ", " = ", false)
fmt.Println(arr4) //[]string{" a", "b", "c", ""}
arr5 := strutil.SplitEx(" a = b = c = ", " = ", true)
fmt.Println(arr5) //[]string{" a", "b", "c"}
}
```

View File

@@ -5,7 +5,7 @@ strutil包含处理字符串的相关函数。
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/strutil/string.go) [https://github.com/duke-git/lancet/blob/v1/strutil/string.go](https://github.com/duke-git/lancet/blob/v1/strutil/string.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ strutil包含处理字符串的相关函数。
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
``` ```
@@ -37,6 +37,7 @@ import (
- [Wrap](#Wrap) - [Wrap](#Wrap)
- [Unwrap](#Unwrap) - [Unwrap](#Unwrap)
- [SplitEx](#SplitEx)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -58,7 +59,7 @@ func After(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -88,7 +89,7 @@ func AfterLast(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -119,7 +120,7 @@ func Before(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -150,7 +151,7 @@ func BeforeLast(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -181,7 +182,7 @@ func CamelCase(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -215,7 +216,7 @@ func Capitalize(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -238,14 +239,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func IsString(v any) bool func IsString(v interface{}) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -273,7 +274,7 @@ func KebabCase(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -307,7 +308,7 @@ func LowerFirst(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -341,7 +342,7 @@ func UpperFirst(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -375,7 +376,7 @@ func PadEnd(source string, size int, padStr string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -409,7 +410,7 @@ func PadStart(source string, size int, padStr string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -443,7 +444,7 @@ func ReverseStr(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -470,7 +471,7 @@ func SnakeCase(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -507,7 +508,7 @@ func Wrap(str string, wrapWith string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -544,7 +545,7 @@ func Unwrap(str string, wrapToken string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/strutil" "github.com/duke-git/lancet/strutil"
) )
func main() { func main() {
@@ -567,6 +568,39 @@ func main() {
### <span id="SplitEx">SplitEx</span>
<p>分割字符串为切片removeEmptyString参数指定是否去除空字符串</p>
<b>函数签名:</b>
```go
func SplitEx(s, sep string, removeEmptyString bool) []string
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/strutil"
)
func main() {
arr1 := strutil.SplitEx(" a b c ", "", true)
fmt.Println(arr1) //[]string{}
arr2 := strutil.SplitEx(" a b c ", " ", false)
fmt.Println(arr2) //[]string{"", "a", "b", "c", ""}
arr3 := strutil.SplitEx(" a b c ", " ", true)
fmt.Println(arr3) //[]string{"a", "b", "c"}
arr4 := strutil.SplitEx(" a = b = c = ", " = ", false)
fmt.Println(arr4) //[]string{" a", "b", "c", ""}
arr5 := strutil.SplitEx(" a = b = c = ", " = ", true)
fmt.Println(arr5) //[]string{" a", "b", "c"}
}
```

View File

@@ -5,7 +5,7 @@ Package system contains some functions about os, runtime, shell command.
## Source: ## 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/v1/system/os.go](https://github.com/duke-git/lancet/blob/v1/system/os.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ Package system contains some functions about os, runtime, shell command.
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
``` ```
@@ -48,7 +48,7 @@ func IsWindows() bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -73,7 +73,7 @@ func IsLinux() bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -97,7 +97,7 @@ func IsMac() bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -121,7 +121,7 @@ func GetOsEnv(key string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -145,7 +145,7 @@ func SetOsEnv(key, value string) error
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -170,7 +170,7 @@ func RemoveOsEnv(key string) error
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -196,7 +196,7 @@ func CompareOsEnv(key, comparedEnv string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -222,7 +222,7 @@ func ExecCommand(command string) (stdout, stderr string, err error)
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {

View File

@@ -5,7 +5,7 @@ system包含os, runtime, shell command相关函数。
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go) [https://github.com/duke-git/lancet/blob/v1/system/os.go](https://github.com/duke-git/lancet/blob/v1/system/os.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ system包含os, runtime, shell command相关函数。
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
``` ```
@@ -48,7 +48,7 @@ func IsWindows() bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -73,7 +73,7 @@ func IsLinux() bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -97,7 +97,7 @@ func IsMac() bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -121,7 +121,7 @@ func GetOsEnv(key string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -145,7 +145,7 @@ func SetOsEnv(key, value string) error
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -170,7 +170,7 @@ func RemoveOsEnv(key string) error
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -196,7 +196,7 @@ func CompareOsEnv(key, comparedEnv string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
@@ -222,7 +222,7 @@ func ExecCommand(command string) (stdout, stderr string, err error)
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {

View File

@@ -5,7 +5,7 @@ Package validator contains some functions for data validation.
## Source: ## Source:
- [https://github.com/duke-git/lancet/blob/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/validator/validator.go) [https://github.com/duke-git/lancet/blob/v1/validator/validator.go](https://github.com/duke-git/lancet/blob/v1/validator/validator.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ Package validator contains some functions for data validation.
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
``` ```
@@ -67,7 +67,7 @@ func ContainChinese(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -97,7 +97,7 @@ func ContainLetter(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -128,7 +128,7 @@ func ContainLower(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -159,7 +159,7 @@ func ContainUpper(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -190,7 +190,7 @@ func IsAlpha(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -218,7 +218,7 @@ func IsAllUpper(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -246,7 +246,7 @@ func IsAllLower(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -274,7 +274,7 @@ func IsBase64(base64 string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -302,7 +302,7 @@ func IsChineseMobile(mobileNum string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -329,7 +329,7 @@ func IsChineseIdNum(id string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -357,7 +357,7 @@ func IsChinesePhone(phone string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -385,7 +385,7 @@ func IsCreditCard(creditCart string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -413,7 +413,7 @@ func IsDns(dns string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -444,7 +444,7 @@ func IsEmail(email string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -473,7 +473,7 @@ func IsEmptyString(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -501,7 +501,7 @@ func IsFloatStr(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -530,7 +530,7 @@ func IsNumberStr(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -559,7 +559,7 @@ func IsJSON(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -588,7 +588,7 @@ func IsRegexMatch(s, regex string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -614,7 +614,7 @@ func IsIntStr(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -641,7 +641,7 @@ func IsIp(ipstr string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -668,7 +668,7 @@ func IsIpV4(ipstr string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -695,7 +695,7 @@ func IsIpV6(ipstr string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -722,7 +722,7 @@ func IsStrongPassword(password string, length int) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -750,7 +750,7 @@ func IsUrl(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -778,7 +778,7 @@ func IsWeakPassword(password string, length int) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {

View File

@@ -5,7 +5,7 @@ validator验证器包包含常用字符串格式验证函数。
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/validator/validator.go) [https://github.com/duke-git/lancet/blob/v1/validator/validator.go](https://github.com/duke-git/lancet/blob/v1/validator/validator.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ validator验证器包包含常用字符串格式验证函数。
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
``` ```
@@ -67,7 +67,7 @@ func ContainChinese(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -97,7 +97,7 @@ func ContainLetter(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -128,7 +128,7 @@ func ContainLower(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -159,7 +159,7 @@ func ContainUpper(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -190,7 +190,7 @@ func IsAlpha(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -218,7 +218,7 @@ func IsAllUpper(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -246,7 +246,7 @@ func IsAllLower(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -274,7 +274,7 @@ func IsBase64(base64 string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -302,7 +302,7 @@ func IsChineseMobile(mobileNum string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -329,7 +329,7 @@ func IsChineseIdNum(id string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -357,7 +357,7 @@ func IsChinesePhone(phone string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -385,7 +385,7 @@ func IsCreditCard(creditCart string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -413,7 +413,7 @@ func IsDns(dns string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -444,7 +444,7 @@ func IsEmail(email string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -473,7 +473,7 @@ func IsEmptyString(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -501,7 +501,7 @@ func IsFloatStr(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -530,7 +530,7 @@ func IsNumberStr(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -559,7 +559,7 @@ func IsJSON(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -588,7 +588,7 @@ func IsRegexMatch(s, regex string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -614,7 +614,7 @@ func IsIntStr(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -641,7 +641,7 @@ func IsIp(ipstr string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -668,7 +668,7 @@ func IsIpV4(ipstr string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -695,7 +695,7 @@ func IsIpV6(ipstr string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -722,7 +722,7 @@ func IsStrongPassword(password string, length int) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -750,7 +750,7 @@ func IsUrl(str string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {
@@ -778,7 +778,7 @@ func IsWeakPassword(password string, length int) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/validator"
) )
func main() { func main() {

View File

@@ -1,57 +0,0 @@
# 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)
<div STYLE="page-break-after: always;"></div>
## Usage:
```go
import (
"github.com/duke-git/lancet/v2/xerror"
)
```
<div STYLE="page-break-after: always;"></div>
## Index
- [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>
```go
func Unwrap[T any](val T, err error) T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/xerror"
)
func main() {
_, err := strconv.Atoi("4o2")
defer func() {
v := recover()
fmt.Println(err.Error()) // err.Error() == v.(*strconv.NumError).Error()
}()
xerror.Unwrap(strconv.Atoi("4o2"))
}
```

View File

@@ -1,57 +0,0 @@
# 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)
<div STYLE="page-break-after: always;"></div>
## 用法:
```go
import (
"github.com/duke-git/lancet/v2/xerror"
)
```
<div STYLE="page-break-after: always;"></div>
## 目录
- [Unwrap](#Unwrap)
<div STYLE="page-break-after: always;"></div>
## 文档
### <span id="Unwrap">Unwrap</span>
<p>如果err为nil则展开则它返回一个有效值。 如果err不是nil则Unwrap使用err发生恐慌。</p>
<b>函数签名:</b>
```go
func Unwrap[T any](val T, err error) T
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/xerror"
)
func main() {
_, err := strconv.Atoi("4o2")
defer func() {
v := recover()
fmt.Println(err.Error()) // err.Error() == v.(*strconv.NumError).Error()
}()
xerror.Unwrap(strconv.Atoi("4o2"))
}
```

View File

@@ -13,6 +13,7 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os" "os"
"path"
"path/filepath" "path/filepath"
"strings" "strings"
) )
@@ -40,6 +41,11 @@ func CreateFile(path string) bool {
return true return true
} }
// CreateDir create directory in absolute path. param `absPath` like /a/, /a/b/
func CreateDir(absPath string) error {
return os.MkdirAll(path.Dir(absPath), os.ModePerm)
}
// IsDir checks if the path is directory or not // IsDir checks if the path is directory or not
func IsDir(path string) bool { func IsDir(path string) bool {
file, err := os.Stat(path) file, err := os.Stat(path)
@@ -263,7 +269,7 @@ func FileMode(path string) (fs.FileMode, error) {
// MiMeType return file mime type // MiMeType return file mime type
// param `file` should be string(file path) or *os.File // param `file` should be string(file path) or *os.File
func MiMeType(file any) string { func MiMeType(file interface{}) string {
var mediatype string var mediatype string
readBuffer := func(f *os.File) ([]byte, error) { readBuffer := func(f *os.File) ([]byte, error) {

View File

@@ -4,7 +4,7 @@ import (
"os" "os"
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestIsExist(t *testing.T) { func TestIsExist(t *testing.T) {
@@ -33,6 +33,27 @@ func TestCreateFile(t *testing.T) {
os.Remove(f) os.Remove(f)
} }
func TestCreateDir(t *testing.T) {
assert := internal.NewAssert(t, "TestCreateDir")
pwd, err := os.Getwd()
if err != nil {
t.Error(err)
t.FailNow()
}
dirPath := pwd + "/a/"
err = CreateDir(dirPath)
if err != nil {
t.Error(err)
t.FailNow()
}
assert.Equal(true, IsExist(dirPath))
os.Remove(dirPath)
assert.Equal(false, IsExist(dirPath))
}
func TestIsDir(t *testing.T) { func TestIsDir(t *testing.T) {
assert := internal.NewAssert(t, "TestIsDir") assert := internal.NewAssert(t, "TestIsDir")
@@ -76,10 +97,10 @@ func TestCopyFile(t *testing.T) {
func TestListFileNames(t *testing.T) { func TestListFileNames(t *testing.T) {
assert := internal.NewAssert(t, "TestListFileNames") assert := internal.NewAssert(t, "TestListFileNames")
filesInPath, err := ListFileNames("./") filesInPath, err := ListFileNames("../datetime/")
assert.IsNil(err) assert.IsNil(err)
expected := []string{"file.go", "file_test.go"} expected := []string{"conversion.go", "conversion_test.go", "datetime.go", "datetime_test.go"}
assert.Equal(expected, filesInPath) assert.Equal(expected, filesInPath)
} }

View File

@@ -7,7 +7,7 @@ package formatter
import "strings" import "strings"
// Comma add comma to number by every 3 numbers from right. ahead by symbol char // Comma add comma to number by every 3 numbers from right. ahead by symbol char
func Comma(v any, symbol string) string { func Comma(v interface{}, symbol string) string {
s := numString(v) s := numString(v)
dotIndex := strings.Index(s, ".") dotIndex := strings.Index(s, ".")
if dotIndex != -1 { if dotIndex != -1 {

View File

@@ -14,7 +14,7 @@ func commaString(s string) string {
return commaString(s[:len(s)-3]) + "," + commaString(s[len(s)-3:]) return commaString(s[:len(s)-3]) + "," + commaString(s[len(s)-3:])
} }
func numString(value any) string { func numString(value interface{}) string {
switch reflect.TypeOf(value).Kind() { switch reflect.TypeOf(value).Kind() {
case reflect.Int, reflect.Int64, reflect.Float32, reflect.Float64: case reflect.Int, reflect.Int64, reflect.Float32, reflect.Float64:
return fmt.Sprintf("%v", value) return fmt.Sprintf("%v", value)

View File

@@ -3,7 +3,7 @@ package formatter
import ( import (
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestComma(t *testing.T) { func TestComma(t *testing.T) {

View File

@@ -10,11 +10,11 @@ import (
) )
// After creates a function that invokes func once it's called n or more times // After creates a function that invokes func once it's called n or more times
func After(n int, fn any) func(args ...any) []reflect.Value { func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
// Catch programming error while constructing the closure // Catch programming error while constructing the closure
mustBeFunction(fn) mustBeFunction(fn)
return func(args ...any) []reflect.Value { return func(args ...interface{}) []reflect.Value {
n-- n--
if n < 1 { if n < 1 {
return unsafeInvokeFunc(fn, args...) return unsafeInvokeFunc(fn, args...)
@@ -24,11 +24,11 @@ func After(n int, fn any) func(args ...any) []reflect.Value {
} }
// Before creates a function that invokes func once it's called less than n times // Before creates a function that invokes func once it's called less than n times
func Before(n int, fn any) func(args ...any) []reflect.Value { func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
// Catch programming error while constructing the closure // Catch programming error while constructing the closure
mustBeFunction(fn) mustBeFunction(fn)
var res []reflect.Value var res []reflect.Value
return func(args ...any) []reflect.Value { return func(args ...interface{}) []reflect.Value {
if n > 0 { if n > 0 {
res = unsafeInvokeFunc(fn, args...) res = unsafeInvokeFunc(fn, args...)
} }
@@ -40,20 +40,20 @@ func Before(n int, fn any) func(args ...any) []reflect.Value {
} }
} }
// Fn is for curry function which is func(...any) any // Fn is for curry function which is func(...interface{}) interface{}
type Fn func(...any) any type Fn func(...interface{}) interface{}
// Curry make a curry function // Curry make a curry function
func (f Fn) Curry(i any) func(...any) any { func (f Fn) Curry(i interface{}) func(...interface{}) interface{} {
return func(values ...any) any { return func(values ...interface{}) interface{} {
v := append([]any{i}, values...) v := append([]interface{}{i}, values...)
return f(v...) return f(v...)
} }
} }
// Compose compose the functions from right to left // Compose compose the functions from right to left
func Compose(fnList ...func(...any) any) func(...any) any { func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{} {
return func(s ...any) any { return func(s ...interface{}) interface{} {
f := fnList[0] f := fnList[0]
restFn := fnList[1:] restFn := fnList[1:]
@@ -66,7 +66,7 @@ func Compose(fnList ...func(...any) any) func(...any) any {
} }
// Delay make the function execution after delayed time // Delay make the function execution after delayed time
func Delay(delay time.Duration, fn any, args ...any) { func Delay(delay time.Duration, fn interface{}, args ...interface{}) {
// Catch programming error while constructing the closure // Catch programming error while constructing the closure
mustBeFunction(fn) mustBeFunction(fn)
@@ -95,7 +95,7 @@ func Debounced(fn func(), duration time.Duration) func() {
} }
// Schedule invoke function every duration time, util close the returned bool chan // Schedule invoke function every duration time, util close the returned bool chan
func Schedule(d time.Duration, fn any, args ...any) chan bool { func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool {
// Catch programming error while constructing the closure // Catch programming error while constructing the closure
mustBeFunction(fn) mustBeFunction(fn)

View File

@@ -5,7 +5,7 @@ import (
"reflect" "reflect"
) )
func invokeFunc(fn any, args ...any) []reflect.Value { func invokeFunc(fn interface{}, args ...interface{}) []reflect.Value {
fv := functionValue(fn) fv := functionValue(fn)
params := make([]reflect.Value, len(args)) params := make([]reflect.Value, len(args))
for i, item := range args { for i, item := range args {
@@ -14,7 +14,7 @@ func invokeFunc(fn any, args ...any) []reflect.Value {
return fv.Call(params) return fv.Call(params)
} }
func unsafeInvokeFunc(fn any, args ...any) []reflect.Value { func unsafeInvokeFunc(fn interface{}, args ...interface{}) []reflect.Value {
fv := reflect.ValueOf(fn) fv := reflect.ValueOf(fn)
params := make([]reflect.Value, len(args)) params := make([]reflect.Value, len(args))
for i, item := range args { for i, item := range args {
@@ -23,7 +23,7 @@ func unsafeInvokeFunc(fn any, args ...any) []reflect.Value {
return fv.Call(params) return fv.Call(params)
} }
func functionValue(function any) reflect.Value { func functionValue(function interface{}) reflect.Value {
v := reflect.ValueOf(function) v := reflect.ValueOf(function)
if v.Kind() != reflect.Func { if v.Kind() != reflect.Func {
panic(fmt.Sprintf("Invalid function type, value of type %T", function)) panic(fmt.Sprintf("Invalid function type, value of type %T", function))
@@ -31,7 +31,7 @@ func functionValue(function any) reflect.Value {
return v return v
} }
func mustBeFunction(function any) { func mustBeFunction(function interface{}) {
v := reflect.ValueOf(function) v := reflect.ValueOf(function)
if v.Kind() != reflect.Func { if v.Kind() != reflect.Func {
panic(fmt.Sprintf("Invalid function type, value of type %T", function)) panic(fmt.Sprintf("Invalid function type, value of type %T", function))

View File

@@ -7,7 +7,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestAfter(t *testing.T) { func TestAfter(t *testing.T) {
@@ -16,7 +16,7 @@ func TestAfter(t *testing.T) {
fmt.Println("print done") fmt.Println("print done")
return i return i
}) })
type cb func(args ...any) []reflect.Value type cb func(args ...interface{}) []reflect.Value
print := func(i int, s string, fn cb) { print := func(i int, s string, fn cb) {
fmt.Printf("print: arr[%d] is %s \n", i, s) fmt.Printf("print: arr[%d] is %s \n", i, s)
v := fn(i) v := fn(i)
@@ -42,7 +42,7 @@ func TestBefore(t *testing.T) {
}) })
var res []int64 var res []int64
type cb func(args ...any) []reflect.Value type cb func(args ...interface{}) []reflect.Value
appendStr := func(i int, s string, fn cb) { appendStr := func(i int, s string, fn cb) {
v := fn(i) v := fn(i)
res = append(res, v[0].Int()) res = append(res, v[0].Int())
@@ -62,7 +62,7 @@ func TestCurry(t *testing.T) {
add := func(a, b int) int { add := func(a, b int) int {
return a + b return a + b
} }
var addCurry Fn = func(values ...any) any { var addCurry Fn = func(values ...interface{}) interface{} {
return add(values[0].(int), values[1].(int)) return add(values[0].(int), values[1].(int))
} }
add1 := addCurry.Curry(1) add1 := addCurry.Curry(1)
@@ -72,10 +72,10 @@ func TestCurry(t *testing.T) {
func TestCompose(t *testing.T) { func TestCompose(t *testing.T) {
assert := internal.NewAssert(t, "TestCompose") assert := internal.NewAssert(t, "TestCompose")
toUpper := func(a ...any) any { toUpper := func(a ...interface{}) interface{} {
return strings.ToUpper(a[0].(string)) return strings.ToUpper(a[0].(string))
} }
toLower := func(a ...any) any { toLower := func(a ...interface{}) interface{} {
return strings.ToLower(a[0].(string)) return strings.ToLower(a[0].(string))
} }

View File

@@ -3,7 +3,7 @@ package function
import ( import (
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestWatcher(t *testing.T) { func TestWatcher(t *testing.T) {

4
go.mod
View File

@@ -1,3 +1,3 @@
module github.com/duke-git/lancet/v2 module github.com/duke-git/lancet
go 1.18 go 1.16

View File

@@ -30,14 +30,14 @@ func NewAssert(t *testing.T, caseName string) *Assert {
} }
// Equal check if expected is equal with actual // Equal check if expected is equal with actual
func (a *Assert) Equal(expected, actual any) { func (a *Assert) Equal(expected, actual interface{}) {
if compare(expected, actual) != compareEqual { if compare(expected, actual) != compareEqual {
makeTestFailed(a.T, a.CaseName, expected, actual) makeTestFailed(a.T, a.CaseName, expected, actual)
} }
} }
// NotEqual check if expected is not equal with actual // NotEqual check if expected is not equal with actual
func (a *Assert) NotEqual(expected, actual any) { func (a *Assert) NotEqual(expected, actual interface{}) {
if compare(expected, actual) == compareEqual { if compare(expected, actual) == compareEqual {
expectedInfo := fmt.Sprintf("not %v", expected) expectedInfo := fmt.Sprintf("not %v", expected)
makeTestFailed(a.T, a.CaseName, expectedInfo, actual) makeTestFailed(a.T, a.CaseName, expectedInfo, actual)
@@ -45,7 +45,7 @@ func (a *Assert) NotEqual(expected, actual any) {
} }
// Greater check if expected is greate than actual // Greater check if expected is greate than actual
func (a *Assert) Greater(expected, actual any) { func (a *Assert) Greater(expected, actual interface{}) {
if compare(expected, actual) != compareGreater { if compare(expected, actual) != compareGreater {
expectedInfo := fmt.Sprintf("> %v", expected) expectedInfo := fmt.Sprintf("> %v", expected)
makeTestFailed(a.T, a.CaseName, expectedInfo, actual) makeTestFailed(a.T, a.CaseName, expectedInfo, actual)
@@ -53,7 +53,7 @@ func (a *Assert) Greater(expected, actual any) {
} }
// GreaterOrEqual check if expected is greate than or equal with actual // GreaterOrEqual check if expected is greate than or equal with actual
func (a *Assert) GreaterOrEqual(expected, actual any) { func (a *Assert) GreaterOrEqual(expected, actual interface{}) {
isGreatOrEqual := compare(expected, actual) == compareGreater || compare(expected, actual) == compareEqual isGreatOrEqual := compare(expected, actual) == compareGreater || compare(expected, actual) == compareEqual
if !isGreatOrEqual { if !isGreatOrEqual {
expectedInfo := fmt.Sprintf(">= %v", expected) expectedInfo := fmt.Sprintf(">= %v", expected)
@@ -62,7 +62,7 @@ func (a *Assert) GreaterOrEqual(expected, actual any) {
} }
// Less check if expected is less than actual // Less check if expected is less than actual
func (a *Assert) Less(expected, actual any) { func (a *Assert) Less(expected, actual interface{}) {
if compare(expected, actual) != compareLess { if compare(expected, actual) != compareLess {
expectedInfo := fmt.Sprintf("< %v", expected) expectedInfo := fmt.Sprintf("< %v", expected)
makeTestFailed(a.T, a.CaseName, expectedInfo, actual) makeTestFailed(a.T, a.CaseName, expectedInfo, actual)
@@ -70,7 +70,7 @@ func (a *Assert) Less(expected, actual any) {
} }
// LessOrEqual check if expected is less than or equal with actual // LessOrEqual check if expected is less than or equal with actual
func (a *Assert) LessOrEqual(expected, actual any) { func (a *Assert) LessOrEqual(expected, actual interface{}) {
isLessOrEqual := compare(expected, actual) == compareLess || compare(expected, actual) == compareEqual isLessOrEqual := compare(expected, actual) == compareLess || compare(expected, actual) == compareEqual
if !isLessOrEqual { if !isLessOrEqual {
expectedInfo := fmt.Sprintf("<= %v", expected) expectedInfo := fmt.Sprintf("<= %v", expected)
@@ -79,14 +79,14 @@ func (a *Assert) LessOrEqual(expected, actual any) {
} }
// IsNil check if value is nil // IsNil check if value is nil
func (a *Assert) IsNil(value any) { func (a *Assert) IsNil(value interface{}) {
if value != nil { if value != nil {
makeTestFailed(a.T, a.CaseName, nil, value) makeTestFailed(a.T, a.CaseName, nil, value)
} }
} }
// IsNotNil check if value is not nil // IsNotNil check if value is not nil
func (a *Assert) IsNotNil(value any) { func (a *Assert) IsNotNil(value interface{}) {
if value == nil { if value == nil {
makeTestFailed(a.T, a.CaseName, "not nil", value) makeTestFailed(a.T, a.CaseName, "not nil", value)
} }
@@ -94,7 +94,7 @@ func (a *Assert) IsNotNil(value any) {
// compare x and y return : // compare x and y return :
// x > y -> 1, x < y -> -1, x == y -> 0, x != y -> -2 // x > y -> 1, x < y -> -1, x == y -> 0, x != y -> -2
func compare(x, y any) int { func compare(x, y interface{}) int {
vx := reflect.ValueOf(x) vx := reflect.ValueOf(x)
vy := reflect.ValueOf(y) vy := reflect.ValueOf(y)
@@ -163,7 +163,7 @@ func compare(x, y any) int {
} }
// logFailedInfo make test failed and log error info // logFailedInfo make test failed and log error info
func makeTestFailed(t *testing.T, caseName string, expected, actual any) { func makeTestFailed(t *testing.T, caseName string, expected, actual interface{}) {
_, file, line, _ := runtime.Caller(2) _, file, line, _ := runtime.Caller(2)
errInfo := fmt.Sprintf("Case %v failed. file: %v, line: %v, expected: %v, actual: %v.", caseName, file, line, expected, actual) errInfo := fmt.Sprintf("Case %v failed. file: %v, line: %v, expected: %v, actual: %v.", caseName, file, line, expected, actual)
t.Error(errInfo) t.Error(errInfo)

View File

@@ -1,18 +0,0 @@
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
// Use of this source code is governed by MIT license
// Package lancetconstraints contain some comstomer constraints.
package lancetconstraints
// Comparator is for comparing two values
type Comparator interface {
// Compare v1 and v2
// Ascending order: should return 1 -> v1 > v2, 0 -> v1 = v2, -1 -> v1 < v2
// Descending order: should return 1 -> v1 < v2, 0 -> v1 = v2, -1 -> v1 > v2
Compare(v1, v2 any) int
}
// Number contains all types of number and uintptr, used for generics constraint
type Number interface {
int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | uintptr | float32 | float64
}

View File

@@ -1,107 +0,0 @@
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
// Use of this source code is governed by MIT license
// Package maputil includes some functions to manipulate map.
package maputil
import "reflect"
// Keys returns a slice of the map's keys
func Keys[K comparable, V any](m map[K]V) []K {
keys := make([]K, 0, len(m))
for k := range m {
keys = append(keys, k)
}
return keys
}
// Values returns a slice of the map's values
func Values[K comparable, V any](m map[K]V) []V {
values := make([]V, 0, len(m))
for _, v := range m {
values = append(values, v)
}
return values
}
// Merge maps, next key will overwrite previous key
func Merge[K comparable, V any](maps ...map[K]V) map[K]V {
res := make(map[K]V, 0)
for _, m := range maps {
for k, v := range m {
res[k] = v
}
}
return res
}
// ForEach executes iteratee funcation for every key and value pair in map
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V)) {
for k, v := range m {
iteratee(k, v)
}
}
// Filter iterates over map, return a new map contains all key and value pairs pass the predicate function
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V {
res := make(map[K]V)
for k, v := range m {
if predicate(k, v) {
res[k] = v
}
}
return res
}
// Intersect iterates over maps, return a new map of key and value pairs in all given maps
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V {
if len(maps) == 0 {
return map[K]V{}
}
if len(maps) == 1 {
return maps[0]
}
res := make(map[K]V)
reducer := func(m1, m2 map[K]V) map[K]V {
m := make(map[K]V)
for k, v1 := range m1 {
if v2, ok := m2[k]; ok && reflect.DeepEqual(v1, v2) {
m[k] = v1
}
}
return m
}
reduceMaps := make([]map[K]V, 2, 2)
res = reducer(maps[0], maps[1])
for i := 2; i < len(maps); i++ {
reduceMaps[0] = res
reduceMaps[1] = maps[i]
res = reducer(reduceMaps[0], reduceMaps[1])
}
return res
}
// Minus creates an map of whose key in mapA but not in mapB
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V {
res := make(map[K]V)
for k, v := range mapA {
if _, ok := mapB[k]; !ok {
res[k] = v
}
}
return res
}

View File

@@ -1,150 +0,0 @@
package maputil
import (
"sort"
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestKeys(t *testing.T) {
assert := internal.NewAssert(t, "TestKeys")
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
keys := Keys(m)
sort.Ints(keys)
assert.Equal([]int{1, 2, 3, 4, 5}, keys)
}
func TestValues(t *testing.T) {
assert := internal.NewAssert(t, "TestValues")
m := map[int]string{
1: "a",
2: "a",
3: "b",
4: "c",
5: "d",
}
values := Values(m)
sort.Strings(values)
assert.Equal([]string{"a", "a", "b", "c", "d"}, values)
}
func TestMerge(t *testing.T) {
assert := internal.NewAssert(t, "TestMerge")
m1 := map[int]string{
1: "a",
2: "b",
}
m2 := map[int]string{
1: "1",
3: "2",
}
expected := map[int]string{
1: "1",
2: "b",
3: "2",
}
acturl := Merge(m1, m2)
assert.Equal(expected, acturl)
}
func TestForEach(t *testing.T) {
assert := internal.NewAssert(t, "TestForEach")
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
}
var sum int
ForEach(m, func(_ string, value int) {
sum += value
})
assert.Equal(10, sum)
}
func TestFilter(t *testing.T) {
assert := internal.NewAssert(t, "TestFilter")
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
}
isEven := func(_ string, value int) bool {
return value%2 == 0
}
acturl := Filter(m, isEven)
assert.Equal(map[string]int{
"b": 2,
"d": 4,
}, acturl)
}
func TestIntersect(t *testing.T) {
assert := internal.NewAssert(t, "TestIntersect")
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"a": 1,
"b": 2,
"c": 6,
"d": 7,
}
m3 := map[string]int{
"a": 1,
"b": 9,
"e": 9,
}
assert.Equal(map[string]int{"a": 1, "b": 2, "c": 3}, Intersect(m1))
assert.Equal(map[string]int{"a": 1, "b": 2}, Intersect(m1, m2))
assert.Equal(map[string]int{"a": 1}, Intersect(m1, m2, m3))
}
func TestMinus(t *testing.T) {
assert := internal.NewAssert(t, "TestMinus")
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := map[string]int{
"a": 11,
"b": 22,
"d": 33,
}
assert.Equal(map[string]int{"c": 3}, Minus(m1, m2))
}

View File

@@ -9,8 +9,6 @@ import (
"math" "math"
"strconv" "strconv"
"strings" "strings"
"github.com/duke-git/lancet/v2/lancetconstraints"
) )
// Exponent calculate x^n // Exponent calculate x^n
@@ -92,40 +90,3 @@ func TruncRound(x float64, n int) float64 {
res, _ := strconv.ParseFloat(newFloat, 64) res, _ := strconv.ParseFloat(newFloat, 64)
return res return res
} }
// Max return max value of params
func Max[T lancetconstraints.Number](numbers ...T) T {
max := numbers[0]
for _, v := range numbers {
if max < v {
max = v
}
}
return max
}
// Min return min value of params
func Min[T lancetconstraints.Number](numbers ...T) T {
min := numbers[0]
for _, v := range numbers {
if min > v {
min = v
}
}
return min
}
// Average return average value of params
func Average[T lancetconstraints.Number](numbers ...T) T {
var sum T
n := T(len(numbers))
for _, v := range numbers {
sum += v
}
return sum / n
}

View File

@@ -3,7 +3,7 @@ package mathutil
import ( import (
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestExponent(t *testing.T) { func TestExponent(t *testing.T) {
@@ -70,29 +70,3 @@ func TestTruncRound(t *testing.T) {
assert.Equal(TruncRound(0.125, 3), float64(0.125)) assert.Equal(TruncRound(0.125, 3), float64(0.125))
assert.Equal(TruncRound(33.33333, 2), float64(33.33)) assert.Equal(TruncRound(33.33333, 2), float64(33.33))
} }
func TestAverage(t *testing.T) {
assert := internal.NewAssert(t, "TestAverage")
assert.Equal(Average(0, 0), 0)
assert.Equal(Average(1, 1), 1)
avg := Average(1.2, 1.4)
t.Log(avg)
assert.Equal(1.3, RoundToFloat(avg, 1))
}
func TestMax(t *testing.T) {
assert := internal.NewAssert(t, "TestMax")
assert.Equal(Max(0, 0), 0)
assert.Equal(Max(1, 2, 3), 3)
assert.Equal(Max(1.2, 1.4, 1.1, 1.4), 1.4)
}
func TestMin(t *testing.T) {
assert := internal.NewAssert(t, "TestMin")
assert.Equal(Min(0, 0), 0)
assert.Equal(Min(1, 2, 3), 1)
assert.Equal(Min(1.2, 1.4, 1.1, 1.4), 1.1)
}

View File

@@ -6,7 +6,8 @@
// HttpGet, HttpPost, HttpDelete, HttpPut, HttpPatch, function param `url` is required. // HttpGet, HttpPost, HttpDelete, HttpPut, HttpPatch, function param `url` is required.
// HttpGet, HttpPost, HttpDelete, HttpPut, HttpPatch, function param `params` is variable, the order is: // HttpGet, HttpPost, HttpDelete, HttpPut, HttpPatch, function param `params` is variable, the order is:
// params[0] is header which type should be http.Header or map[string]string, // params[0] is header which type should be http.Header or map[string]string,
// params[1] is query param which type should be url.Values or map[string]any, // params[1] is query param which type should be url.Values or map[string]interface{}, when content-type header is
// multipart/form-data or application/x-www-form-urlencoded must pass url.Values params
// params[2] is post body which type should be []byte. // params[2] is post body which type should be []byte.
// params[3] is http client which type should be http.Client. // params[3] is http client which type should be http.Client.
package netutil package netutil
@@ -21,32 +22,32 @@ import (
) )
//HttpGet send get http request //HttpGet send get http request
func HttpGet(url string, params ...any) (*http.Response, error) { func HttpGet(url string, params ...interface{}) (*http.Response, error) {
return doHttpRequest(http.MethodGet, url, params...) return doHttpRequest(http.MethodGet, url, params...)
} }
//HttpPost send post http request //HttpPost send post http request
func HttpPost(url string, params ...any) (*http.Response, error) { func HttpPost(url string, params ...interface{}) (*http.Response, error) {
return doHttpRequest(http.MethodPost, url, params...) return doHttpRequest(http.MethodPost, url, params...)
} }
//HttpPut send put http request //HttpPut send put http request
func HttpPut(url string, params ...any) (*http.Response, error) { func HttpPut(url string, params ...interface{}) (*http.Response, error) {
return doHttpRequest(http.MethodPut, url, params...) return doHttpRequest(http.MethodPut, url, params...)
} }
//HttpDelete send delete http request //HttpDelete send delete http request
func HttpDelete(url string, params ...any) (*http.Response, error) { func HttpDelete(url string, params ...interface{}) (*http.Response, error) {
return doHttpRequest(http.MethodDelete, url, params...) return doHttpRequest(http.MethodDelete, url, params...)
} }
// HttpPatch send patch http request // HttpPatch send patch http request
func HttpPatch(url string, params ...any) (*http.Response, error) { func HttpPatch(url string, params ...interface{}) (*http.Response, error) {
return doHttpRequest(http.MethodPatch, url, params...) return doHttpRequest(http.MethodPatch, url, params...)
} }
// ParseHttpResponse decode http response to specified interface // ParseHttpResponse decode http response to specified interface
func ParseHttpResponse(resp *http.Response, obj any) error { func ParseHttpResponse(resp *http.Response, obj interface{}) error {
if resp == nil { if resp == nil {
return errors.New("InvalidResp") return errors.New("InvalidResp")
} }
@@ -55,7 +56,7 @@ func ParseHttpResponse(resp *http.Response, obj any) error {
} }
// ConvertMapToQueryString convert map to sorted url query string // ConvertMapToQueryString convert map to sorted url query string
func ConvertMapToQueryString(param map[string]any) string { func ConvertMapToQueryString(param map[string]interface{}) string {
if param == nil { if param == nil {
return "" return ""
} }

View File

@@ -4,9 +4,10 @@ import (
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"log" "log"
"net/url"
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestHttpGet(t *testing.T) { func TestHttpGet(t *testing.T) {
@@ -46,6 +47,29 @@ func TestHttpPost(t *testing.T) {
t.Log("response: ", resp.StatusCode, string(body)) t.Log("response: ", resp.StatusCode, string(body))
} }
func TestHttpPostFormData(t *testing.T) {
apiUrl := "https://jsonplaceholder.typicode.com/todos"
header := map[string]string{
// "Content-Type": "application/x-www-form-urlencoded",
"Content-Type": "multipart/form-data",
}
type Todo struct {
UserId int `json:"userId"`
Title string `json:"title"`
}
postData := url.Values{}
postData.Add("userId", "1")
postData.Add("title", "TestAddToDo")
resp, err := HttpPost(apiUrl, header, postData, nil)
if err != nil {
log.Fatal(err)
t.FailNow()
}
body, _ := ioutil.ReadAll(resp.Body)
t.Log("response: ", resp.StatusCode, string(body))
}
func TestHttpPut(t *testing.T) { func TestHttpPut(t *testing.T) {
url := "https://jsonplaceholder.typicode.com/todos/1" url := "https://jsonplaceholder.typicode.com/todos/1"
header := map[string]string{ header := map[string]string{
@@ -104,7 +128,7 @@ func TestHttpDelete(t *testing.T) {
func TestConvertMapToQueryString(t *testing.T) { func TestConvertMapToQueryString(t *testing.T) {
assert := internal.NewAssert(t, "TestConvertMapToQueryString") assert := internal.NewAssert(t, "TestConvertMapToQueryString")
var m = map[string]any{ var m = map[string]interface{}{
"c": 3, "c": 3,
"a": 1, "a": 1,
"b": 2, "b": 2,

View File

@@ -10,7 +10,7 @@ import (
"strings" "strings"
) )
func doHttpRequest(method, reqUrl string, params ...any) (*http.Response, error) { func doHttpRequest(method, reqUrl string, params ...interface{}) (*http.Response, error) {
if len(reqUrl) == 0 { if len(reqUrl) == 0 {
return nil, errors.New("url should be specified") return nil, errors.New("url should be specified")
} }
@@ -41,6 +41,7 @@ func doHttpRequest(method, reqUrl string, params ...any) (*http.Response, error)
return nil, err return nil, err
} }
case 3: case 3:
err := setHeaderAndQueryAndBody(req, reqUrl, params[0], params[1], params[2]) err := setHeaderAndQueryAndBody(req, reqUrl, params[0], params[1], params[2])
if err != nil { if err != nil {
return nil, err return nil, err
@@ -60,7 +61,7 @@ func doHttpRequest(method, reqUrl string, params ...any) (*http.Response, error)
return resp, e return resp, e
} }
func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam any) error { func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam interface{}) error {
err := setHeader(req, header) err := setHeader(req, header)
if err != nil { if err != nil {
return err return err
@@ -72,7 +73,7 @@ func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam
return nil return nil
} }
func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryParam, body any) error { func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryParam, body interface{}) error {
err := setHeader(req, header) err := setHeader(req, header)
if err != nil { if err != nil {
return err return err
@@ -81,14 +82,19 @@ func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryPar
if err != nil { if err != nil {
return err return err
} }
err = setBodyByte(req, body) if req.Header.Get("Content-Type") == "multipart/form-data" || req.Header.Get("Content-Type") == "application/x-www-form-urlencoded" {
formData := queryParam.(url.Values)
err = setBodyByte(req, []byte(formData.Encode()))
} else {
err = setBodyByte(req, body)
}
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
func setHeader(req *http.Request, header any) error { func setHeader(req *http.Request, header interface{}) error {
if header != nil { if header != nil {
switch v := header.(type) { switch v := header.(type) {
case map[string]string: case map[string]string:
@@ -122,11 +128,11 @@ func setUrl(req *http.Request, reqUrl string) error {
return nil return nil
} }
func setQueryParam(req *http.Request, reqUrl string, queryParam any) error { func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) error {
var values url.Values var values url.Values
if queryParam != nil { if queryParam != nil {
switch v := queryParam.(type) { switch v := queryParam.(type) {
case map[string]any: case map[string]interface{}:
values = url.Values{} values = url.Values{}
for k := range v { for k := range v {
values.Set(k, fmt.Sprintf("%v", v[k])) values.Set(k, fmt.Sprintf("%v", v[k]))
@@ -134,7 +140,7 @@ func setQueryParam(req *http.Request, reqUrl string, queryParam any) error {
case url.Values: case url.Values:
values = v values = v
default: default:
return errors.New("query params type should be url.Values or map[string]any") return errors.New("query params type should be url.Values or map[string]interface{}")
} }
} }
@@ -155,7 +161,7 @@ func setQueryParam(req *http.Request, reqUrl string, queryParam any) error {
return nil return nil
} }
func setBodyByte(req *http.Request, body any) error { func setBodyByte(req *http.Request, body interface{}) error {
if body != nil { if body != nil {
switch b := body.(type) { switch b := body.(type) {
case []byte: case []byte:
@@ -168,7 +174,7 @@ func setBodyByte(req *http.Request, body any) error {
return nil return nil
} }
func getClient(client any) (*http.Client, error) { func getClient(client interface{}) (*http.Client, error) {
c := http.Client{} c := http.Client{}
if client != nil { if client != nil {
switch v := client.(type) { switch v := client.(type) {

View File

@@ -4,7 +4,7 @@ import (
"net" "net"
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestGetInternalIp(t *testing.T) { func TestGetInternalIp(t *testing.T) {

View File

@@ -5,7 +5,7 @@ import (
"regexp" "regexp"
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestRandString(t *testing.T) { func TestRandString(t *testing.T) {

View File

@@ -6,7 +6,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestRetryFailed(t *testing.T) { func TestRetryFailed(t *testing.T) {

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@ import (
) )
// sliceValue return the reflect value of a slice // sliceValue return the reflect value of a slice
func sliceValue(slice any) reflect.Value { func sliceValue(slice interface{}) reflect.Value {
v := reflect.ValueOf(slice) v := reflect.ValueOf(slice)
if v.Kind() != reflect.Slice { if v.Kind() != reflect.Slice {
panic(fmt.Sprintf("Invalid slice type, value of type %T", slice)) panic(fmt.Sprintf("Invalid slice type, value of type %T", slice))
@@ -15,7 +15,7 @@ func sliceValue(slice any) reflect.Value {
} }
// functionValue return the reflect value of a function // functionValue return the reflect value of a function
func functionValue(function any) reflect.Value { func functionValue(function interface{}) reflect.Value {
v := reflect.ValueOf(function) v := reflect.ValueOf(function)
if v.Kind() != reflect.Func { if v.Kind() != reflect.Func {
panic(fmt.Sprintf("Invalid function type, value of type %T", function)) panic(fmt.Sprintf("Invalid function type, value of type %T", function))

View File

@@ -1,10 +1,10 @@
package slice package slice
import ( import (
"math" "reflect"
"testing" "testing"
"github.com/duke-git/lancet/v2/internal" "github.com/duke-git/lancet/internal"
) )
func TestContain(t *testing.T) { func TestContain(t *testing.T) {
@@ -15,36 +15,41 @@ func TestContain(t *testing.T) {
assert.Equal(true, Contain([]string{""}, "")) assert.Equal(true, Contain([]string{""}, ""))
assert.Equal(false, Contain([]string{}, "")) assert.Equal(false, Contain([]string{}, ""))
assert.Equal(true, Contain([]int{1, 2, 3}, 1)) var m = map[string]int{"a": 1}
assert.Equal(true, Contain(m, "a"))
assert.Equal(false, Contain(m, "b"))
assert.Equal(true, Contain("abc", "a"))
assert.Equal(false, Contain("abc", "d"))
} }
func TestContainSubSlice(t *testing.T) { func TestContainSubSlice(t *testing.T) {
assert := internal.NewAssert(t, "TestContainSubSlice") assert := internal.NewAssert(t, "TestContainSubSlice")
assert.Equal(true, ContainSubSlice([]string{"a", "a", "b", "c"}, []string{"a", "a"})) assert.Equal(true, ContainSubSlice([]string{"a", "a", "b", "c"}, []string{"a", "a"}))
assert.Equal(false, ContainSubSlice([]string{"a", "a", "b", "c"}, []string{"a", "d"})) assert.Equal(false, ContainSubSlice([]string{"a", "a", "b", "c"}, []string{"a", "d"}))
assert.Equal(true, ContainSubSlice([]int{1, 2, 3}, []int{1, 2}))
assert.Equal(false, ContainSubSlice([]int{1, 2, 3}, []int{0, 1})) assert.Equal(true, ContainSubSlice([]int{1, 2, 3}, []int{1}))
assert.Equal(false, ContainSubSlice([]int{1, 2, 3}, []string{"a"}))
} }
func TestChunk(t *testing.T) { func TestChunk(t *testing.T) {
assert := internal.NewAssert(t, "TestChunk") assert := internal.NewAssert(t, "TestChunk")
arr := []string{"a", "b", "c", "d", "e"} arr := []string{"a", "b", "c", "d", "e"}
r1 := [][]interface{}{{"a"}, {"b"}, {"c"}, {"d"}, {"e"}}
assert.Equal(r1, Chunk(InterfaceSlice(arr), 1))
r1 := [][]string{{"a"}, {"b"}, {"c"}, {"d"}, {"e"}} r2 := [][]interface{}{{"a", "b"}, {"c", "d"}, {"e"}}
assert.Equal(r1, Chunk(arr, 1)) assert.Equal(r2, Chunk(InterfaceSlice(arr), 2))
r2 := [][]string{{"a", "b"}, {"c", "d"}, {"e"}} r3 := [][]interface{}{{"a", "b", "c"}, {"d", "e"}}
assert.Equal(r2, Chunk(arr, 2)) assert.Equal(r3, Chunk(InterfaceSlice(arr), 3))
r3 := [][]string{{"a", "b", "c"}, {"d", "e"}} r4 := [][]interface{}{{"a", "b", "c", "d"}, {"e"}}
assert.Equal(r3, Chunk(arr, 3)) assert.Equal(r4, Chunk(InterfaceSlice(arr), 4))
r4 := [][]string{{"a", "b", "c", "d"}, {"e"}} r5 := [][]interface{}{{"a"}, {"b"}, {"c"}, {"d"}, {"e"}}
assert.Equal(r4, Chunk(arr, 4)) assert.Equal(r5, Chunk(InterfaceSlice(arr), 5))
r5 := [][]string{{"a"}, {"b"}, {"c"}, {"d"}, {"e"}}
assert.Equal(r5, Chunk(arr, 5))
} }
func TestCompact(t *testing.T) { func TestCompact(t *testing.T) {
@@ -61,11 +66,35 @@ func TestCompact(t *testing.T) {
func TestConcat(t *testing.T) { func TestConcat(t *testing.T) {
assert := internal.NewAssert(t, "Concat") assert := internal.NewAssert(t, "Concat")
// assert.Equal([]int{0}, Concat([]int{}, 0)) assert.Equal([]int{0}, Concat([]int{}, 0))
// assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, 4, 5)) assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, 4, 5))
assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, []int{4, 5})) assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, []int{4, 5}))
assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, []int{4}, []int{5})) assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, []int{4}, []int{5}))
// assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, []int{4}, 5)) assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, []int{4}, 5))
}
func TestEqual(t *testing.T) {
assert := internal.NewAssert(t, "TestEqual")
slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}
slice3 := []int{3, 2, 1}
assert.Equal(true, Equal(slice1, slice2))
assert.Equal(false, Equal(slice1, slice3))
}
func TestEqualWith(t *testing.T) {
assert := internal.NewAssert(t, "TestEqualWith")
slice1 := []int{1, 2, 3}
slice2 := []int{2, 4, 6}
isDouble := func(a, b int) bool {
return b == a*2
}
assert.Equal(true, EqualWith(slice1, slice2, isDouble))
} }
func TestEvery(t *testing.T) { func TestEvery(t *testing.T) {
@@ -143,20 +172,6 @@ func TestGroupBy(t *testing.T) {
assert.Equal(expectedOdd, odd) assert.Equal(expectedOdd, odd)
} }
func TestGroupWith(t *testing.T) {
nums := []float64{6.1, 4.2, 6.3}
floor := func(num float64) float64 {
return math.Floor(num)
}
expected := map[float64][]float64{
4: {4.2},
6: {6.1, 6.3},
}
actual := GroupWith(nums, floor)
assert := internal.NewAssert(t, "TestGroupWith")
assert.Equal(expected, actual)
}
func TestCount(t *testing.T) { func TestCount(t *testing.T) {
nums := []int{1, 2, 3, 4, 5, 6} nums := []int{1, 2, 3, 4, 5, 6}
evenFunc := func(i, num int) bool { evenFunc := func(i, num int) bool {
@@ -178,7 +193,7 @@ func TestFind(t *testing.T) {
} }
assert := internal.NewAssert(t, "TestFind") assert := internal.NewAssert(t, "TestFind")
assert.Equal(2, *res) assert.Equal(2, res)
} }
func TestFindLast(t *testing.T) { func TestFindLast(t *testing.T) {
@@ -192,7 +207,7 @@ func TestFindLast(t *testing.T) {
} }
assert := internal.NewAssert(t, "TestFindLast") assert := internal.NewAssert(t, "TestFindLast")
assert.Equal(4, *res) assert.Equal(4, res)
} }
func TestFindFoundNothing(t *testing.T) { func TestFindFoundNothing(t *testing.T) {
@@ -221,11 +236,9 @@ func TestForEach(t *testing.T) {
expected := []int{3, 4, 5, 6, 7} expected := []int{3, 4, 5, 6, 7}
var numbersAddTwo []int var numbersAddTwo []int
addTwo := func(index int, value int) { ForEach(numbers, func(index int, value int) {
numbersAddTwo = append(numbersAddTwo, value+2) numbersAddTwo = append(numbersAddTwo, value+2)
} })
ForEach(numbers, addTwo)
assert := internal.NewAssert(t, "TestForEach") assert := internal.NewAssert(t, "TestForEach")
assert.Equal(expected, numbersAddTwo) assert.Equal(expected, numbersAddTwo)
@@ -283,7 +296,7 @@ func TestReduce(t *testing.T) {
} }
func TestIntSlice(t *testing.T) { func TestIntSlice(t *testing.T) {
var nums []any var nums []interface{}
nums = append(nums, 1, 2, 3) nums = append(nums, 1, 2, 3)
assert := internal.NewAssert(t, "TestIntSlice") assert := internal.NewAssert(t, "TestIntSlice")
@@ -291,7 +304,7 @@ func TestIntSlice(t *testing.T) {
} }
func TestStringSlice(t *testing.T) { func TestStringSlice(t *testing.T) {
var strs []any var strs []interface{}
strs = append(strs, "a", "b", "c") strs = append(strs, "a", "b", "c")
assert := internal.NewAssert(t, "TestStringSlice") assert := internal.NewAssert(t, "TestStringSlice")
@@ -300,27 +313,41 @@ func TestStringSlice(t *testing.T) {
func TestInterfaceSlice(t *testing.T) { func TestInterfaceSlice(t *testing.T) {
strs := []string{"a", "b", "c"} strs := []string{"a", "b", "c"}
expect := []any{"a", "b", "c"} expect := []interface{}{"a", "b", "c"}
assert := internal.NewAssert(t, "TestInterfaceSlice") assert := internal.NewAssert(t, "TestInterfaceSlice")
assert.Equal(expect, InterfaceSlice(strs)) assert.Equal(expect, InterfaceSlice(strs))
} }
func TestDeleteAt(t *testing.T) { func TestDeleteByIndex(t *testing.T) {
assert := internal.NewAssert(t, "TestDeleteAt") assert := internal.NewAssert(t, "TestDeleteByIndex")
assert.Equal([]string{"a", "b", "c"}, DeleteAt([]string{"a", "b", "c"}, -1)) t1 := []string{"a", "b", "c", "d", "e"}
assert.Equal([]string{"a", "b", "c"}, DeleteAt([]string{"a", "b", "c"}, 3)) r1 := []string{"b", "c", "d", "e"}
assert.Equal([]string{"b", "c"}, DeleteAt([]string{"a", "b", "c"}, 0)) a1, _ := DeleteByIndex(t1, 0)
assert.Equal([]string{"a", "c"}, DeleteAt([]string{"a", "b", "c"}, 1)) assert.Equal(r1, a1)
assert.Equal([]string{"a", "b"}, DeleteAt([]string{"a", "b", "c"}, 2))
assert.Equal([]string{"b", "c"}, DeleteAt([]string{"a", "b", "c"}, 0, 1)) t2 := []string{"a", "b", "c", "d", "e"}
assert.Equal([]string{"c"}, DeleteAt([]string{"a", "b", "c"}, 0, 2)) r2 := []string{"a", "b", "c", "e"}
assert.Equal([]string{}, DeleteAt([]string{"a", "b", "c"}, 0, 3)) a2, _ := DeleteByIndex(t2, 3)
assert.Equal([]string{}, DeleteAt([]string{"a", "b", "c"}, 0, 4)) assert.Equal(r2, a2)
assert.Equal([]string{"a"}, DeleteAt([]string{"a", "b", "c"}, 1, 3))
assert.Equal([]string{"a"}, DeleteAt([]string{"a", "b", "c"}, 1, 4)) t3 := []string{"a", "b", "c", "d", "e"}
r3 := []string{"c", "d", "e"}
a3, _ := DeleteByIndex(t3, 0, 2)
assert.Equal(r3, a3)
t4 := []string{"a", "b", "c", "d", "e"}
r4 := []string{}
a4, _ := DeleteByIndex(t4, 0, 5)
assert.Equal(r4, a4)
t5 := []string{"a", "b", "c", "d", "e"}
_, err := DeleteByIndex(t5, 1, 1)
assert.IsNotNil(err)
_, err = DeleteByIndex(t5, 0, 6)
assert.IsNotNil(err)
} }
func TestDrop(t *testing.T) { func TestDrop(t *testing.T) {
@@ -340,28 +367,48 @@ func TestDrop(t *testing.T) {
assert.Equal([]int{}, Drop([]int{1, 2, 3, 4, 5}, -6)) assert.Equal([]int{}, Drop([]int{1, 2, 3, 4, 5}, -6))
} }
func TestInsertAt(t *testing.T) { func TestInsertByIndex(t *testing.T) {
assert := internal.NewAssert(t, "TestInsertAt") assert := internal.NewAssert(t, "TestInsertByIndex")
strs := []string{"a", "b", "c"} t1 := []string{"a", "b", "c"}
assert.Equal([]string{"a", "b", "c"}, InsertAt(strs, -1, "1")) r1, _ := InsertByIndex(t1, 0, "1")
assert.Equal([]string{"a", "b", "c"}, InsertAt(strs, 4, "1")) assert.Equal([]string{"1", "a", "b", "c"}, r1)
assert.Equal([]string{"1", "a", "b", "c"}, InsertAt(strs, 0, "1"))
assert.Equal([]string{"a", "1", "b", "c"}, InsertAt(strs, 1, "1")) r2, _ := InsertByIndex(t1, 1, "1")
assert.Equal([]string{"a", "b", "1", "c"}, InsertAt(strs, 2, "1")) assert.Equal([]string{"a", "1", "b", "c"}, r2)
assert.Equal([]string{"a", "b", "c", "1"}, InsertAt(strs, 3, "1"))
assert.Equal([]string{"1", "2", "3", "a", "b", "c"}, InsertAt(strs, 0, []string{"1", "2", "3"})) r3, _ := InsertByIndex(t1, 3, "1")
assert.Equal([]string{"a", "b", "c", "1", "2", "3"}, InsertAt(strs, 3, []string{"1", "2", "3"})) assert.Equal([]string{"a", "b", "c", "1"}, r3)
t.Log(strs)
r4, _ := InsertByIndex(t1, 0, []string{"1", "2", "3"})
assert.Equal([]string{"1", "2", "3", "a", "b", "c"}, r4)
r5, _ := InsertByIndex(t1, 3, []string{"1", "2", "3"})
assert.Equal([]string{"a", "b", "c", "1", "2", "3"}, r5)
_, err := InsertByIndex(t1, 4, "1")
assert.IsNotNil(err)
_, err = InsertByIndex(t1, 0, 1)
assert.IsNotNil(err)
} }
func TestUpdateAt(t *testing.T) { func TestUpdateByIndex(t *testing.T) {
assert := internal.NewAssert(t, "TestUpdateAt") assert := internal.NewAssert(t, "TestUpdateByIndex")
assert.Equal([]string{"a", "b", "c"}, UpdateAt([]string{"a", "b", "c"}, -1, "1")) t1 := []string{"a", "b", "c"}
assert.Equal([]string{"1", "b", "c"}, UpdateAt([]string{"a", "b", "c"}, 0, "1")) r1, _ := UpdateByIndex(t1, 0, "1")
assert.Equal([]string{"a", "b", "2"}, UpdateAt([]string{"a", "b", "c"}, 2, "2")) assert.Equal([]string{"1", "b", "c"}, r1)
assert.Equal([]string{"a", "b", "c"}, UpdateAt([]string{"a", "b", "c"}, 3, "2"))
t2 := []string{"a", "b", "c"}
r2, _ := UpdateByIndex(t2, 1, "1")
assert.Equal([]string{"a", "1", "c"}, r2)
_, err := UpdateByIndex([]string{"a", "b", "c"}, 4, "1")
assert.IsNotNil(err)
_, err = UpdateByIndex([]string{"a", "b", "c"}, 0, 1)
assert.IsNotNil(err)
} }
func TestUnique(t *testing.T) { func TestUnique(t *testing.T) {
@@ -371,6 +418,15 @@ func TestUnique(t *testing.T) {
assert.Equal([]string{"a", "b", "c"}, Unique([]string{"a", "a", "b", "c"})) assert.Equal([]string{"a", "b", "c"}, Unique([]string{"a", "a", "b", "c"}))
} }
func TestUniqueBy(t *testing.T) {
assert := internal.NewAssert(t, "TestUniqueBy")
actual := UniqueBy([]int{1, 2, 3, 4, 5, 6}, func(val int) int {
return val % 4
})
assert.Equal([]int{1, 2, 3, 0}, actual)
}
func TestUnion(t *testing.T) { func TestUnion(t *testing.T) {
assert := internal.NewAssert(t, "TestUnion") assert := internal.NewAssert(t, "TestUnion")
@@ -395,7 +451,7 @@ func TestIntersection(t *testing.T) {
{1, 2, 3}, {1, 2, 3},
{}, {},
} }
res := []any{ res := []interface{}{
Intersection(s1, s2, s3), Intersection(s1, s2, s3),
Intersection(s1, s2), Intersection(s1, s2),
Intersection(s1), Intersection(s1),
@@ -405,31 +461,20 @@ func TestIntersection(t *testing.T) {
assert := internal.NewAssert(t, "TestIntersection") assert := internal.NewAssert(t, "TestIntersection")
for i := 0; i < len(res); i++ { for i := 0; i < len(res); i++ {
assert.Equal(expected[i], res[i]) assert.Equal(res[i], expected[i])
} }
assert.IsNil(Intersection())
} }
func TestSymmetricDifference(t *testing.T) { func TestReverseSlice(t *testing.T) {
assert := internal.NewAssert(t, "TestSymmetricDifference") assert := internal.NewAssert(t, "TestIntersection")
s1 := []int{1, 2, 3}
s2 := []int{1, 2, 4}
s3 := []int{1, 2, 3, 5}
assert.Equal([]int{1, 2, 3}, SymmetricDifference(s1))
assert.Equal([]int{3, 4}, SymmetricDifference(s1, s2))
assert.Equal([]int{3, 4, 5}, SymmetricDifference(s1, s2, s3))
}
func TestReverse(t *testing.T) {
assert := internal.NewAssert(t, "TestReverse")
s1 := []int{1, 2, 3, 4, 5} s1 := []int{1, 2, 3, 4, 5}
Reverse(s1) ReverseSlice(s1)
assert.Equal([]int{5, 4, 3, 2, 1}, s1) assert.Equal([]int{5, 4, 3, 2, 1}, s1)
s2 := []string{"a", "b", "c", "d", "e"} s2 := []string{"a", "b", "c", "d", "e"}
Reverse(s2) ReverseSlice(s2)
assert.Equal([]string{"e", "d", "c", "b", "a"}, s2) assert.Equal([]string{"e", "d", "c", "b", "a"}, s2)
} }
@@ -441,17 +486,6 @@ func TestDifference(t *testing.T) {
assert.Equal([]int{1, 2, 3}, Difference(s1, s2)) assert.Equal([]int{1, 2, 3}, Difference(s1, s2))
} }
func TestDifferenceWith(t *testing.T) {
assert := internal.NewAssert(t, "TestDifferenceWith")
s1 := []int{1, 2, 3, 4, 5}
s2 := []int{4, 5, 6, 7, 8}
isDouble := func(v1, v2 int) bool {
return v2 == 2*v1
}
assert.Equal([]int{1, 5}, DifferenceWith(s1, s2, isDouble))
}
func TestDifferenceBy(t *testing.T) { func TestDifferenceBy(t *testing.T) {
assert := internal.NewAssert(t, "TestDifferenceBy") assert := internal.NewAssert(t, "TestDifferenceBy")
@@ -528,5 +562,33 @@ func TestShuffle(t *testing.T) {
res := Shuffle(s) res := Shuffle(s)
t.Log("Shuffle result: ", res) t.Log("Shuffle result: ", res)
assert.Equal(5, len(res)) assert.Equal(reflect.TypeOf(s), reflect.TypeOf(res))
rv := reflect.ValueOf(res)
assert.Equal(5, rv.Len())
assert.Equal(true, rv.Kind() == reflect.Slice)
assert.Equal(true, rv.Type().Elem().Kind() == reflect.Int)
assert.Equal(true, Contain(res, 1))
assert.Equal(true, Contain(res, 2))
assert.Equal(true, Contain(res, 3))
assert.Equal(true, Contain(res, 4))
assert.Equal(true, Contain(res, 5))
}
func TestIndexOf(t *testing.T) {
assert := internal.NewAssert(t, "TestIndexOf")
arr := []string{"a", "a", "b", "c"}
assert.Equal(0, IndexOf(arr, "a"))
assert.Equal(-1, IndexOf(arr, "d"))
}
func TestLastIndexOf(t *testing.T) {
assert := internal.NewAssert(t, "TestLastIndexOf")
arr := []string{"a", "a", "b", "c"}
assert.Equal(1, LastIndexOf(arr, "a"))
assert.Equal(-1, LastIndexOf(arr, "d"))
} }

View File

@@ -1,3 +1,4 @@
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
// Use of this source code is governed by MIT license // Use of this source code is governed by MIT license
// Package strutil implements some functions to manipulate string. // Package strutil implements some functions to manipulate string.
@@ -196,7 +197,7 @@ func AfterLast(s, char string) string {
} }
// IsString check if the value data type is string or not. // IsString check if the value data type is string or not.
func IsString(v any) bool { func IsString(v interface{}) bool {
if v == nil { if v == nil {
return false return false
} }
@@ -247,3 +248,52 @@ func Unwrap(str string, wrapToken string) string {
return str return str
} }
// SplitEx split a given string whether the result contains empty string
func SplitEx(s, sep string, removeEmptyString bool) []string {
if sep == "" {
return []string{}
}
n := strings.Count(s, sep) + 1
a := make([]string, n)
n--
i := 0
sepSave := 0
ignore := false
for i < n {
m := strings.Index(s, sep)
if m < 0 {
break
}
ignore = false
if removeEmptyString {
if s[:m+sepSave] == "" {
ignore = true
}
}
if !ignore {
a[i] = s[:m+sepSave]
s = s[m+len(sep):]
i++
} else {
s = s[m+len(sep):]
}
}
var ret []string
if removeEmptyString {
if s != "" {
a[i] = s
ret = a[:i+1]
} else {
ret = a[:i]
}
} else {
a[i] = s
ret = a[:i+1]
}
return ret
}

Some files were not shown because too many files have changed in this diff Show More