1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-08 06:32:28 +08:00

Compare commits

...

99 Commits

Author SHA1 Message Date
dudaodong
40b2560752 docs: add v2 in import path 2022-03-17 11:33:45 +08:00
dudaodong
50c6e51393 upgrade go module v2 2022-03-17 10:57:35 +08:00
dudaodong
1434e00712 docs: add func HeapSort 2022-03-17 10:11:34 +08:00
dudaodong
76c941cff0 update readme file 2022-03-16 19:39:21 +08:00
dudaodong
bb03f31a8b release v2.0.0 2022-03-16 19:16:43 +08:00
dudaodong
c939b26cb8 refactor: interface{} -> any 2022-03-16 18:41:40 +08:00
dudaodong
af480efa8c docs: add xerror package doc 2022-03-16 18:21:30 +08:00
dudaodong
bc913d70b1 docs: update doc style 2022-03-16 18:06:06 +08:00
dudaodong
2bc87d8a6b docs: add docs/algorithm.md 2022-03-16 18:00:38 +08:00
dudaodong
2185c48eab docs: add docs/algorithm.md 2022-03-16 18:00:29 +08:00
dudaodong
59b5046a15 docs: update slice.md 2022-03-16 16:59:15 +08:00
dudaodong
569902b528 fix: fix lru cache bug 2022-03-14 11:19:30 +08:00
dudaodong
78519088ab feat: add lru cache 2022-03-11 17:05:55 +08:00
dudaodong
0c06cdb29f Merge branch 'main' into v2 2022-03-04 17:42:18 +08:00
dudaodong
e8b8ff8927 merge main branch 2022-03-01 15:00:02 +08:00
dudaodong
06bd407a0c feat: add LevelOrderTraverse func 2022-03-01 11:23:33 +08:00
dudaodong
aa28479d11 feat: update deleteTreeNode func 2022-03-01 11:13:44 +08:00
dudaodong
bf7db0ded2 feat: add DeletetNode 2022-03-01 11:04:38 +08:00
dudaodong
dd1cbf2ee3 refactor: rename Insert to InsertNode 2022-03-01 10:11:37 +08:00
dudaodong
9d5db895c9 Merge branch 'main' into v2 2022-03-01 10:02:23 +08:00
dudaodong
6b09da6e6e feat: add funcs to traverse bstree 2022-02-23 19:34:35 +08:00
dudaodong
b2b6710a1b feat: add BSTree which is binary search tree 2022-02-21 16:48:27 +08:00
dudaodong
e7ee2ed7cf Merge branch 'main' into v2 2022-02-20 11:35:43 +08:00
dudaodong
1dfd1ec1d3 Merge branch 'main' into v2 2022-02-19 21:55:09 +08:00
dudaodong
2e8834a2c1 docs: update slice.doc 2022-02-18 11:05:14 +08:00
dudaodong
df098392c2 merge main branch 2022-02-18 10:28:47 +08:00
dudaodong
5e318a78d2 refactor: remove unused code 2022-02-15 11:19:07 +08:00
dudaodong
d872d64fe0 feat: add CircularQueue 2022-02-15 10:34:14 +08:00
dudaodong
c2257493a8 fix: fix panic info text 2022-02-14 15:36:44 +08:00
dudaodong
48c1f8ffad fix: fix some spell mistake 2022-02-13 19:00:44 +08:00
dudaodong
8a4c8218d2 update func DeQueue comment 2022-02-11 10:49:33 +08:00
dudaodong
92e1321d43 refactor: rename func Length -> Size 2022-02-11 10:48:38 +08:00
dudaodong
43fb907a81 feat: add LinkedQueue 2022-02-11 10:46:48 +08:00
dudaodong
f551c56921 refactor: reconstructure souce file into the corresponding folder 2022-02-10 17:57:53 +08:00
dudaodong
85e1f711f5 feat: and Clear and IsEmpty func 2022-02-10 17:41:51 +08:00
dudaodong
ade567a620 feat: add ArrayQueue data structure 2022-02-10 17:30:37 +08:00
dudaodong
a26e519a3f refactor: rename func Length -> Size 2022-02-10 15:42:05 +08:00
dudaodong
797e47363f rename: rename StackArray -> ArrayStack, StackLink -> LinkedStack 2022-02-10 11:50:03 +08:00
dudaodong
20e1836eb7 rename: rename StackArray -> ArrayStack, StackLink -> LinkedStack 2022-02-10 11:49:46 +08:00
dudaodong
5ae746a1f0 rename: rename InsertByIndex -> InsertAt, UpdateByIndex -> UpdateAt, DeleteByIndex -> DeleteAt for release 2.0 2022-02-10 11:25:34 +08:00
dudaodong
17d271190b feat: add DoublyLink data structure 2022-02-10 10:57:17 +08:00
dudaodong
310f8bd1e1 feat: add Set data structure 2022-02-09 15:15:49 +08:00
dudaodong
bf7a4e729f feat: add func Contain, Union, Intersection 2022-02-09 11:40:08 +08:00
dudaodong
8d0ff28304 update comment for StackLink 2022-02-04 22:45:01 +08:00
dudaodong
cee9bb538f feat: add stacklink.go implements stack with link 2022-02-04 22:42:51 +08:00
dudaodong
eb59d02a08 feat: add stackarray.go implements stack with array 2022-02-04 19:35:06 +08:00
dudaodong
10ed71a3a2 refactor: rename linknode.go to node.go 2022-02-04 09:22:16 +08:00
dudaodong
0e86244559 refactor: rename linknode.go to node.go 2022-02-04 09:21:35 +08:00
dudaodong
5ab150cad3 feat: add DeleteAtHead, DeleteAtTail, DeleteAt, Reverse, Size, GetMiddleNode funcs in singlelink 2022-02-03 16:37:34 +08:00
dudaodong
3546afe86c feat: add some functons of singlelink 2022-02-02 22:41:49 +08:00
dudaodong
70077a6010 merge main branch 2022-01-26 17:47:57 +08:00
dudaodong
efdf36a817 Merge branch 'main' into v2 2022-01-26 17:44:46 +08:00
dudaodong
e233788f69 comment: add comment for List struct 2022-01-26 15:25:52 +08:00
dudaodong
957e6356f6 feat: add singlelink 2022-01-26 15:25:02 +08:00
dudaodong
887eaa528a update: algorithm package comment 2022-01-26 14:57:37 +08:00
dudaodong
33126570bd feat: add datastructure package and list implementation 2022-01-26 14:56:40 +08:00
dudaodong
5937183af0 feat: replace constraints comparable into any in some funcs 2022-01-24 15:47:47 +08:00
dudaodong
4eaa0a39d5 feat: add FindLast func 2022-01-24 15:22:43 +08:00
dudaodong
18ec73839b feat: add DifferenceWith 2022-01-24 14:53:45 +08:00
dudaodong
89aef977a2 refactor: clean code for slice/slice.go 2022-01-24 11:46:09 +08:00
dudaodong
2612569500 merge: merge main branch and refector slice func with generics 2022-01-24 11:10:12 +08:00
dudaodong
acc8b59387 comment: add comment for Unwrap 2022-01-24 10:24:10 +08:00
donutloop
2878d389c8 error: Add unwrap (#24)
Add a unwrap func helper

* Unwrap if err is nil then it returns a valid value otherwise it panics
2022-01-22 21:25:31 +08:00
dudaodong
3f8effb7a3 refactor: make BinarySearch func code clear 2022-01-21 11:57:36 +08:00
dudaodong
bd30855ae6 feat: add LinearSearch 2022-01-21 11:36:31 +08:00
dudaodong
0efe2f57c3 merge main 2022-01-19 20:47:47 +08:00
dudaodong
8868fcabed Merge branch 'main' into v2 2022-01-19 17:35:48 +08:00
dudaodong
dfbb9e30e0 feat: algorithm package, BinarySearch and BinaryIterativeSearch functions 2022-01-17 15:36:48 +08:00
dudaodong
b22be7cade refactor: change var name low -> lowIndex, high -> highIndex 2022-01-17 15:11:33 +08:00
dudaodong
87da6c6816 Merge branch 'main' into v2 2022-01-17 15:01:38 +08:00
dudaodong
912f7052a3 gofmt 2022-01-17 10:29:42 +08:00
dudaodong
e6f9b0954c feat: add CountSort 2022-01-16 17:20:20 +08:00
dudaodong
98e861cf3b feat: add QuickSort, HeapSort, and MergeSort functions 2022-01-16 16:52:17 +08:00
dudaodong
43e0ca7edf feat: add ShellSort 2022-01-14 18:17:46 +08:00
dudaodong
d491bea263 feat: add BubbleSort and InsertionSort 2022-01-14 17:57:14 +08:00
dudaodong
6f1feb96d6 experimental feature, algorithm/sorter.go try to implements sort function with go generics 2022-01-14 17:01:44 +08:00
dudaodong
d46d12f949 feat: add func ContainSubSlice 2022-01-13 11:52:21 +08:00
dudaodong
c6fc92a94c update go version to v1.18 2022-01-12 10:23:04 +08:00
dudaodong
f4fa790b72 Merge branch 'main' into v2 2022-01-12 10:05:35 +08:00
dudaodong
22798fd750 fix: fix some go report issue 2022-01-12 10:01:48 +08:00
dudaodong
907df56f86 update: make func comment consistent 2022-01-11 20:27:06 +08:00
dudaodong
3dadfa234b update: make func comment consistent 2022-01-11 19:33:15 +08:00
donutloop
f1d7154179 refactor: sort (#21)
Removed reverse func because it use to much cpu and add test cas for asc sort
2022-01-11 19:24:36 +08:00
dudaodong
dc47b9ce98 fix: fix confict in readme file 2022-01-11 18:15:09 +08:00
dudaodong
6e626851cf merge #pr20 2022-01-11 18:12:57 +08:00
donutloop
c906d8aea7 Slice: group by and without v2 (#20)
* Slice: group by and without v2

Migrate from reflection to generic

* update doc
2022-01-11 18:11:01 +08:00
dudaodong
e5e4e09308 comment without func 2022-01-11 18:10:21 +08:00
dudaodong
7ed173849a refactor: rewrite DeleteByIndex, InsertByIndex, UpdateByIndex and Without func with generics 2022-01-11 18:08:22 +08:00
donutloop
24c0d95112 Slice: reverse and shufffle v2 (#19)
* Slice: reverse and shufffle v2

Migrate from reflection to generic form

Note: after migration, old reverse must be removed

* Suffle test: remove reflection calls

* Reverse test: change name of test
2022-01-10 19:52:23 +08:00
dudaodong
e9fed34729 fmt: slice.go 2022-01-10 10:27:20 +08:00
dudaodong
9caefdb67d fmt: slice.go 2022-01-10 10:24:33 +08:00
dudaodong
681d5b6bdf update comment for Count func 2022-01-09 22:17:50 +08:00
dudaodong
b0e9758e0d Merge branch 'v2' of github.com:duke-git/lancet into v2 2022-01-09 22:15:18 +08:00
donutloop
7b9a8a55e7 Slice: CountV2 (#18)
Use generic instead of reflection
2022-01-09 22:15:03 +08:00
dudaodong
44ac82e8b8 refactor: rewrite some slice functions with go generics 2022-01-09 22:14:46 +08:00
dudaodong
c4b4cb1173 merge master: rewrite all unit test functions with assert 2022-01-09 18:33:00 +08:00
donutloop
30d798366b Slice: find v2 (#17)
* If slice len is zero then return false
* Convert find to generic form.
* If return T is nil then no items matched the predicate func
2022-01-07 20:19:27 +08:00
dudaodong
3e9a2b5c59 refactor: refact Filter, ForEach, Map func with generics 2022-01-07 17:53:55 +08:00
dudaodong
1343683b08 checkout v2 branch for generics migration 2022-01-07 17:48:00 +08:00
99 changed files with 6284 additions and 1378 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.16" go-version: "1.18"
- 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

View File

@@ -4,9 +4,9 @@
<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-1.2.6-green.svg)](https://github.com/duke-git/lancet/releases) [![Release](https://img.shields.io/badge/release-2.0.0-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet) [![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/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)
[![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)
@@ -24,14 +24,21 @@ English | [简体中文](./README_zh-CN.md)
## Feature ## Feature
- 👏 Comprehensive, efficient and reusable. - 👏 Comprehensive, efficient and reusable.
- 💪 180+ go util functions, support string, slice, datetime, net, crypt... - 💪 250+ 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 go get github.com/duke-git/lancet/v2 // will install latest version of v2.x.x
```
2. <b>For users who use version below go1.18, you should install v1.x.x. now latest v1 is v1.2.6. </b>
```go
go get github.com/duke-git/lancet@v1.2.6 // below go1.18, install latest version of v1.x.x
``` ```
## Usage ## Usage
@@ -39,7 +46,7 @@ go get github.com/duke-git/lancet
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/strutil" import "github.com/duke-git/lancet/v2/strutil"
``` ```
## Example ## Example
@@ -62,10 +69,31 @@ func main() {
``` ```
## API Documentation ## API Documentation
### Algorithm package implements some basic algorithm. eg. sort, search.
```go
import "github.com/duke-git/lancet/v2/algorithm"
```
#### 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. ### Convertor package contains some functions for data convertion.
```go ```go
import "github.com/duke-git/lancet/convertor" 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)
@@ -81,7 +109,7 @@ import "github.com/duke-git/lancet/convertor"
### Cryptor package is for data encryption and decryption. ### Cryptor package is for data encryption and decryption.
```go ```go
import "github.com/duke-git/lancet/cryptor" import "github.com/duke-git/lancet/v2/cryptor"
``` ```
#### Function list: #### Function list:
@@ -122,7 +150,7 @@ import "github.com/duke-git/lancet/cryptor"
```go ```go
import "github.com/duke-git/lancet/datetime" import "github.com/duke-git/lancet/v2/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)
@@ -151,7 +179,7 @@ import "github.com/duke-git/lancet/datetime"
### Fileutil package implements some basic functions for file operations. ### Fileutil package implements some basic functions for file operations.
```go ```go
import "github.com/duke-git/lancet/fileutil" import "github.com/duke-git/lancet/v2/fileutil"
``` ```
#### Function list #### Function list
@@ -174,7 +202,7 @@ import "github.com/duke-git/lancet/fileutil"
### Formatter contains some functions for data formatting. ### Formatter contains some functions for data formatting.
```go ```go
import "github.com/duke-git/lancet/formatter" import "github.com/duke-git/lancet/v2/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)
@@ -182,7 +210,7 @@ import "github.com/duke-git/lancet/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/function" import "github.com/duke-git/lancet/v2/function"
``` ```
#### Function list: #### Function list:
@@ -198,7 +226,7 @@ import "github.com/duke-git/lancet/function"
### Mathutil package implements some functions for math calculation. ### Mathutil package implements some functions for math calculation.
```go ```go
import "github.com/duke-git/lancet/mathutil" import "github.com/duke-git/lancet/v2/mathutil"
``` ```
#### Function list: #### Function list:
@@ -214,7 +242,7 @@ import "github.com/duke-git/lancet/mathutil"
### Netutil package contains functions to get net information and send http request. ### Netutil package contains functions to get net information and send http request.
```go ```go
import "github.com/duke-git/lancet/netutil" import "github.com/duke-git/lancet/v2/netutil"
``` ```
#### Function list: #### Function list:
@@ -234,7 +262,7 @@ import "github.com/duke-git/lancet/netutil"
### Random package implements some basic functions to generate random int and string. ### Random package implements some basic functions to generate random int and string.
```go ```go
import "github.com/duke-git/lancet/random" import "github.com/duke-git/lancet/v2/random"
``` ```
#### Function list: #### Function list:
@@ -246,7 +274,7 @@ import "github.com/duke-git/lancet/random"
### Retry package is for executing a function repeatedly until it was successful or canceled by the context. ### 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/retry" import "github.com/duke-git/lancet/v2/retry"
``` ```
#### Function list: #### Function list:
@@ -259,7 +287,7 @@ import "github.com/duke-git/lancet/retry"
### Slice contains some functions to manipulate slice. ### Slice contains some functions to manipulate slice.
```go ```go
import "github.com/duke-git/lancet/slice" import "github.com/duke-git/lancet/v2/slice"
``` ```
#### Function list: #### Function list:
@@ -271,7 +299,8 @@ import "github.com/duke-git/lancet/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)
- [DeleteByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DeleteByIndex) - [DifferenceWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceWith)
- [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)
- [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)
@@ -283,9 +312,9 @@ import "github.com/duke-git/lancet/slice"
- [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)
- [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)
- [InsertByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InsertByIndex) - [InsertAt](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InsertAt)
- [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)
- [ReverseSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ReverseSlice) - [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reverse)
- [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)
@@ -293,13 +322,12 @@ import "github.com/duke-git/lancet/slice"
- [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)
- [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)
- [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)
- [UpdateByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UpdateByIndex) - [UpdateAt](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UpdateAt)
- [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. ### Strutil package contains some functions to manipulate string.
```go ```go
import "github.com/duke-git/lancet/strutil" import "github.com/duke-git/lancet/v2/strutil"
``` ```
#### Function list: #### Function list:
@@ -324,9 +352,8 @@ import "github.com/duke-git/lancet/strutil"
### System package contain some functions about os, runtime, shell command. ### System package contain some functions about os, runtime, shell command.
```go ```go
import "github.com/duke-git/lancet/system" import "github.com/duke-git/lancet/v2/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)
@@ -340,8 +367,9 @@ import "github.com/duke-git/lancet/system"
### Validator package contains some functions for data validation. ### Validator package contains some functions for data validation.
```go ```go
import "github.com/duke-git/lancet/validator" import "github.com/duke-git/lancet/v2/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)
@@ -370,6 +398,13 @@ import "github.com/duke-git/lancet/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,9 +4,9 @@
<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-1.2.6-green.svg)](https://github.com/duke-git/lancet/releases) [![Release](https://img.shields.io/badge/release-2.0.0-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet) [![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/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)
[![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)
@@ -24,14 +24,21 @@
## 特性 ## 特性
- 👏 全面、高效、可复用 - 👏 全面、高效、可复用
- 💪 180+常用go工具函数支持string、slice、datetime、net、crypt... - 💪 250+常用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 go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
```
2. <b>使用go1.18以下版本的用户必须安装v1.x.x。目前最新的v1版本是v1.2.6。</b>
```go
go get github.com/duke-git/lancet@v1.2.6 // 使用go1.18以下版本, 必须安装v1.x.x版本
``` ```
## 用法 ## 用法
@@ -39,7 +46,7 @@ go get github.com/duke-git/lancet
lancet是以包的结构组织代码的使用时需要导入相应的包名。例如如果使用字符串相关函数需要导入strutil包: lancet是以包的结构组织代码的使用时需要导入相应的包名。例如如果使用字符串相关函数需要导入strutil包:
```go ```go
import "github.com/duke-git/lancet/strutil" import "github.com/duke-git/lancet/v2/strutil"
``` ```
## 例子 ## 例子
@@ -62,10 +69,30 @@ func main() {
``` ```
## API文档 ## API文档
### algorithm算法包实现一些基本算法。eg. sort, search.
```go
import "github.com/duke-git/lancet/v2/algorithm"
```
#### 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转换器包支持一些常见的数据类型转换。 ### convertor转换器包支持一些常见的数据类型转换。
```go ```go
import "github.com/duke-git/lancet/convertor" 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)
@@ -81,7 +108,7 @@ import "github.com/duke-git/lancet/convertor"
### cryptor加密包支持数据加密和解密获取md5hash值。支持base64, md5, hmac, aes, des, rsa。 ### cryptor加密包支持数据加密和解密获取md5hash值。支持base64, md5, hmac, aes, des, rsa。
```go ```go
import "github.com/duke-git/lancet/cryptor" import "github.com/duke-git/lancet/v2/cryptor"
``` ```
#### 函数列表: #### 函数列表:
@@ -122,7 +149,7 @@ import "github.com/duke-git/lancet/cryptor"
```go ```go
import "github.com/duke-git/lancet/datetime" import "github.com/duke-git/lancet/v2/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)
@@ -151,7 +178,7 @@ import "github.com/duke-git/lancet/datetime"
### fileutil包支持文件基本操作。 ### fileutil包支持文件基本操作。
```go ```go
import "github.com/duke-git/lancet/fileutil" import "github.com/duke-git/lancet/v2/fileutil"
``` ```
#### 函数列表: #### 函数列表:
@@ -174,7 +201,7 @@ import "github.com/duke-git/lancet/fileutil"
### formatter格式化器包含一些数据格式化处理方法。 ### formatter格式化器包含一些数据格式化处理方法。
```go ```go
import "github.com/duke-git/lancet/formatter" import "github.com/duke-git/lancet/v2/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)
@@ -183,7 +210,7 @@ import "github.com/duke-git/lancet/formatter"
### function函数包控制函数执行流程包含部分函数式编程。 ### function函数包控制函数执行流程包含部分函数式编程。
```go ```go
import "github.com/duke-git/lancet/function" import "github.com/duke-git/lancet/v2/function"
``` ```
#### 函数列表: #### 函数列表:
@@ -198,7 +225,7 @@ import "github.com/duke-git/lancet/function"
### mathutil包实现了一些数学计算的函数。 ### mathutil包实现了一些数学计算的函数。
```go ```go
import "github.com/duke-git/lancet/mathutil" import "github.com/duke-git/lancet/v2/mathutil"
``` ```
#### Function list: #### Function list:
@@ -213,7 +240,7 @@ import "github.com/duke-git/lancet/mathutil"
### netutil网络包支持获取ip地址发送http请求。 ### netutil网络包支持获取ip地址发送http请求。
```go ```go
import "github.com/duke-git/lancet/netutil" import "github.com/duke-git/lancet/v2/netutil"
``` ```
#### 函数列表: #### 函数列表:
@@ -233,7 +260,7 @@ import "github.com/duke-git/lancet/netutil"
### random随机数生成器包可以生成随机[]bytes, int, string。 ### random随机数生成器包可以生成随机[]bytes, int, string。
```go ```go
import "github.com/duke-git/lancet/random" import "github.com/duke-git/lancet/v2/random"
``` ```
#### 函数列表: #### 函数列表:
@@ -244,7 +271,7 @@ import "github.com/duke-git/lancet/random"
### retry重试执行函数直到函数运行成功或被context cancel。 ### retry重试执行函数直到函数运行成功或被context cancel。
```go ```go
import "github.com/duke-git/lancet/retry" import "github.com/duke-git/lancet/v2/retry"
``` ```
#### 函数列表: #### 函数列表:
@@ -258,7 +285,7 @@ import "github.com/duke-git/lancet/retry"
### slice包包含操作切片的方法集合。 ### slice包包含操作切片的方法集合。
```go ```go
import "github.com/duke-git/lancet/slice" import "github.com/duke-git/lancet/v2/slice"
``` ```
#### 函数列表: #### 函数列表:
@@ -270,7 +297,8 @@ import "github.com/duke-git/lancet/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)
- [DeleteByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DeleteByIndex) - [DifferenceWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceWith)
- [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)
- [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)
@@ -282,9 +310,9 @@ import "github.com/duke-git/lancet/slice"
- [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)
- [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)
- [InsertByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InsertByIndex) - [InsertAt](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InsertAt)
- [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)
- [ReverseSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ReverseSlice) - [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reverse)
- [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)
@@ -292,14 +320,14 @@ import "github.com/duke-git/lancet/slice"
- [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)
- [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)
- [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)
- [UpdateByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UpdateByIndex) - [UpdateAt](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UpdateAt)
- [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包含处理字符串的相关函数。 ### strutil包含处理字符串的相关函数。
```go ```go
import "github.com/duke-git/lancet/strutil" import "github.com/duke-git/lancet/v2/strutil"
``` ```
#### 函数列表: #### 函数列表:
@@ -325,7 +353,7 @@ import "github.com/duke-git/lancet/strutil"
### system包含os, runtime, shell command相关函数。 ### system包含os, runtime, shell command相关函数。
```go ```go
import "github.com/duke-git/lancet/system" import "github.com/duke-git/lancet/v2/system"
``` ```
#### 函数列表: #### 函数列表:
@@ -341,7 +369,7 @@ import "github.com/duke-git/lancet/system"
### validator验证器包包含常用字符串格式验证函数。 ### validator验证器包包含常用字符串格式验证函数。
```go ```go
import "github.com/duke-git/lancet/validator" import "github.com/duke-git/lancet/v2/validator"
``` ```
#### 函数列表: #### 函数列表:
@@ -372,6 +400,14 @@ import "github.com/duke-git/lancet/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)
## 如何贡献代码 ## 如何贡献代码

102
algorithm/lru_cache.go Normal file
View File

@@ -0,0 +1,102 @@
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

@@ -0,0 +1,36 @@
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)
}

63
algorithm/search.go Normal file
View File

@@ -0,0 +1,63 @@
// 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
}

33
algorithm/search_test.go Normal file
View File

@@ -0,0 +1,33 @@
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))
}

208
algorithm/sorter.go Normal file
View File

@@ -0,0 +1,208 @@
// 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] = preItem
}
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]
}

177
algorithm/sorter_test.go Normal file
View File

@@ -0,0 +1,177 @@
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 := 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 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

@@ -21,7 +21,7 @@ func ToBool(s string) (bool, error) {
} }
// ToBytes convert interface to bytes // ToBytes convert interface to bytes
func ToBytes(data interface{}) ([]byte, error) { func ToBytes(data any) ([]byte, error) {
var buf bytes.Buffer var buf bytes.Buffer
enc := gob.NewEncoder(&buf) enc := gob.NewEncoder(&buf)
err := enc.Encode(data) err := enc.Encode(data)
@@ -44,7 +44,7 @@ func ToChar(s string) []string {
} }
// ToString convert value to string // ToString convert value to string
func ToString(value interface{}) string { func ToString(value any) string {
res := "" res := ""
if value == nil { if value == nil {
return res return res
@@ -76,7 +76,7 @@ func ToString(value interface{}) string {
} }
// ToJson convert value to a valid json string // ToJson convert value to a valid json string
func ToJson(value interface{}) (string, error) { func ToJson(value any) (string, error) {
res, err := json.Marshal(value) res, err := json.Marshal(value)
if err != nil { if err != nil {
return "", err return "", err
@@ -86,7 +86,7 @@ func ToJson(value interface{}) (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 interface{}) (float64, error) { func ToFloat(value any) (float64, error) {
v := reflect.ValueOf(value) v := reflect.ValueOf(value)
res := 0.0 res := 0.0
@@ -113,7 +113,7 @@ func ToFloat(value interface{}) (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 interface{}) (int64, error) { func ToInt(value any) (int64, error) {
v := reflect.ValueOf(value) v := reflect.ValueOf(value)
var res int64 var res int64
@@ -141,7 +141,7 @@ func ToInt(value interface{}) (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 interface{}) (map[string]interface{}, error) { func StructToMap(value any) (map[string]any, error) {
v := reflect.ValueOf(value) v := reflect.ValueOf(value)
t := reflect.TypeOf(value) t := reflect.TypeOf(value)
@@ -152,7 +152,7 @@ func StructToMap(value interface{}) (map[string]interface{}, 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]interface{}) res := make(map[string]any)
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/internal" "github.com/duke-git/lancet/v2/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 := []interface{}{ cases := []any{
0, 0,
false, false,
"1", "1",
@@ -55,7 +55,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 := []interface{}{"123", "-123", 123, cases := []any{"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"}
@@ -71,7 +71,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 := []interface{}{ cases := []any{
"", "-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),
@@ -99,7 +99,7 @@ func TestToString(t *testing.T) {
} }
aStruct := TestStruct{Name: "TestStruct"} aStruct := TestStruct{Name: "TestStruct"}
cases := []interface{}{ cases := []any{
"", 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),
@@ -147,7 +147,7 @@ func TestStructToMap(t *testing.T) {
100, 100,
} }
pm, _ := StructToMap(p) pm, _ := StructToMap(p)
var expected = map[string]interface{}{"name": "test"} var expected = map[string]any{"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/internal" "github.com/duke-git/lancet/v2/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/internal" "github.com/duke-git/lancet/v2/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/internal" "github.com/duke-git/lancet/v2/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/internal" "github.com/duke-git/lancet/v2/internal"
) )
func TestRsaEncrypt(t *testing.T) { func TestRsaEncrypt(t *testing.T) {

View File

@@ -0,0 +1,241 @@
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

@@ -0,0 +1,182 @@
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)
err = link.InsertAt(0, 1)
err = link.InsertAt(1, 2)
err = link.InsertAt(2, 4)
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 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

@@ -0,0 +1,224 @@
package datastructure
import (
"errors"
"fmt"
"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")
}
// 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

@@ -0,0 +1,182 @@
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)
err = link.InsertAt(1, 2)
err = link.InsertAt(2, 4)
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_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())
}

245
datastructure/list/list.go Normal file
View File

@@ -0,0 +1,245 @@
// 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

@@ -0,0 +1,272 @@
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{})
v, 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{})
v, 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))
}

47
datastructure/node.go Normal file
View File

@@ -0,0 +1,47 @@
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

@@ -0,0 +1,92 @@
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

@@ -0,0 +1,90 @@
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

@@ -0,0 +1,118 @@
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

@@ -0,0 +1,148 @@
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

@@ -0,0 +1,104 @@
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

@@ -0,0 +1,84 @@
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]()
val, 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]()
val, 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())
}

105
datastructure/set/set.go Normal file
View File

@@ -0,0 +1,105 @@
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
}

View File

@@ -0,0 +1,129 @@
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)
}

View File

@@ -0,0 +1,62 @@
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

@@ -0,0 +1,77 @@
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]()
topItem, 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]()
topItem, 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

@@ -0,0 +1,94 @@
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

@@ -0,0 +1,80 @@
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]()
topItem, 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]()
topItem, 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

@@ -0,0 +1,83 @@
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

@@ -0,0 +1,142 @@
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

@@ -0,0 +1,224 @@
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

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

593
docs/algorithm.md Normal file
View File

@@ -0,0 +1,593 @@
# 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
}
```

593
docs/algorithm_zh-CN.md Normal file
View File

@@ -0,0 +1,593 @@
# 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/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/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/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
``` ```
@@ -50,12 +50,12 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
colorHex := "#003366" colorHex := "#003366"
r, g, b := ColorHexToRGB(colorHex) r, g, b := convertor.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/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
r := 0 r := 0
g := 51 g := 51
b := 102 b := 102
colorHex := ColorRGBToHex(r, g, b) colorHex := convertor.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/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -136,7 +136,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ToBytes(data interface{}) ([]byte, error) func ToBytes(data any) ([]byte, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -145,7 +145,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -175,7 +175,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -199,7 +199,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ToFloat(value interface{}) (float64, error) func ToFloat(value any) (float64, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -208,7 +208,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -232,7 +232,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ToInt(value interface{}) (int64, error) func ToInt(value any) (int64, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -241,7 +241,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -265,7 +265,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ToJson(value interface{}) (string, error) func ToJson(value any) (string, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -274,7 +274,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -293,7 +293,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ToString(value interface{}) string func ToString(value any) string
``` ```
<b>Example:</b> <b>Example:</b>
@@ -302,7 +302,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -321,7 +321,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func StructToMap(value interface{}) (map[string]interface{}, error) func StructToMap(value any) (map[string]any, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -330,7 +330,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/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/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/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/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
``` ```
@@ -52,12 +52,12 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
colorHex := "#003366" colorHex := "#003366"
r, g, b := ColorHexToRGB(colorHex) r, g, b := convertor.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/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
r := 0 r := 0
g := 51 g := 51
b := 102 b := 102
colorHex := ColorRGBToHex(r, g, b) colorHex := convertor.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/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -138,7 +138,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ToBytes(data interface{}) ([]byte, error) func ToBytes(data any) ([]byte, error)
``` ```
<b>列子:</b> <b>列子:</b>
@@ -147,7 +147,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -177,7 +177,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -201,7 +201,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ToFloat(value interface{}) (float64, error) func ToFloat(value any) (float64, error)
``` ```
<b>列子:</b> <b>列子:</b>
@@ -210,7 +210,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -234,7 +234,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ToInt(value interface{}) (int64, error) func ToInt(value any) (int64, error)
``` ```
<b>例子:</b> <b>例子:</b>
@@ -243,7 +243,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -267,7 +267,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ToJson(value interface{}) (string, error) func ToJson(value any) (string, error)
``` ```
<b>列子:</b> <b>列子:</b>
@@ -276,7 +276,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -295,7 +295,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ToString(value interface{}) string func ToString(value any) string
``` ```
<b>例子:</b> <b>例子:</b>
@@ -304,7 +304,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {
@@ -323,7 +323,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func StructToMap(value interface{}) (map[string]interface{}, error) func StructToMap(value any) (map[string]any, error)
``` ```
<b>列子:</b> <b>列子:</b>
@@ -332,7 +332,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/v2/convertor"
) )
func main() { func main() {

View File

@@ -15,7 +15,7 @@ Package cryptor contains some functions for data encryption and decryption. Supp
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
``` ```
@@ -80,7 +80,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -110,7 +110,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -140,7 +140,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -171,7 +171,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -202,7 +202,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -234,7 +234,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -264,7 +264,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -295,7 +295,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -325,7 +325,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -356,7 +356,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -384,7 +384,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -412,7 +412,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -443,7 +443,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -475,7 +475,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -506,7 +506,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -538,7 +538,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -570,7 +570,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -600,7 +600,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -631,7 +631,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -661,7 +661,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -693,7 +693,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -721,7 +721,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -749,7 +749,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -777,7 +777,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -806,7 +806,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -834,7 +834,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -862,7 +862,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -890,7 +890,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -918,7 +918,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -946,7 +946,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -976,7 +976,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -1012,7 +1012,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {

View File

@@ -15,7 +15,7 @@ cryptor加密包支持数据加密和解密获取md5hash值。支持base64
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
``` ```
@@ -80,7 +80,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -110,7 +110,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -140,7 +140,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -171,7 +171,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -203,7 +203,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -235,7 +235,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -265,7 +265,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -296,7 +296,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -326,7 +326,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -356,7 +356,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -384,7 +384,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -412,7 +412,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -443,7 +443,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -475,7 +475,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -506,7 +506,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -538,7 +538,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -570,7 +570,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -600,7 +600,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -631,7 +631,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -661,7 +661,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -692,7 +692,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -720,7 +720,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -748,7 +748,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -776,7 +776,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -805,7 +805,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -833,7 +833,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -861,7 +861,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -889,7 +889,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -917,7 +917,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -945,7 +945,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -975,7 +975,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {
@@ -1009,7 +1009,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/v2/cryptor"
) )
func main() { func main() {

View File

@@ -5,14 +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/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.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/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
``` ```
@@ -86,7 +86,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -115,7 +115,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -143,7 +143,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -171,7 +171,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -197,7 +197,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -223,7 +223,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -251,7 +251,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -279,7 +279,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -306,7 +306,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -334,7 +334,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -360,7 +360,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -386,7 +386,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -414,7 +414,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -442,7 +442,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -469,7 +469,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -496,7 +496,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -523,7 +523,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -550,7 +550,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -577,7 +577,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -604,7 +604,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -630,7 +630,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -656,7 +656,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/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/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/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/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
``` ```
@@ -85,7 +85,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -114,7 +114,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -142,7 +142,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -170,7 +170,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -196,7 +196,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -222,7 +222,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -250,7 +250,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -278,7 +278,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -305,7 +305,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -333,7 +333,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -359,7 +359,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -385,7 +385,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -413,7 +413,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -441,7 +441,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -468,7 +468,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -495,7 +495,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -522,7 +522,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -549,7 +549,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -576,7 +576,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -603,7 +603,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -629,7 +629,7 @@ package main
import ( import (
"fmt" "fmt"
"time" "time"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {
@@ -655,7 +655,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/v2/datetime"
) )
func main() { func main() {

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/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/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/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
``` ```
@@ -56,7 +56,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -82,7 +82,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -107,7 +107,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -135,7 +135,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -155,7 +155,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func MiMeType(file interface{}) string func MiMeType(file any) string
``` ```
<b>Example:</b> <b>Example:</b>
@@ -165,7 +165,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -196,7 +196,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -223,7 +223,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -249,7 +249,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -278,7 +278,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -304,7 +304,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -332,7 +332,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -365,7 +365,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -398,7 +398,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -427,7 +427,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/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/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/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/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
``` ```
@@ -56,7 +56,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -82,7 +82,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -107,7 +107,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -135,7 +135,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -155,7 +155,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func MiMeType(file interface{}) string func MiMeType(file any) string
``` ```
<b>例子:</b> <b>例子:</b>
@@ -165,7 +165,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -196,7 +196,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -223,7 +223,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -249,7 +249,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -278,7 +278,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -304,7 +304,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -332,7 +332,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -365,7 +365,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -398,7 +398,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/fileutil"
) )
func main() { func main() {
@@ -427,7 +427,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/v2/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/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/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/formatter" "github.com/duke-git/lancet/v2/formatter"
) )
``` ```
@@ -34,7 +34,7 @@ Param should be number or numberic string.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Comma(v interface{}, symbol string) string func Comma(v any, symbol string) string
``` ```
<b>Example:</b> <b>Example:</b>
@@ -43,7 +43,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/formatter" "github.com/duke-git/lancet/v2/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/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/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/formatter" "github.com/duke-git/lancet/v2/formatter"
) )
``` ```
@@ -33,7 +33,7 @@ import (
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Comma(v interface{}, symbol string) string func Comma(v any, symbol string) string
``` ```
<b>例子:</b> <b>例子:</b>
@@ -42,7 +42,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/formatter" "github.com/duke-git/lancet/v2/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/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go)
[https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go) - [https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/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/function" "github.com/duke-git/lancet/v2/function"
) )
``` ```
@@ -40,7 +40,7 @@ import (
<b>Signature:</b> <b>Signature:</b>
```go ```go
func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value func After(n int, fn any) func(args ...any) []reflect.Value
``` ```
<b>Example:</b> <b>Example:</b>
@@ -49,7 +49,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/function"
) )
func main() { func main() {
@@ -59,7 +59,7 @@ func main() {
return i return i
}) })
type cb func(args ...interface{}) []reflect.Value type cb func(args ...any) []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 interface{}) func(args ...interface{}) []reflect.Value func Before(n int, fn any) func(args ...any) []reflect.Value
``` ```
<b>Example:</b> <b>Example:</b>
@@ -96,8 +96,8 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/function"
"github.com/duke-git/lancet/internal" "github.com/duke-git/lancet/v2/internal"
) )
func main() { func main() {
@@ -109,7 +109,7 @@ func main() {
}) })
var res []int64 var res []int64
type cb func(args ...interface{}) []reflect.Value type cb func(args ...any) []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(...interface{}) interface{} type Fn func(...any) any
func (f Fn) Curry(i interface{}) func(...interface{}) interface{} func (f Fn) Curry(i any) func(...any) any
``` ```
<b>Example:</b> <b>Example:</b>
@@ -143,14 +143,14 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/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 ...interface{}) interface{} { var addCurry function.Fn = func(values ...any) any {
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(...interface{}) interface{}) func(...interface{}) interface{} func Compose(fnList ...func(...any) any) func(...any) any
``` ```
<b>Example:</b> <b>Example:</b>
@@ -177,14 +177,14 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/function"
) )
func main() { func main() {
add1 := func(v ...interface{}) interface{} { add1 := func(v ...any) any {
return v[0].(int) + 1 return v[0].(int) + 1
} }
add2 := func(v ...interface{}) interface{} { add2 := func(v ...any) any {
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/function" "github.com/duke-git/lancet/v2/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 interface{}, args ...interface{}) func Delay(delay time.Duration, fn any, args ...any)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -255,7 +255,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/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 interface{}, args ...interface{}) chan bool func Schedule(d time.Duration, fn any, args ...any) chan bool
``` ```
<b>Example:</b> <b>Example:</b>
@@ -284,7 +284,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/function"
) )
func main() { func main() {
@@ -327,7 +327,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/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/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go)
[https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go) - [https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/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/function" "github.com/duke-git/lancet/v2/function"
) )
``` ```
@@ -40,7 +40,7 @@ import (
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value func After(n int, fn any) func(args ...any) []reflect.Value
``` ```
<b>例子:</b> <b>例子:</b>
@@ -49,7 +49,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/function"
) )
func main() { func main() {
@@ -59,7 +59,7 @@ func main() {
return i return i
}) })
type cb func(args ...interface{}) []reflect.Value type cb func(args ...any) []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 interface{}) func(args ...interface{}) []reflect.Value func Before(n int, fn any) func(args ...any) []reflect.Value
``` ```
<b>例子:</b> <b>例子:</b>
@@ -96,8 +96,8 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/function"
"github.com/duke-git/lancet/internal" "github.com/duke-git/lancet/v2/internal"
) )
func main() { func main() {
@@ -109,7 +109,7 @@ func main() {
}) })
var res []int64 var res []int64
type cb func(args ...interface{}) []reflect.Value type cb func(args ...any) []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(...interface{}) interface{} type Fn func(...any) any
func (f Fn) Curry(i interface{}) func(...interface{}) interface{} func (f Fn) Curry(i any) func(...any) any
``` ```
<b>例子:</b> <b>例子:</b>
@@ -143,14 +143,14 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/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 ...interface{}) interface{} { var addCurry function.Fn = func(values ...any) any {
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(...interface{}) interface{}) func(...interface{}) interface{} func Compose(fnList ...func(...any) any) func(...any) any
``` ```
<b>例子:</b> <b>例子:</b>
@@ -177,14 +177,14 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/function"
) )
func main() { func main() {
add1 := func(v ...interface{}) interface{} { add1 := func(v ...any) any {
return v[0].(int) + 1 return v[0].(int) + 1
} }
add2 := func(v ...interface{}) interface{} { add2 := func(v ...any) any {
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/function" "github.com/duke-git/lancet/v2/function"
) )
func main() { func main() {
@@ -246,7 +246,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Delay(delay time.Duration, fn interface{}, args ...interface{}) func Delay(delay time.Duration, fn any, args ...any)
``` ```
<b>例子:</b> <b>例子:</b>
@@ -255,7 +255,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/function"
) )
func main() { func main() {
@@ -275,7 +275,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool func Schedule(d time.Duration, fn any, args ...any) chan bool
``` ```
<b>例子:</b> <b>例子:</b>
@@ -284,7 +284,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/function"
) )
func main() { func main() {
@@ -327,7 +327,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/v2/function"
) )
func main() { func main() {

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/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ Package mathutil implements some functions for math calculation.
## Example: ## Example:
```go ```go
import ( import (
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
``` ```
@@ -48,7 +48,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
func main() { func main() {
@@ -75,7 +75,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
func main() { func main() {
@@ -104,7 +104,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
func main() { func main() {
@@ -132,7 +132,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
func main() { func main() {
@@ -158,7 +158,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
func main() { func main() {
@@ -188,7 +188,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
func main() { func main() {
@@ -217,7 +217,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/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/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -13,7 +13,7 @@ mathutil包实现了一些数学计算的函数.
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
``` ```
@@ -49,7 +49,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
func main() { func main() {
@@ -76,7 +76,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
func main() { func main() {
@@ -105,7 +105,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
func main() { func main() {
@@ -133,7 +133,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
func main() { func main() {
@@ -159,7 +159,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
func main() { func main() {
@@ -189,7 +189,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/mathutil"
) )
func main() { func main() {
@@ -218,7 +218,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/v2/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/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go)
[https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go) - [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/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/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
``` ```
@@ -46,7 +46,7 @@ import (
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ConvertMapToQueryString(param map[string]interface{}) string func ConvertMapToQueryString(param map[string]any) string
``` ```
<b>Example:</b> <b>Example:</b>
@@ -55,11 +55,11 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
var m = map[string]interface{}{ var m = map[string]any{
"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/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -117,7 +117,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -144,7 +144,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -184,7 +184,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -215,7 +215,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/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]interface{}, // params[1] is query param which type should be url.Values or map[string]any,
// 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 ...interface{}) (*http.Response, error) func HttpGet(url string, params ...any) (*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/netutil" "github.com/duke-git/lancet/v2/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]interface{}, // params[1] is query param which type should be url.Values or map[string]any,
// 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 ...interface{}) (*http.Response, error) func HttpPost(url string, params ...any) (*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/netutil" "github.com/duke-git/lancet/v2/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]interface{}, // params[1] is query param which type should be url.Values or map[string]any,
// 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 ...interface{}) (*http.Response, error) func HttpPut(url string, params ...any) (*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/netutil" "github.com/duke-git/lancet/v2/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]interface{}, // params[1] is query param which type should be url.Values or map[string]any,
// 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 ...interface{}) (*http.Response, error) func HttpDelete(url string, params ...any) (*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/netutil" "github.com/duke-git/lancet/v2/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]interface{}, // params[1] is query param which type should be url.Values or map[string]any,
// 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 ...interface{}) (*http.Response, error) func HttpPatch(url string, params ...any) (*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/netutil" "github.com/duke-git/lancet/v2/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 interface{}) error func ParseHttpResponse(resp *http.Response, obj any) 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/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {

View File

@@ -5,16 +5,15 @@ netutil网络包支持获取ip地址发送http请求。
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go) - [https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go)
- [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go)
[https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/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/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
``` ```
@@ -46,7 +45,7 @@ import (
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ConvertMapToQueryString(param map[string]interface{}) string func ConvertMapToQueryString(param map[string]any) string
``` ```
<b>例子:</b> <b>例子:</b>
@@ -55,11 +54,11 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
var m = map[string]interface{}{ var m = map[string]any{
"c": 3, "c": 3,
"a": 1, "a": 1,
"b": 2, "b": 2,
@@ -88,7 +87,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -116,7 +115,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -143,7 +142,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -183,7 +182,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -214,7 +213,7 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -236,10 +235,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]interface{} // params[1] http查询字符串类型必须是url.Values或者map[string]any
// 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 ...interface{}) (*http.Response, error) func HttpGet(url string, params ...any) (*http.Response, error)
``` ```
<b>例子:</b> <b>例子:</b>
@@ -250,7 +249,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -278,10 +277,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]interface{} // params[1] http查询字符串类型必须是url.Values或者map[string]any
// 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 ...interface{}) (*http.Response, error) func HttpPost(url string, params ...any) (*http.Response, error)
``` ```
<b>例子:</b> <b>例子:</b>
@@ -293,7 +292,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -327,10 +326,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]interface{} // params[1] http查询字符串类型必须是url.Values或者map[string]any
// 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 ...interface{}) (*http.Response, error) func HttpPut(url string, params ...any) (*http.Response, error)
``` ```
<b>Example:</b> <b>Example:</b>
@@ -342,7 +341,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -377,10 +376,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]interface{} // params[1] http查询字符串类型必须是url.Values或者map[string]any
// 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 ...interface{}) (*http.Response, error) func HttpDelete(url string, params ...any) (*http.Response, error)
``` ```
<b>例子:</b> <b>例子:</b>
@@ -392,7 +391,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -416,10 +415,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]interface{} // params[1] http查询字符串类型必须是url.Values或者map[string]any
// 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 ...interface{}) (*http.Response, error) func HttpPatch(url string, params ...any) (*http.Response, error)
``` ```
<b>例子:</b> <b>例子:</b>
@@ -431,7 +430,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/netutil"
) )
func main() { func main() {
@@ -465,7 +464,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ParseHttpResponse(resp *http.Response, obj interface{}) error func ParseHttpResponse(resp *http.Response, obj any) error
``` ```
<b>例子:</b> <b>例子:</b>
@@ -477,7 +476,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"github.com/duke-git/lancet/netutil" "github.com/duke-git/lancet/v2/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/main/random/random.go](https://github.com/duke-git/lancet/blob/main/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/random" "github.com/duke-git/lancet/v2/random"
) )
``` ```
@@ -45,7 +45,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/random" "github.com/duke-git/lancet/v2/random"
) )
func main() { func main() {
@@ -70,7 +70,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/random" "github.com/duke-git/lancet/v2/random"
) )
func main() { func main() {
@@ -96,7 +96,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/random" "github.com/duke-git/lancet/v2/random"
) )
func main() { func main() {
@@ -123,7 +123,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/random" "github.com/duke-git/lancet/v2/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/main/random/random.go](https://github.com/duke-git/lancet/blob/main/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/random" "github.com/duke-git/lancet/v2/random"
) )
``` ```
@@ -46,7 +46,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/random" "github.com/duke-git/lancet/v2/random"
) )
func main() { func main() {
@@ -71,7 +71,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/random" "github.com/duke-git/lancet/v2/random"
) )
func main() { func main() {
@@ -97,7 +97,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/random" "github.com/duke-git/lancet/v2/random"
) )
func main() { func main() {
@@ -123,7 +123,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/random" "github.com/duke-git/lancet/v2/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/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/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/retry" "github.com/duke-git/lancet/v2/retry"
) )
``` ```
@@ -46,7 +46,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"github.com/duke-git/lancet/retry" "github.com/duke-git/lancet/v2/retry"
"time" "time"
) )
@@ -92,7 +92,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/retry" "github.com/duke-git/lancet/v2/retry"
) )
func main() { func main() {
@@ -134,7 +134,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/retry" "github.com/duke-git/lancet/v2/retry"
) )
func main() { func main() {
@@ -173,7 +173,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/retry" "github.com/duke-git/lancet/v2/retry"
) )
func main() { func main() {
@@ -213,7 +213,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/retry" "github.com/duke-git/lancet/v2/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/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/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/retry" "github.com/duke-git/lancet/v2/retry"
) )
``` ```
@@ -94,7 +94,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/retry" "github.com/duke-git/lancet/v2/retry"
) )
func main() { func main() {
@@ -136,7 +136,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/retry" "github.com/duke-git/lancet/v2/retry"
) )
func main() { func main() {
@@ -175,7 +175,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/retry" "github.com/duke-git/lancet/v2/retry"
) )
func main() { func main() {
@@ -215,7 +215,7 @@ import (
"fmt" "fmt"
"errors" "errors"
"log" "log"
"github.com/duke-git/lancet/retry" "github.com/duke-git/lancet/v2/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/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/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/slice" "github.com/duke-git/lancet/v2/slice"
) )
``` ```
@@ -28,7 +28,8 @@ import (
- [Count](#Count) - [Count](#Count)
- [Difference](#Difference) - [Difference](#Difference)
- [DifferenceBy](#DifferenceBy) - [DifferenceBy](#DifferenceBy)
- [DeleteByIndex](#DeleteByIndex) - [DifferenceWith](#DifferenceWith)
- [DeleteAt](#DeleteAt)
- [Drop](#Drop) - [Drop](#Drop)
- [Every](#Every) - [Every](#Every)
- [Filter](#Filter) - [Filter](#Filter)
@@ -41,9 +42,9 @@ import (
- [IntSlice](#IntSlice) - [IntSlice](#IntSlice)
- [InterfaceSlice](#InterfaceSlice) - [InterfaceSlice](#InterfaceSlice)
- [Intersection](#Intersection) - [Intersection](#Intersection)
- [InsertByIndex](#InsertByIndex) - [InsertAt](#InsertAt)
- [Map](#Map) - [Map](#Map)
- [ReverseSlice](#ReverseSlice) - [Reverse](#Reverse)
- [Reduce](#Reduce) - [Reduce](#Reduce)
- [Shuffle](#Shuffle) - [Shuffle](#Shuffle)
- [SortByField](#SortByField) - [SortByField](#SortByField)
@@ -51,30 +52,27 @@ import (
- [StringSlice](#StringSlice) - [StringSlice](#StringSlice)
- [Unique](#Unique) - [Unique](#Unique)
- [Union](#Union) - [Union](#Union)
- [UpdateByIndex](#UpdateByIndex) - [UpdateAt](#UpdateAt)
- [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. iterableType param can be string, map or slice.</p> <p>Check if the value is in the slice or not.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Contain(iterableType interface{}, value interface{}) bool func Contain[T any](slice []T, value T) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -90,14 +88,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ContainSubSlice(slice interface{}, subslice interface{}) bool func ContainSubSlice[T any](slice, subslice []T) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -115,20 +113,20 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Chunk(slice []interface{}, size int) [][]interface{} func Chunk[T any](slice []T, size int) [][]T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/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) //[][]interface{}{{"a", "b", "c"}, {"d", "e"}} fmt.Println(res) //[][]any{{"a", "b", "c"}, {"d", "e"}}
} }
``` ```
@@ -140,14 +138,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Compact(slice interface{}) interface{} func Compact[T any](slice []T) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -163,14 +161,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Concat(slice interface{}, values ...interface{}) interface{} func Concat[T any](slice []T, values ...[]T) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -185,19 +183,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. The function signature should be func(index int, value interface{}) bool.</p> <p>Count iterates over elements of slice, returns a count of all matched elements.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Count(slice, function interface{}) int func Count[T any](slice []T, predicate func(index int, t T) bool) int
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -220,14 +218,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Difference(slice1, slice2 interface{}) interface{} func Difference[T comparable](slice, comparedSlice []T) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -248,14 +246,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{} func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, t T) T) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -271,29 +269,55 @@ 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>
### <span id="DeleteByIndex">DeleteByIndex</span>
<p>Delete the element of slice from start index to end index - 1.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error) func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
res1 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 3) 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>
<b>Signature:</b>
```go
func DeleteAt[T any](slice []T, start int, end ...int)
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
res1 := slice.DeleteAt([]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.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 0, 2) res2 := slice.DeleteAt([]string{"a", "b", "c", "d", "e"}, 0, 2)
fmt.Println(res2) //[]string{"c", "d", "e"} fmt.Println(res2) //[]string{"c", "d", "e"}
} }
@@ -308,14 +332,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Drop(slice interface{}, n int) interface{} func Drop[T any](slice []T, n int) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -334,19 +358,19 @@ func main() {
### <span id="Every">Every</span> ### <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> <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(slice, function interface{}) bool func Every[T any](slice []T, predicate func(index int, t T) bool) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -364,19 +388,19 @@ func main() {
### <span id="Filter">Filter</span> ### <span id="Filter">Filter</span>
<p>Return all elements which match the function. Function signature should be func(index int, value interface{}) bool.</p> <p>Return all elements which match the function.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Filter(slice, function interface{}) interface{} func Filter[T any](slice []T, predicate func(index int, t T) bool) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -393,19 +417,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.function signature should be func(index int, value interface{}) bool.</p> <p>Iterates over elements of slice, returning the first one that passes a truth test on function.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Find(slice, function interface{}) (interface{}, bool) func Find[T any](slice []T, predicate func(index int, t T) bool) (*T, bool)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -424,19 +448,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. The function signature should be func(index int, value interface{}) bool.</p> <p>iterates over elements of slice from end to begin, returning the last one that passes a truth test on function.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func FindLast(slice, function interface{}) (interface{}, bool) func FindLast[T any](slice []T, predicate func(index int, t T) bool) (*T, bool)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -459,14 +483,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func FlattenDeep(slice interface{}) interface{} func FlattenDeep(slice any) any
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -481,19 +505,19 @@ func main() {
### <span id="ForEach">ForEach</span> ### <span id="ForEach">ForEach</span>
<p>Iterates over elements of slice and invokes function for each element, function signature should be func(index int, value interface{}).</p> <p>Iterates over elements of slice and invokes function for each element.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ForEach(slice, function interface{}) func ForEach[T any](slice []T, iteratee func(index int, t T))
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -510,19 +534,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. The function signature should be func(index int, value interface{}) bool.</p> <p>Iterates over elements of the slice, each element will be group by criteria, returns two slices.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func GroupBy(slice, function interface{}) (interface{}, interface{}) func GroupBy[T any](slice []T, groupFn func(index int, t T) bool) ([]T, []T)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -546,18 +570,18 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func IntSlice(slice interface{}) []int func IntSlice(slice any) []int
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
var nums = []interface{}{1, 2, 3} var nums = []any{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}
} }
@@ -572,20 +596,20 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func InterfaceSlice(slice interface{}) []interface{} func InterfaceSlice(slice any) []any
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/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) //[]interface{}{1, 2, 3} fmt.Println(res) //[]any{1, 2, 3}
} }
``` ```
@@ -598,14 +622,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Intersection(slices ...interface{}) interface{} func Intersection[T any](slices ...[]T) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -620,29 +644,29 @@ func main() {
### <span id="InsertByIndex">InsertByIndex</span> ### <span id="InsertAt">InsertAt</span>
<p>insert the element into slice at index.</p> <p>insert the element into slice at index.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error) func InsertAt[T any](slice []T, index int, value any) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
s := []string{"a", "b", "c"} s := []string{"a", "b", "c"}
res1, _ := slice.InsertByIndex(s, 0, "1") res1, _ := slice.InsertAt(s, 0, "1")
fmt.Println(res1) //[]string{"1", "a", "b", "c"} fmt.Println(res1) //[]string{"1", "a", "b", "c"}
res2, _ := slice.InsertByIndex(s, 3, []string{"1", "2", "3"}) res2, _ := slice.InsertAt(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"}
} }
``` ```
@@ -651,19 +675,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, function signature should be func(index int, value interface{}) interface{}.</p> <p>Creates an slice of values by running each element in slice thru function.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Map(slice, function interface{}) interface{} func Map[T any, U any](slice []T, iteratee func(index int, t T) U) []U
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -679,25 +703,25 @@ func main() {
### <span id="ReverseSlice">ReverseSlice</span> ### <span id="Reverse">Reverse</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 ReverseSlice(slice interface{}) func Reverse[T any](slice []T)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
nums := []int{1, 2, 3, 4} nums := []int{1, 2, 3, 4}
slice.ReverseSlice(nums) slice.Reverse(nums)
fmt.Println(res) //[]int{4, 3, 2, 1} fmt.Println(res) //[]int{4, 3, 2, 1}
} }
``` ```
@@ -705,19 +729,19 @@ func main() {
### <span id="Reduce">Reduce</span> ### <span id="Reduce">Reduce</span>
<p>Reduce slice, function signature should be func(index int, value1, value2 interface{}) interface{}.</p> <p>Reduce slice.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Reduce(slice, function, zero interface{}) interface{} func Reduce[T any](slice []T, iteratee func(index int, t1, t2 T) T, initial T) T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -739,14 +763,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Shuffle(slice interface{}) interface{} func Shuffle[T any](slice []T) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -764,14 +788,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func SortByField(slice interface{}, field string, sortType ...string) error func SortByField(slice any, field string, sortType ...string) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -802,19 +826,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, function signature should be func(index int, value interface{}) bool.</p> <p>Return true if any of the values in the list pass the predicate function.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Some(slice, function interface{}) bool func Some[T any](slice []T, predicate func(index int, t T) bool) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -836,18 +860,18 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func StringSlice(slice interface{}) []string func StringSlice(slice any) []string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
var s = []interface{}{"a", "b", "c"} var s = []any{"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"}
} }
@@ -862,14 +886,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Unique(slice interface{}) interface{} func Unique[T any](slice []T) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -886,14 +910,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Union(slices ...interface{}) interface{} func Union[T any](slices ...[]T) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -907,26 +931,26 @@ func main() {
### <span id="UpdateByIndex">UpdateByIndex</span> ### <span id="UpdateAt">UpdateAt</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 UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) func UpdateAt[T any](slice []T, index int, value T) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
s := []string{"a", "b", "c"} s := []string{"a", "b", "c"}
res1, _ := slice.UpdateByIndex(s, 0, "1") res1, _ := slice.UpdateAt(s, 0, "1")
fmt.Println(res1) //[]string{"1", "b", "c"} fmt.Println(res1) //[]string{"1", "b", "c"}
} }
``` ```
@@ -940,14 +964,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Without(slice interface{}, values ...interface{}) interface{} func Without[T any](slice []T, values ...T) []T
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/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/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/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/slice" "github.com/duke-git/lancet/v2/slice"
) )
``` ```
@@ -28,7 +28,8 @@ import (
- [Count](#Count) - [Count](#Count)
- [Difference](#Difference) - [Difference](#Difference)
- [DifferenceBy](#DifferenceBy) - [DifferenceBy](#DifferenceBy)
- [DeleteByIndex](#DeleteByIndex) - [DifferenceWith](#DifferenceWith)
- [DeleteAt](#DeleteAt)
- [Drop](#Drop) - [Drop](#Drop)
- [Every](#Every) - [Every](#Every)
- [Filter](#Filter) - [Filter](#Filter)
@@ -41,9 +42,9 @@ import (
- [IntSlice](#IntSlice) - [IntSlice](#IntSlice)
- [InterfaceSlice](#InterfaceSlice) - [InterfaceSlice](#InterfaceSlice)
- [Intersection](#Intersection) - [Intersection](#Intersection)
- [InsertByIndex](#InsertByIndex) - [InsertAt](#InsertAt)
- [Map](#Map) - [Map](#Map)
- [ReverseSlice](#ReverseSlice) - [Reverse](#Reverse)
- [Reduce](#Reduce) - [Reduce](#Reduce)
- [Shuffle](#Shuffle) - [Shuffle](#Shuffle)
- [SortByField](#SortByField) - [SortByField](#SortByField)
@@ -51,7 +52,7 @@ import (
- [StringSlice](#StringSlice) - [StringSlice](#StringSlice)
- [Unique](#Unique) - [Unique](#Unique)
- [Union](#Union) - [Union](#Union)
- [UpdateByIndex](#UpdateByIndex) - [UpdateAt](#UpdateAt)
- [Without](#Without) - [Without](#Without)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -64,14 +65,14 @@ import (
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Contain(iterableType interface{}, value interface{}) bool func Contain[T any](slice []T, value T) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -87,14 +88,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ContainSubSlice(slice interface{}, subslice interface{}) bool func ContainSubSlice[T any](slice, subslice []T) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -112,20 +113,20 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Chunk(slice []interface{}, size int) [][]interface{} func Chunk[T any](slice []T, size int) [][]T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/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) //[][]interface{}{{"a", "b", "c"}, {"d", "e"}} fmt.Println(res) //[][]any{{"a", "b", "c"}, {"d", "e"}}
} }
``` ```
@@ -137,14 +138,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Compact(slice interface{}) interface{} func Compact[T any](slice []T) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -160,14 +161,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Concat(slice interface{}, values ...interface{}) interface{} func Concat[T any](slice []T, values ...[]T) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -182,19 +183,19 @@ func main() {
### <span id="Count">Count</span> ### <span id="Count">Count</span>
<p>遍历切片对每个元素执行函数function. 返回符合函数返回值为true的元素的个数函数签名必须是func(index int, value interface{}) bool</p> <p>遍历切片对每个元素执行函数function. 返回符合函数返回值为true的元素的个数</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Count(slice, function interface{}) int func Count[T any](slice []T, predicate func(index int, t T) bool) int
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -217,14 +218,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Difference(slice1, slice2 interface{}) interface{} func Difference[T comparable](slice, comparedSlice []T) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -245,14 +246,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{} func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, t T) T) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -269,28 +270,56 @@ func main() {
### <span id="DifferenceWith">DifferenceWith</span>
### <span id="DeleteByIndex">DeleteByIndex</span> <p>DifferenceWith 接受比较器,该比较器被调用以将切片的元素与值进行比较。 结果值的顺序和引用由第一个切片确定</p>
<p>删除切片中从开始索引到结束索引-1的元素</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error) func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
res1 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 3) 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>
<b>函数签名:</b>
```go
func DeleteAt[T any](slice []T, start int, end ...int)
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
res1 := slice.DeleteAt([]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.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 0, 2) res2 := slice.DeleteAt([]string{"a", "b", "c", "d", "e"}, 0, 2)
fmt.Println(res2) //[]string{"c", "d", "e"} fmt.Println(res2) //[]string{"c", "d", "e"}
} }
@@ -305,14 +334,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Drop(slice interface{}, n int) interface{} func Drop[T any](slice []T, n int) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -331,19 +360,19 @@ func main() {
### <span id="Every">Every</span> ### <span id="Every">Every</span>
<p>如果切片中的所有值都通过谓词函数则返回true。 函数签名应该是func(index int, value interface{}) bool</p> <p>如果切片中的所有值都通过谓词函数则返回true。 函数签名应该是func(index int, value any) bool</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Every(slice, function interface{}) bool func Every[T any](slice []T, predicate func(index int, t T) bool) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -361,19 +390,19 @@ func main() {
### <span id="Filter">Filter</span> ### <span id="Filter">Filter</span>
<p>返回与函数匹配的所有元素。 函数签名应该是 func(index int, value interface{}) bool</p> <p>返回与函数匹配的所有元素。 函数签名应该是 func(index int, value any) bool</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Filter(slice, function interface{}) interface{} func Filter[T any](slice []T, predicate func(index int, t T) bool) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -390,19 +419,19 @@ func main() {
### <span id="Find">Find</span> ### <span id="Find">Find</span>
<p>遍历slice的元素返回第一个通过function真值测试的元素。函数签名应该是 func(index int, value interface{}) bool</p> <p>遍历slice的元素返回第一个通过function真值测试的元素</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Find(slice, function interface{}) (interface{}, bool) func Find[T any](slice []T, predicate func(index int, t T) bool) (*T, bool)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -421,19 +450,19 @@ func main() {
### <span id="FindLast">FindLast</span> ### <span id="FindLast">FindLast</span>
<p>从头到尾遍历 slice 的元素,返回最后一个通过函数真值测试的元素。 函数签名应该是 func(index int, value interface{}) bool。</p> <p>从头到尾遍历 slice 的元素,返回最后一个通过函数真值测试的元素。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func FindLast(slice, function interface{}) (interface{}, bool) func FindLast[T any](slice []T, predicate func(index int, t T) bool) (*T, bool)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -456,14 +485,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func FlattenDeep(slice interface{}) interface{} func FlattenDeep(slice any) any
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -478,19 +507,19 @@ func main() {
### <span id="ForEach">ForEach</span> ### <span id="ForEach">ForEach</span>
<p>遍历slice的元素并为每个元素调用函数函数签名应该是func(index int, value interface{})</p> <p>遍历slice的元素并为每个元素调用函数</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ForEach(slice, function interface{}) func ForEach[T any](slice []T, iteratee func(index int, t T))
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -507,19 +536,19 @@ func main() {
### <span id="GroupBy">GroupBy</span> ### <span id="GroupBy">GroupBy</span>
<p>迭代切片的元素,每个元素将按条件分组,返回两个切片。 函数签名应该是func(index int, value interface{}) bool</p> <p>迭代切片的元素,每个元素将按条件分组,返回两个切片</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func GroupBy(slice, function interface{}) (interface{}, interface{}) func GroupBy[T any](slice []T, groupFn func(index int, t T) bool) ([]T, []T)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -543,18 +572,18 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func IntSlice(slice interface{}) []int func IntSlice(slice any) []int
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
var nums = []interface{}{1, 2, 3} var nums = []any{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}
} }
@@ -569,20 +598,20 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func InterfaceSlice(slice interface{}) []interface{} func InterfaceSlice(slice any) []any
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/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) //[]interface{}{1, 2, 3} fmt.Println(res) //[]any{1, 2, 3}
} }
``` ```
@@ -595,14 +624,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Intersection(slices ...interface{}) interface{} func Intersection[T any](slices ...[]T) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -617,29 +646,29 @@ func main() {
### <span id="InsertByIndex">InsertByIndex</span> ### <span id="InsertAt">InsertAt</span>
<p>将元素插入到索引处的切片中</p> <p>将元素插入到索引处的切片中</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error) func InsertAt[T any](slice []T, index int, value any) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
s := []string{"a", "b", "c"} s := []string{"a", "b", "c"}
res1, _ := slice.InsertByIndex(s, 0, "1") res1, _ := slice.InsertAt(s, 0, "1")
fmt.Println(res1) //[]string{"1", "a", "b", "c"} fmt.Println(res1) //[]string{"1", "a", "b", "c"}
res2, _ := slice.InsertByIndex(s, 3, []string{"1", "2", "3"}) res2, _ := slice.InsertAt(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"}
} }
``` ```
@@ -648,19 +677,19 @@ func main() {
### <span id="Map">Map</span> ### <span id="Map">Map</span>
<p>通过运行函数slice中的每个元素来创建一个切片函数签名应该是func(index int, value interface{}) interface{}。</p> <p>通过运行函数slice中的每个元素来创建一个切片</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Map(slice, function interface{}) interface{} func Map[T any, U any](slice []T, iteratee func(index int, t T) U) []U
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -676,25 +705,25 @@ func main() {
### <span id="ReverseSlice">ReverseSlice</span> ### <span id="Reverse">Reverse</span>
<p>反转切片中的元素顺序</p> <p>反转切片中的元素顺序</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ReverseSlice(slice interface{}) func Reverse[T any](slice []T)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
nums := []int{1, 2, 3, 4} nums := []int{1, 2, 3, 4}
slice.ReverseSlice(nums) slice.Reverse(nums)
fmt.Println(res) //[]int{4, 3, 2, 1} fmt.Println(res) //[]int{4, 3, 2, 1}
} }
``` ```
@@ -702,19 +731,19 @@ func main() {
### <span id="Reduce">Reduce</span> ### <span id="Reduce">Reduce</span>
<p>将slice中的元素运行函数返回运行结果。函数签名应该是func(index int, value1, value2 interface{}) interface{}。</p> <p>将slice中的元素依次运行函数,返回运行结果</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Reduce(slice, function, zero interface{}) interface{} func Reduce[T any](slice []T, iteratee func(index int, t1, t2 T) T, initial T) T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -736,14 +765,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Shuffle(slice interface{}) interface{} func Shuffle[T any](slice []T) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -761,14 +790,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func SortByField(slice interface{}, field string, sortType ...string) error func SortByField(slice any, field string, sortType ...string) error
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -799,19 +828,19 @@ func main() {
### <span id="Some">Some</span> ### <span id="Some">Some</span>
<p>如果列表中的任何值通过谓词函数则返回true函数签名应该是func(index int, value interface{}) bool .</p> <p>如果列表中的任何值通过谓词函数则返回true</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Some(slice, function interface{}) bool func Some[T any](slice []T, predicate func(index int, t T) bool) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -833,18 +862,18 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func StringSlice(slice interface{}) []string func StringSlice(slice any) []string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
var s = []interface{}{"a", "b", "c"} var s = []any{"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"}
} }
@@ -859,14 +888,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Unique(slice interface{}) interface{} func Unique[T any](slice []T) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -883,14 +912,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Union(slices ...interface{}) interface{} func Union[T any](slices ...[]T) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
@@ -904,26 +933,26 @@ func main() {
### <span id="UpdateByIndex">UpdateByIndex</span> ### <span id="UpdateAt">UpdateAt</span>
<p>更新索引处的切片元素。 如果 param index < 0 或 index >= len(slice),将返回错误</p> <p>更新索引处的切片元素。 如果 param index < 0 或 index >= len(slice),将返回错误</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) func UpdateAt[T any](slice []T, index int, value T) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/slice"
) )
func main() { func main() {
s := []string{"a", "b", "c"} s := []string{"a", "b", "c"}
res1, _ := slice.UpdateByIndex(s, 0, "1") res1, _ := slice.UpdateAt(s, 0, "1")
fmt.Println(res1) //[]string{"1", "b", "c"} fmt.Println(res1) //[]string{"1", "b", "c"}
} }
``` ```
@@ -937,14 +966,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Without(slice interface{}, values ...interface{}) interface{} func Without[T any](slice []T, values ...T) []T
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/slice" "github.com/duke-git/lancet/v2/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/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/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/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
``` ```
@@ -57,7 +57,7 @@ func After(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -87,7 +87,7 @@ func AfterLast(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -118,7 +118,7 @@ func Before(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -149,7 +149,7 @@ func BeforeLast(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -180,7 +180,7 @@ func CamelCase(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -214,7 +214,7 @@ func Capitalize(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -237,14 +237,14 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func IsString(v interface{}) bool func IsString(v any) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -272,7 +272,7 @@ func KebabCase(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -306,7 +306,7 @@ func LowerFirst(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -340,7 +340,7 @@ func UpperFirst(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -374,7 +374,7 @@ func PadEnd(source string, size int, padStr string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -408,7 +408,7 @@ func PadStart(source string, size int, padStr string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -442,7 +442,7 @@ func ReverseStr(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -469,7 +469,7 @@ func SnakeCase(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -506,7 +506,7 @@ func Wrap(str string, wrapWith string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -543,7 +543,7 @@ func Unwrap(str string, wrapToken string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {

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/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/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/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
``` ```
@@ -58,7 +58,7 @@ func After(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -88,7 +88,7 @@ func AfterLast(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -119,7 +119,7 @@ func Before(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -150,7 +150,7 @@ func BeforeLast(s, char string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -181,7 +181,7 @@ func CamelCase(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -215,7 +215,7 @@ func Capitalize(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -238,14 +238,14 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func IsString(v interface{}) bool func IsString(v any) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -273,7 +273,7 @@ func KebabCase(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -307,7 +307,7 @@ func LowerFirst(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -341,7 +341,7 @@ func UpperFirst(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -375,7 +375,7 @@ func PadEnd(source string, size int, padStr string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -409,7 +409,7 @@ func PadStart(source string, size int, padStr string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -443,7 +443,7 @@ func ReverseStr(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -470,7 +470,7 @@ func SnakeCase(s string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -507,7 +507,7 @@ func Wrap(str string, wrapWith string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {
@@ -544,7 +544,7 @@ func Unwrap(str string, wrapToken string) string
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/strutil" "github.com/duke-git/lancet/v2/strutil"
) )
func main() { func main() {

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/main/system/os.go](https://github.com/duke-git/lancet/blob/main/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/system" "github.com/duke-git/lancet/v2/system"
) )
``` ```
@@ -48,7 +48,7 @@ func IsWindows() bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/v2/system"
) )
func main() { func main() {
@@ -73,7 +73,7 @@ func IsLinux() bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/v2/system"
) )
func main() { func main() {
@@ -97,7 +97,7 @@ func IsMac() bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/v2/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/system" "github.com/duke-git/lancet/v2/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/system" "github.com/duke-git/lancet/v2/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/system" "github.com/duke-git/lancet/v2/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/system" "github.com/duke-git/lancet/v2/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/system" "github.com/duke-git/lancet/v2/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/main/system/os.go](https://github.com/duke-git/lancet/blob/main/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/system" "github.com/duke-git/lancet/v2/system"
) )
``` ```
@@ -48,7 +48,7 @@ func IsWindows() bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/v2/system"
) )
func main() { func main() {
@@ -73,7 +73,7 @@ func IsLinux() bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/v2/system"
) )
func main() { func main() {
@@ -97,7 +97,7 @@ func IsMac() bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/v2/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/system" "github.com/duke-git/lancet/v2/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/system" "github.com/duke-git/lancet/v2/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/system" "github.com/duke-git/lancet/v2/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/system" "github.com/duke-git/lancet/v2/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/system" "github.com/duke-git/lancet/v2/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/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/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/validator" "github.com/duke-git/lancet/v2/validator"
) )
``` ```
@@ -67,7 +67,7 @@ func ContainChinese(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/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/validator" "github.com/duke-git/lancet/v2/validator"
) )
``` ```
@@ -67,7 +67,7 @@ func ContainChinese(s string) bool
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/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/validator" "github.com/duke-git/lancet/v2/validator"
) )
func main() { func main() {

57
docs/xerror.md Normal file
View File

@@ -0,0 +1,57 @@
# 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"))
}
```

57
docs/xerror_zh-CN.md Normal file
View File

@@ -0,0 +1,57 @@
# 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

@@ -263,7 +263,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 interface{}) string { func MiMeType(file any) 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/internal" "github.com/duke-git/lancet/v2/internal"
) )
func TestIsExist(t *testing.T) { func TestIsExist(t *testing.T) {

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 interface{}, symbol string) string { func Comma(v any, 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 interface{}) string { func numString(value any) 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/internal" "github.com/duke-git/lancet/v2/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 interface{}) func(args ...interface{}) []reflect.Value { func After(n int, fn any) func(args ...any) []reflect.Value {
// Catch programming error while constructing the closure // Catch programming error while constructing the closure
mustBeFunction(fn) mustBeFunction(fn)
return func(args ...interface{}) []reflect.Value { return func(args ...any) []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 interface{}) func(args ...interface{}) []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 interface{}) func(args ...interface{}) []reflect.Value { func Before(n int, fn any) func(args ...any) []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 ...interface{}) []reflect.Value { return func(args ...any) []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 interface{}) func(args ...interface{}) []reflect.Value {
} }
} }
// Fn is for curry function which is func(...interface{}) interface{} // Fn is for curry function which is func(...any) any
type Fn func(...interface{}) interface{} type Fn func(...any) any
// Curry make a curry function // Curry make a curry function
func (f Fn) Curry(i interface{}) func(...interface{}) interface{} { func (f Fn) Curry(i any) func(...any) any {
return func(values ...interface{}) interface{} { return func(values ...any) any {
v := append([]interface{}{i}, values...) v := append([]any{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(...interface{}) interface{}) func(...interface{}) interface{} { func Compose(fnList ...func(...any) any) func(...any) any {
return func(s ...interface{}) interface{} { return func(s ...any) any {
f := fnList[0] f := fnList[0]
restFn := fnList[1:] restFn := fnList[1:]
@@ -66,7 +66,7 @@ func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) in
} }
// Delay make the function execution after delayed time // Delay make the function execution after delayed time
func Delay(delay time.Duration, fn interface{}, args ...interface{}) { func Delay(delay time.Duration, fn any, args ...any) {
// 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 interface{}, args ...interface{}) chan bool { func Schedule(d time.Duration, fn any, args ...any) 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 interface{}, args ...interface{}) []reflect.Value { func invokeFunc(fn any, args ...any) []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 interface{}, args ...interface{}) []reflect.Value {
return fv.Call(params) return fv.Call(params)
} }
func unsafeInvokeFunc(fn interface{}, args ...interface{}) []reflect.Value { func unsafeInvokeFunc(fn any, args ...any) []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 interface{}, args ...interface{}) []reflect.Value {
return fv.Call(params) return fv.Call(params)
} }
func functionValue(function interface{}) reflect.Value { func functionValue(function any) 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 interface{}) reflect.Value {
return v return v
} }
func mustBeFunction(function interface{}) { func mustBeFunction(function any) {
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/internal" "github.com/duke-git/lancet/v2/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 ...interface{}) []reflect.Value type cb func(args ...any) []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 ...interface{}) []reflect.Value type cb func(args ...any) []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 ...interface{}) interface{} { var addCurry Fn = func(values ...any) any {
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 ...interface{}) interface{} { toUpper := func(a ...any) any {
return strings.ToUpper(a[0].(string)) return strings.ToUpper(a[0].(string))
} }
toLower := func(a ...interface{}) interface{} { toLower := func(a ...any) any {
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/internal" "github.com/duke-git/lancet/v2/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 module github.com/duke-git/lancet/v2
go 1.16 go 1.18

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 interface{}) { func (a *Assert) Equal(expected, actual any) {
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 interface{}) { func (a *Assert) NotEqual(expected, actual any) {
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 interface{}) {
} }
// Greater check if expected is greate than actual // Greater check if expected is greate than actual
func (a *Assert) Greater(expected, actual interface{}) { func (a *Assert) Greater(expected, actual any) {
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 interface{}) {
} }
// 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 interface{}) { func (a *Assert) GreaterOrEqual(expected, actual any) {
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 interface{}) {
} }
// Less check if expected is less than actual // Less check if expected is less than actual
func (a *Assert) Less(expected, actual interface{}) { func (a *Assert) Less(expected, actual any) {
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 interface{}) {
} }
// 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 interface{}) { func (a *Assert) LessOrEqual(expected, actual any) {
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 interface{}) {
} }
// IsNil check if value is nil // IsNil check if value is nil
func (a *Assert) IsNil(value interface{}) { func (a *Assert) IsNil(value any) {
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 interface{}) { func (a *Assert) IsNotNil(value any) {
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 interface{}) {
// 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 interface{}) int { func compare(x, y any) 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 interface{}) 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 interface{}) { func makeTestFailed(t *testing.T, caseName string, expected, actual any) {
_, 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

@@ -0,0 +1,13 @@
// 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
}

View File

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

View File

@@ -6,7 +6,7 @@
// 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]interface{}, // params[1] is query param which type should be url.Values or map[string]any,
// 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 +21,32 @@ import (
) )
//HttpGet send get http request //HttpGet send get http request
func HttpGet(url string, params ...interface{}) (*http.Response, error) { func HttpGet(url string, params ...any) (*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 ...interface{}) (*http.Response, error) { func HttpPost(url string, params ...any) (*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 ...interface{}) (*http.Response, error) { func HttpPut(url string, params ...any) (*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 ...interface{}) (*http.Response, error) { func HttpDelete(url string, params ...any) (*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 ...interface{}) (*http.Response, error) { func HttpPatch(url string, params ...any) (*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 interface{}) error { func ParseHttpResponse(resp *http.Response, obj any) error {
if resp == nil { if resp == nil {
return errors.New("InvalidResp") return errors.New("InvalidResp")
} }
@@ -55,7 +55,7 @@ func ParseHttpResponse(resp *http.Response, obj interface{}) error {
} }
// ConvertMapToQueryString convert map to sorted url query string // ConvertMapToQueryString convert map to sorted url query string
func ConvertMapToQueryString(param map[string]interface{}) string { func ConvertMapToQueryString(param map[string]any) string {
if param == nil { if param == nil {
return "" return ""
} }

View File

@@ -6,7 +6,7 @@ import (
"log" "log"
"testing" "testing"
"github.com/duke-git/lancet/internal" "github.com/duke-git/lancet/v2/internal"
) )
func TestHttpGet(t *testing.T) { func TestHttpGet(t *testing.T) {
@@ -104,7 +104,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]interface{}{ var m = map[string]any{
"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 ...interface{}) (*http.Response, error) { func doHttpRequest(method, reqUrl string, params ...any) (*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")
} }
@@ -60,7 +60,7 @@ func doHttpRequest(method, reqUrl string, params ...interface{}) (*http.Response
return resp, e return resp, e
} }
func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam interface{}) error { func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam any) error {
err := setHeader(req, header) err := setHeader(req, header)
if err != nil { if err != nil {
return err return err
@@ -72,7 +72,7 @@ func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam
return nil return nil
} }
func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryParam, body interface{}) error { func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryParam, body any) error {
err := setHeader(req, header) err := setHeader(req, header)
if err != nil { if err != nil {
return err return err
@@ -88,7 +88,7 @@ func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryPar
return nil return nil
} }
func setHeader(req *http.Request, header interface{}) error { func setHeader(req *http.Request, header any) 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 +122,11 @@ func setUrl(req *http.Request, reqUrl string) error {
return nil return nil
} }
func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) error { func setQueryParam(req *http.Request, reqUrl string, queryParam any) 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]interface{}: case map[string]any:
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 +134,7 @@ func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) err
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]interface{}") return errors.New("query params type should be url.Values or map[string]any")
} }
} }
@@ -155,7 +155,7 @@ func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) err
return nil return nil
} }
func setBodyByte(req *http.Request, body interface{}) error { func setBodyByte(req *http.Request, body any) error {
if body != nil { if body != nil {
switch b := body.(type) { switch b := body.(type) {
case []byte: case []byte:
@@ -168,7 +168,7 @@ func setBodyByte(req *http.Request, body interface{}) error {
return nil return nil
} }
func getClient(client interface{}) (*http.Client, error) { func getClient(client any) (*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/internal" "github.com/duke-git/lancet/v2/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/internal" "github.com/duke-git/lancet/v2/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/internal" "github.com/duke-git/lancet/v2/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 interface{}) reflect.Value { func sliceValue(slice any) 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 interface{}) reflect.Value {
} }
// functionValue return the reflect value of a function // functionValue return the reflect value of a function
func functionValue(function interface{}) reflect.Value { func functionValue(function any) 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,9 @@
package slice package slice
import ( import (
"reflect"
"testing" "testing"
"github.com/duke-git/lancet/internal" "github.com/duke-git/lancet/v2/internal"
) )
func TestContain(t *testing.T) { func TestContain(t *testing.T) {
@@ -15,41 +14,36 @@ 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{}, ""))
var m = map[string]int{"a": 1} assert.Equal(true, Contain([]int{1, 2, 3}, 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(true, ContainSubSlice([]int{1, 2, 3}, []int{1})) assert.Equal(false, ContainSubSlice([]int{1, 2, 3}, []int{0, 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))
r2 := [][]interface{}{{"a", "b"}, {"c", "d"}, {"e"}} r1 := [][]string{{"a"}, {"b"}, {"c"}, {"d"}, {"e"}}
assert.Equal(r2, Chunk(InterfaceSlice(arr), 2)) assert.Equal(r1, Chunk(arr, 1))
r3 := [][]interface{}{{"a", "b", "c"}, {"d", "e"}} r2 := [][]string{{"a", "b"}, {"c", "d"}, {"e"}}
assert.Equal(r3, Chunk(InterfaceSlice(arr), 3)) assert.Equal(r2, Chunk(arr, 2))
r4 := [][]interface{}{{"a", "b", "c", "d"}, {"e"}} r3 := [][]string{{"a", "b", "c"}, {"d", "e"}}
assert.Equal(r4, Chunk(InterfaceSlice(arr), 4)) assert.Equal(r3, Chunk(arr, 3))
r5 := [][]interface{}{{"a"}, {"b"}, {"c"}, {"d"}, {"e"}} r4 := [][]string{{"a", "b", "c", "d"}, {"e"}}
assert.Equal(r5, Chunk(InterfaceSlice(arr), 5)) assert.Equal(r4, Chunk(arr, 4))
r5 := [][]string{{"a"}, {"b"}, {"c"}, {"d"}, {"e"}}
assert.Equal(r5, Chunk(arr, 5))
} }
func TestCompact(t *testing.T) { func TestCompact(t *testing.T) {
@@ -66,11 +60,11 @@ 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 TestEvery(t *testing.T) { func TestEvery(t *testing.T) {
@@ -169,7 +163,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) {
@@ -183,7 +177,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) {
@@ -212,9 +206,11 @@ 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
ForEach(numbers, func(index int, value int) { addTwo := 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)
@@ -272,7 +268,7 @@ func TestReduce(t *testing.T) {
} }
func TestIntSlice(t *testing.T) { func TestIntSlice(t *testing.T) {
var nums []interface{} var nums []any
nums = append(nums, 1, 2, 3) nums = append(nums, 1, 2, 3)
assert := internal.NewAssert(t, "TestIntSlice") assert := internal.NewAssert(t, "TestIntSlice")
@@ -280,7 +276,7 @@ func TestIntSlice(t *testing.T) {
} }
func TestStringSlice(t *testing.T) { func TestStringSlice(t *testing.T) {
var strs []interface{} var strs []any
strs = append(strs, "a", "b", "c") strs = append(strs, "a", "b", "c")
assert := internal.NewAssert(t, "TestStringSlice") assert := internal.NewAssert(t, "TestStringSlice")
@@ -289,41 +285,27 @@ 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 := []interface{}{"a", "b", "c"} expect := []any{"a", "b", "c"}
assert := internal.NewAssert(t, "TestInterfaceSlice") assert := internal.NewAssert(t, "TestInterfaceSlice")
assert.Equal(expect, InterfaceSlice(strs)) assert.Equal(expect, InterfaceSlice(strs))
} }
func TestDeleteByIndex(t *testing.T) { func TestDeleteAt(t *testing.T) {
assert := internal.NewAssert(t, "TestDeleteByIndex") assert := internal.NewAssert(t, "TestDeleteAt")
t1 := []string{"a", "b", "c", "d", "e"} assert.Equal([]string{"a", "b", "c"}, DeleteAt([]string{"a", "b", "c"}, -1))
r1 := []string{"b", "c", "d", "e"} assert.Equal([]string{"a", "b", "c"}, DeleteAt([]string{"a", "b", "c"}, 3))
a1, _ := DeleteByIndex(t1, 0) assert.Equal([]string{"b", "c"}, DeleteAt([]string{"a", "b", "c"}, 0))
assert.Equal(r1, a1) assert.Equal([]string{"a", "c"}, DeleteAt([]string{"a", "b", "c"}, 1))
assert.Equal([]string{"a", "b"}, DeleteAt([]string{"a", "b", "c"}, 2))
t2 := []string{"a", "b", "c", "d", "e"} assert.Equal([]string{"b", "c"}, DeleteAt([]string{"a", "b", "c"}, 0, 1))
r2 := []string{"a", "b", "c", "e"} assert.Equal([]string{"c"}, DeleteAt([]string{"a", "b", "c"}, 0, 2))
a2, _ := DeleteByIndex(t2, 3) assert.Equal([]string{}, DeleteAt([]string{"a", "b", "c"}, 0, 3))
assert.Equal(r2, a2) assert.Equal([]string{}, DeleteAt([]string{"a", "b", "c"}, 0, 4))
assert.Equal([]string{"a"}, DeleteAt([]string{"a", "b", "c"}, 1, 3))
t3 := []string{"a", "b", "c", "d", "e"} assert.Equal([]string{"a"}, DeleteAt([]string{"a", "b", "c"}, 1, 4))
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) {
@@ -343,48 +325,28 @@ 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 TestInsertByIndex(t *testing.T) { func TestInsertAt(t *testing.T) {
assert := internal.NewAssert(t, "TestInsertByIndex") assert := internal.NewAssert(t, "TestInsertAt")
t1 := []string{"a", "b", "c"} strs := []string{"a", "b", "c"}
r1, _ := InsertByIndex(t1, 0, "1") assert.Equal([]string{"a", "b", "c"}, InsertAt(strs, -1, "1"))
assert.Equal([]string{"1", "a", "b", "c"}, r1) assert.Equal([]string{"a", "b", "c"}, InsertAt(strs, 4, "1"))
assert.Equal([]string{"1", "a", "b", "c"}, InsertAt(strs, 0, "1"))
r2, _ := InsertByIndex(t1, 1, "1") assert.Equal([]string{"a", "1", "b", "c"}, InsertAt(strs, 1, "1"))
assert.Equal([]string{"a", "1", "b", "c"}, r2) assert.Equal([]string{"a", "b", "1", "c"}, InsertAt(strs, 2, "1"))
assert.Equal([]string{"a", "b", "c", "1"}, InsertAt(strs, 3, "1"))
r3, _ := InsertByIndex(t1, 3, "1") assert.Equal([]string{"1", "2", "3", "a", "b", "c"}, InsertAt(strs, 0, []string{"1", "2", "3"}))
assert.Equal([]string{"a", "b", "c", "1"}, r3) assert.Equal([]string{"a", "b", "c", "1", "2", "3"}, InsertAt(strs, 3, []string{"1", "2", "3"}))
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 TestUpdateByIndex(t *testing.T) { func TestUpdateAt(t *testing.T) {
assert := internal.NewAssert(t, "TestUpdateByIndex") assert := internal.NewAssert(t, "TestUpdateAt")
t1 := []string{"a", "b", "c"} assert.Equal([]string{"a", "b", "c"}, UpdateAt([]string{"a", "b", "c"}, -1, "1"))
r1, _ := UpdateByIndex(t1, 0, "1") assert.Equal([]string{"1", "b", "c"}, UpdateAt([]string{"a", "b", "c"}, 0, "1"))
assert.Equal([]string{"1", "b", "c"}, r1) assert.Equal([]string{"a", "b", "2"}, UpdateAt([]string{"a", "b", "c"}, 2, "2"))
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) {
@@ -418,7 +380,7 @@ func TestIntersection(t *testing.T) {
{1, 2, 3}, {1, 2, 3},
{}, {},
} }
res := []interface{}{ res := []any{
Intersection(s1, s2, s3), Intersection(s1, s2, s3),
Intersection(s1, s2), Intersection(s1, s2),
Intersection(s1), Intersection(s1),
@@ -428,20 +390,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(res[i], expected[i]) assert.Equal(expected[i], res[i])
} }
assert.IsNil(Intersection()) // assert.IsNil(Intersection())
} }
func TestReverseSlice(t *testing.T) { func TestReverse(t *testing.T) {
assert := internal.NewAssert(t, "TestIntersection") assert := internal.NewAssert(t, "TestReverse")
s1 := []int{1, 2, 3, 4, 5} s1 := []int{1, 2, 3, 4, 5}
ReverseSlice(s1) Reverse(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"}
ReverseSlice(s2) Reverse(s2)
assert.Equal([]string{"e", "d", "c", "b", "a"}, s2) assert.Equal([]string{"e", "d", "c", "b", "a"}, s2)
} }
@@ -453,6 +415,17 @@ 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")
@@ -529,17 +502,5 @@ func TestShuffle(t *testing.T) {
res := Shuffle(s) res := Shuffle(s)
t.Log("Shuffle result: ", res) t.Log("Shuffle result: ", res)
assert.Equal(reflect.TypeOf(s), reflect.TypeOf(res)) assert.Equal(5, len(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))
} }

View File

@@ -1,4 +1,3 @@
// 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.
@@ -197,7 +196,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 interface{}) bool { func IsString(v any) bool {
if v == nil { if v == nil {
return false return false
} }

View File

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

View File

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

View File

@@ -234,11 +234,6 @@ func IsStrongPassword(password string, length int) bool {
} }
return num && lower && upper && special return num && lower && upper && special
// go doesn't support regexp (?=re)
//pattern := `^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[@#$%^&+=])(?=\S+$).$`
//reg := regexp.MustCompile(pattern)
//return reg.MatchString(password)
} }
// IsWeakPassword check if the string is weak password // IsWeakPassword check if the string is weak password

View File

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

14
xerror/xerror.go Normal file
View File

@@ -0,0 +1,14 @@
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
// Use of this source code is governed by MIT license
// Package xerror implements helpers for errors
package xerror
// Unwrap if err is nil then it returns a valid value
// If err is not nil, Unwrap panics with err.
func Unwrap[T any](val T, err error) T {
if err != nil {
panic(err)
}
return val
}

25
xerror/xerror_test.go Normal file
View File

@@ -0,0 +1,25 @@
package xerror
import (
"strconv"
"testing"
"github.com/duke-git/lancet/v2/internal"
)
func TestUnwrap(t *testing.T) {
assert := internal.NewAssert(t, "TestUnwrap")
assert.Equal(42, Unwrap(strconv.Atoi("42")))
}
func TestUnwrapFail(t *testing.T) {
assert := internal.NewAssert(t, "TestUnwrapFail")
_, err := strconv.Atoi("4o2")
defer func() {
v := recover()
assert.Equal(err.Error(), v.(*strconv.NumError).Error())
}()
Unwrap(strconv.Atoi("4o2"))
}