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

Compare commits

...

55 Commits

Author SHA1 Message Date
dudaodong
acf028cdcd release v2.1.0 2022-06-22 16:10:54 +08:00
dudaodong
31e43ec356 docs: add doc for UniqueBy function 2022-06-22 16:08:37 +08:00
dudaodong
9f45e68fef test: add fuzz test for Equal function 2022-06-21 14:17:33 +08:00
dudaodong
d2df99a6f0 feat: add UniqueBy function in slice.go 2022-06-17 15:18:04 +08:00
dudaodong
713c341831 docs: update comment for Size function of ArrayQueue 2022-06-16 18:03:50 +08:00
dudaodong
0b05a6dd6f release: v2.0.9 2022-06-15 15:27:01 +08:00
dudaodong
d21c101caf refactor: change function name EqualWithFunc to EqualWith 2022-06-15 15:25:44 +08:00
dudaodong
bf49db60d9 docs: change function name EqualWithFunc to EqualWith 2022-06-15 15:24:58 +08:00
dudaodong
d57fa3b603 docs: update readme file add new functions 2022-06-15 15:23:30 +08:00
dudaodong
b3a29ce82d docs: add doc for function Equal and EqualWithFunc 2022-06-13 15:14:37 +08:00
dudaodong
1d8a37d6e8 docs: add doc for function CreateDir 2022-06-13 15:00:12 +08:00
dudaodong
ef2d8e14b0 feat: add EqualWithFunc function for slice 2022-06-13 14:15:32 +08:00
dudaodong
0cbb3dd97e feat: add Equal function for slice 2022-06-13 14:06:20 +08:00
dudaodong
38a7f9423f fmt: gofmt package datastructure/queue 2022-06-08 14:40:37 +08:00
dudaodong
2c0ab9e922 feat: add CreateDir function in file.go 2022-06-08 14:38:35 +08:00
dudaodong
9aa3b742ff docs: add doc for package datastructure 2022-06-07 14:54:23 +08:00
dudaodong
6bfaba750d docs: add doc tree-zh-CN.md 2022-06-07 14:39:32 +08:00
dudaodong
69f8bee935 docs: add doc tree datastructure 2022-06-07 14:17:34 +08:00
dudaodong
07d04a9cd0 refactor: change function name 2022-06-07 13:48:32 +08:00
dudaodong
6f17ba9116 docs: add doc set_zh-CN.md 2022-06-06 11:20:55 +08:00
dudaodong
56d1e5e95c docs: fix code format 2022-06-06 11:12:53 +08:00
dudaodong
11d86d0270 docs: add doc for Set datastructer 2022-06-06 11:07:43 +08:00
dudaodong
d1c20a1da8 fix: fix function comment 2022-06-06 11:07:13 +08:00
dudaodong
f87ab89207 docs: fix misspell in doc queue.md 2022-06-06 10:34:18 +08:00
dudaodong
9ebb0c7920 docs: add doc queue_zh-CN.md 2022-06-06 10:30:26 +08:00
dudaodong
31a5ed11a3 docs: add doc for PriorityQueue 2022-06-05 17:32:37 +08:00
dudaodong
a706d488e6 feat: add Size func for PriorityQueue 2022-06-05 17:29:36 +08:00
dudaodong
61251fb0f1 refactor: change func Length to Size in CircularQueue 2022-06-05 16:57:03 +08:00
dudaodong
747dc30b02 refactor: Change param __TEXT __DATA __OBJC others dec hex to in NewCircularQueue function 2022-06-05 16:49:30 +08:00
dudaodong
d54f27d9a9 docs: add IsFull function for ArrayQueue 2022-06-05 16:46:01 +08:00
dudaodong
dbca2f6be4 feat: add IsFull function for ArrayQueue 2022-06-05 16:43:15 +08:00
dudaodong
2ef9b56d22 feat: add Contain function for LinkedQueue 2022-06-05 16:41:16 +08:00
dudaodong
52ecde7e24 docs: add doc for LinkedQueue 2022-06-05 16:36:56 +08:00
dudaodong
a7dce5e4d3 docs: add doc for LinkedQueue 2022-06-04 18:57:43 +08:00
dudaodong
4718da44f4 refactor: rename function 'EnQueue' -> 'Enqueue', 'DeQueue' -> 'Dequeue' 2022-06-04 18:53:46 +08:00
dudaodong
1aa1f95524 docs: add doc for queue 2022-06-04 18:49:24 +08:00
dudaodong
d922b2e778 docs: fix code format 2022-06-04 11:26:39 +08:00
dudaodong
5a7b3c4a37 docs: add stack_zh-CN.md doc 2022-06-03 19:20:14 +08:00
dudaodong
1c2b1a2f02 docs: update Peak function comment 2022-06-02 22:26:26 +08:00
dudaodong
c68440ecf8 docs: add docs for stack 2022-06-02 22:25:11 +08:00
dudaodong
6a48b3f99e docs: add docs for linklist 2022-06-01 20:48:30 +08:00
dudaodong
bab9ae32d4 docs: add docs for package datastructure DoublyLink 2022-06-01 20:30:30 +08:00
dudaodong
f0e6e94c5e fix: fix incorrect comment for DoublyLink Clear function 2022-06-01 20:16:34 +08:00
dudaodong
a6fe155781 docs: fix code format 2022-05-31 21:47:56 +08:00
dudaodong
d5be9009fc docs: update list doc 2022-05-31 21:43:26 +08:00
dudaodong
ca47be41f6 fix: fix incorrect comment for SinglyLink Clear function 2022-05-31 21:42:31 +08:00
dudaodong
ff5db30208 docs: add docs for package datastructure SinglyLink 2022-05-31 21:41:25 +08:00
dudaodong
a429d46072 docs: add list_zh-CN.md 2022-05-30 21:09:21 +08:00
dudaodong
7b84fbfd94 fix: fix misspellings -> 2022-05-30 20:54:34 +08:00
dudaodong
fc6f618885 docs: add docs for package datastructure list 2022-05-30 20:53:11 +08:00
dudaodong
7f03c3b0a2 docs: update algorithm package doc 2022-05-30 17:53:21 +08:00
dudaodong
4b4386bd47 Merge branch 'v2' of github.com:duke-git/lancet into v2 2022-05-28 10:54:55 +08:00
dudaodong
10a1706613 docs: update function comments 2022-05-28 10:51:15 +08:00
dudaodong
d097f356fd docs: change some function comments for slice doc 2022-05-21 17:00:28 +08:00
dudaodong
bc9bacaa55 refactor: change param to item 2022-05-21 16:50:57 +08:00
41 changed files with 10206 additions and 271 deletions

1
.gitignore vendored
View File

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

View File

@@ -4,7 +4,7 @@
<br/>
![Go version](https://img.shields.io/badge/go-%3E%3D1.16<recommend>-9cf)
[![Release](https://img.shields.io/badge/release-2.0.7-green.svg)](https://github.com/duke-git/lancet/releases)
[![Release](https://img.shields.io/badge/release-2.1.0-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2)
[![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)
@@ -35,9 +35,9 @@ English | [简体中文](./README_zh-CN.md)
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.9. </b>
2. <b>For users who use version below go1.18, you should install v1.x.x. now latest v1 is v1.3.0. </b>
```go
go get github.com/duke-git/lancet@v1.2.9 // below go1.18, install latest version of v1.x.x
go get github.com/duke-git/lancet@v1.3.0 // below go1.18, install latest version of v1.x.x
```
## Usage
@@ -201,7 +201,29 @@ import "github.com/duke-git/lancet/v2/datetime"
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToFormatForTpl)
- [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToIso8601)
### 6. Fileutil package implements some basic functions for file operations.
### 6. Datastructure package constains some common data structure. eg. list, linklist, stack, queue, set, tree, graph.
```go
import list "github.com/duke-git/lancet/v2/datastructure/list"
import link "github.com/duke-git/lancet/v2/datastructure/link"
import stack "github.com/duke-git/lancet/v2/datastructure/stack"
import queue "github.com/duke-git/lancet/v2/datastructure/queue"
import set "github.com/duke-git/lancet/v2/datastructure/set"
import tree "github.com/duke-git/lancet/v2/datastructure/tree"
```
#### Function list:
- [List](https://github.com/duke-git/lancet/blob/main/docs/datastructure/list.md)
- [Linklist](https://github.com/duke-git/lancet/blob/main/docs/datastructure/linklist.md)
- [Stack](https://github.com/duke-git/lancet/blob/main/docs/datastructure/stack.md)
- [Queue](https://github.com/duke-git/lancet/blob/main/docs/datastructure/queue.md)
- [Set](https://github.com/duke-git/lancet/blob/main/docs/datastructure/set.md)
- [Tree](https://github.com/duke-git/lancet/blob/main/docs/datastructure/tree.md)
### 7. Fileutil package implements some basic functions for file operations.
```go
import "github.com/duke-git/lancet/v2/fileutil"
@@ -211,6 +233,7 @@ import "github.com/duke-git/lancet/v2/fileutil"
- [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ClearFile)
- [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CreateFile)
- [CreateDir](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CreateDir)
- [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CopyFile)
- [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#FileMode)
- [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#MiMeType)
@@ -224,7 +247,7 @@ import "github.com/duke-git/lancet/v2/fileutil"
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#Zip)
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#UnZip)
### 7. Formatter contains some functions for data formatting.
### 8. Formatter contains some functions for data formatting.
```go
import "github.com/duke-git/lancet/v2/formatter"
@@ -232,7 +255,7 @@ import "github.com/duke-git/lancet/v2/formatter"
#### Function list:
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#Comma)
### 8. Function package can control the flow of function execution and support part of functional programming
### 9. Function package can control the flow of function execution and support part of functional programming
```go
import "github.com/duke-git/lancet/v2/function"
@@ -248,7 +271,7 @@ import "github.com/duke-git/lancet/v2/function"
- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function.md#Watcher)
### 9. Maputil package includes some functions to manipulate map.
### 10. Maputil package includes some functions to manipulate map.
```go
import "github.com/duke-git/lancet/v2/maputil"
@@ -264,7 +287,7 @@ import "github.com/duke-git/lancet/v2/maputil"
- [Values](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Values)
### 10. Mathutil package implements some functions for math calculation.
### 11. Mathutil package implements some functions for math calculation.
```go
import "github.com/duke-git/lancet/v2/mathutil"
@@ -285,7 +308,7 @@ import "github.com/duke-git/lancet/v2/mathutil"
- [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#TruncRound)
### 11. Netutil package contains functions to get net information and send http request.
### 12. Netutil package contains functions to get net information and send http request.
```go
import "github.com/duke-git/lancet/v2/netutil"
@@ -305,7 +328,7 @@ import "github.com/duke-git/lancet/v2/netutil"
- [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPatch)
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ParseHttpResponse)
### 12. Random package implements some basic functions to generate random int and string.
### 13. Random package implements some basic functions to generate random int and string.
```go
import "github.com/duke-git/lancet/v2/random"
@@ -317,7 +340,7 @@ import "github.com/duke-git/lancet/v2/random"
- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandString)
- [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4)
### 13. Retry package is for executing a function repeatedly until it was successful or canceled by the context.
### 14. Retry package is for executing a function repeatedly until it was successful or canceled by the context.
```go
import "github.com/duke-git/lancet/v2/retry"
@@ -330,7 +353,7 @@ import "github.com/duke-git/lancet/v2/retry"
- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryDuration)
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryTimes)
### 14. Slice contains some functions to manipulate slice.
### 15. Slice contains some functions to manipulate slice.
```go
import "github.com/duke-git/lancet/v2/slice"
@@ -348,6 +371,8 @@ import "github.com/duke-git/lancet/v2/slice"
- [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)
- [Equal](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Equal)
- [EqualWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#EqualWith)
- [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)
- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Find)
@@ -371,11 +396,12 @@ import "github.com/duke-git/lancet/v2/slice"
- [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#StringSlice)
- [SymmetricDifference](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SymmetricDifference)
- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Unique)
- [UniqueBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UniqueBy)
- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Union)
- [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)
### 15. Strutil package contains some functions to manipulate string.
### 16. Strutil package contains some functions to manipulate string.
```go
import "github.com/duke-git/lancet/v2/strutil"
```
@@ -400,7 +426,7 @@ import "github.com/duke-git/lancet/v2/strutil"
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Wrap)
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Unwrap)
### 16. System package contain some functions about os, runtime, shell command.
### 17. System package contain some functions about os, runtime, shell command.
```go
import "github.com/duke-git/lancet/v2/system"
@@ -415,7 +441,7 @@ import "github.com/duke-git/lancet/v2/system"
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#CompareOsEnv)
- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system.md#ExecCommand)
### 17. Validator package contains some functions for data validation.
### 18. Validator package contains some functions for data validation.
```go
import "github.com/duke-git/lancet/v2/validator"
@@ -449,7 +475,7 @@ import "github.com/duke-git/lancet/v2/validator"
- [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)
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsWeakPassword)
### 18. xerror package implements helpers for errors.
### 19. xerror package implements helpers for errors.
```go
import "github.com/duke-git/lancet/v2/xerror"

View File

@@ -4,7 +4,7 @@
<br/>
![Go version](https://img.shields.io/badge/go-%3E%3D1.16<recommend>-9cf)
[![Release](https://img.shields.io/badge/release-2.0.7-green.svg)](https://github.com/duke-git/lancet/releases)
[![Release](https://img.shields.io/badge/release-2.1.0-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2)
[![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)
@@ -35,9 +35,9 @@
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
```
2. <b>使用go1.18以下版本的用户必须安装v1.x.x。目前最新的v1版本是v1.2.9。</b>
2. <b>使用go1.18以下版本的用户必须安装v1.x.x。目前最新的v1版本是v1.3.0。</b>
```go
go get github.com/duke-git/lancet@v1.2.9 // 使用go1.18以下版本, 必须安装v1.x.x版本
go get github.com/duke-git/lancet@v1.3.0 // 使用go1.18以下版本, 必须安装v1.x.x版本
```
## 用法
@@ -200,7 +200,28 @@ import "github.com/duke-git/lancet/v2/datetime"
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormatForTpl)
- [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToIso8601)
### 6. fileutil包支持文件基本操作。
### 6. datastructure包含一些普通的数据结构实现。例如list, linklist, stack, queue, set, tree, graph.
```go
import list "github.com/duke-git/lancet/v2/datastructure/list"
import link "github.com/duke-git/lancet/v2/datastructure/link"
import stack "github.com/duke-git/lancet/v2/datastructure/stack"
import queue "github.com/duke-git/lancet/v2/datastructure/queue"
import set "github.com/duke-git/lancet/v2/datastructure/set"
import tree "github.com/duke-git/lancet/v2/datastructure/tree"
```
#### Function list:
- [List](https://github.com/duke-git/lancet/blob/main/docs/datastructure/list_zh-CN.md)
- [Linklist](https://github.com/duke-git/lancet/blob/main/docs/datastructure/linklist_zh-CN.md)
- [Stack](https://github.com/duke-git/lancet/blob/main/docs/datastructure/stack_zh-CN.md)
- [Queue](https://github.com/duke-git/lancet/blob/main/docs/datastructure/queue_zh-CN.md)
- [Set](https://github.com/duke-git/lancet/blob/main/docs/datastructure/set_zh-CN.md)
- [Tree](https://github.com/duke-git/lancet/blob/main/docs/datastructure/tree_zh-CN.md)
### 7. fileutil包支持文件基本操作。
```go
import "github.com/duke-git/lancet/v2/fileutil"
@@ -210,6 +231,7 @@ import "github.com/duke-git/lancet/v2/fileutil"
- [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ClearFile)
- [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CreateFile)
- [CreateDir](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CreateDir)
- [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CopyFile)
- [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#FileMode)
- [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#MiMeType)
@@ -223,7 +245,7 @@ import "github.com/duke-git/lancet/v2/fileutil"
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#Zip)
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#UnZip)
### 7. formatter格式化器包含一些数据格式化处理方法。
### 8. formatter格式化器包含一些数据格式化处理方法。
```go
import "github.com/duke-git/lancet/v2/formatter"
@@ -232,7 +254,7 @@ import "github.com/duke-git/lancet/v2/formatter"
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#Comma)
### 8. function函数包控制函数执行流程包含部分函数式编程。
### 9. function函数包控制函数执行流程包含部分函数式编程。
```go
import "github.com/duke-git/lancet/v2/function"
@@ -248,7 +270,7 @@ import "github.com/duke-git/lancet/v2/function"
- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Watcher)
### 9. maputil包包括一些操作map的函数.
### 10. maputil包包括一些操作map的函数.
```go
import "github.com/duke-git/lancet/v2/maputil"
@@ -263,7 +285,7 @@ import "github.com/duke-git/lancet/v2/maputil"
- [Minus](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Minus)
- [Values](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Values)
### 10. mathutil包实现了一些数学计算的函数。
### 11. mathutil包实现了一些数学计算的函数。
```go
import "github.com/duke-git/lancet/v2/mathutil"
@@ -283,7 +305,7 @@ import "github.com/duke-git/lancet/v2/mathutil"
- [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToString)
- [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#TruncRound)
### 11. netutil网络包支持获取ip地址发送http请求。
### 12. netutil网络包支持获取ip地址发送http请求。
```go
import "github.com/duke-git/lancet/v2/netutil"
@@ -303,7 +325,7 @@ import "github.com/duke-git/lancet/v2/netutil"
- [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPatch)
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ParseHttpResponse)
### 12. random随机数生成器包可以生成随机[]bytes, int, string。
### 13. random随机数生成器包可以生成随机[]bytes, int, string。
```go
import "github.com/duke-git/lancet/v2/random"
@@ -314,7 +336,7 @@ import "github.com/duke-git/lancet/v2/random"
- [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandInt)
- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandString)
- [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4)
### 13. retry重试执行函数直到函数运行成功或被context cancel。
### 14. retry重试执行函数直到函数运行成功或被context cancel。
```go
import "github.com/duke-git/lancet/v2/retry"
@@ -328,7 +350,7 @@ import "github.com/duke-git/lancet/v2/retry"
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryTimes)
### 14. slice包包含操作切片的方法集合。
### 15. slice包包含操作切片的方法集合。
```go
import "github.com/duke-git/lancet/v2/slice"
@@ -369,12 +391,13 @@ import "github.com/duke-git/lancet/v2/slice"
- [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#StringSlice)
- [SymmetricDifference](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SymmetricDifference)
- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Unique)
- [UniqueBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UniqueBy)
- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Union)
- [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)
### 15. strutil包含处理字符串的相关函数。
### 16. strutil包含处理字符串的相关函数。
```go
import "github.com/duke-git/lancet/v2/strutil"
@@ -401,7 +424,7 @@ import "github.com/duke-git/lancet/v2/strutil"
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Unwrap)
### 16. system包含os, runtime, shell command相关函数。
### 17. system包含os, runtime, shell command相关函数。
```go
import "github.com/duke-git/lancet/v2/system"
@@ -417,7 +440,7 @@ import "github.com/duke-git/lancet/v2/system"
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#CompareOsEnv)
- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#ExecCommand)
### 17. validator验证器包包含常用字符串格式验证函数。
### 18. validator验证器包包含常用字符串格式验证函数。
```go
import "github.com/duke-git/lancet/v2/validator"
@@ -452,7 +475,7 @@ import "github.com/duke-git/lancet/v2/validator"
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsWeakPassword)
validator.md#IsWeakPassword)
### 18. xerror包实现一些错误处理函数
### 19. xerror包实现一些错误处理函数
```go
import "github.com/duke-git/lancet/v2/xerror"

View File

@@ -234,7 +234,7 @@ func (link *DoublyLink[T]) IsEmpty() bool {
return link.length == 0
}
// Clear checks if link is empty or not
// Clear all nodes in doubly linklist
func (link *DoublyLink[T]) Clear() {
link.Head = nil
link.length = 0

View File

@@ -227,7 +227,7 @@ func (link *SinglyLink[T]) IsEmpty() bool {
return link.length == 0
}
// Clear checks if link is empty or not
// Clear all the node in singly linklist
func (link *SinglyLink[T]) Clear() {
link.Head = nil
link.length = 0

View File

@@ -132,8 +132,8 @@ func (l *List[T]) UpdateAt(index int, value T) {
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 {
// Equal compare list to other list, use reflect.DeepEqual
func (l *List[T]) Equal(other *List[T]) bool {
if len(l.data) != len(other.data) {
return false
}

View File

@@ -155,15 +155,15 @@ func TestUpdateAt(t *testing.T) {
assert.Equal([]int{5, 2, 3, 1}, list.Data())
}
func TestEqutal(t *testing.T) {
assert := internal.NewAssert(t, "TestEqutal")
func TestEqual(t *testing.T) {
assert := internal.NewAssert(t, "TestEqual")
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))
assert.Equal(true, list1.Equal(list2))
assert.Equal(false, list1.Equal(list3))
}
func TestIsEmpty(t *testing.T) {
@@ -192,7 +192,7 @@ func TestClone(t *testing.T) {
list1 := NewList([]int{1, 2, 3, 4})
list2 := list1.Clone()
assert.Equal(true, list1.Equtal(list2))
assert.Equal(true, list1.Equal(list2))
}
func TestMerge(t *testing.T) {
@@ -203,7 +203,7 @@ func TestMerge(t *testing.T) {
expected := NewList([]int{1, 2, 3, 4, 4, 5, 6})
list3 := list1.Merge(list2)
assert.Equal(true, expected.Equtal(list3))
assert.Equal(true, expected.Equal(list3))
}
func TestSize(t *testing.T) {
@@ -224,7 +224,7 @@ func TestSwap(t *testing.T) {
list.Swap(0, 3)
assert.Equal(true, expected.Equtal(list))
assert.Equal(true, expected.Equal(list))
}
func TestReverse(t *testing.T) {
@@ -235,7 +235,7 @@ func TestReverse(t *testing.T) {
list.Reverse()
assert.Equal(true, expected.Equtal(list))
assert.Equal(true, expected.Equal(list))
}
func TestUnique(t *testing.T) {
@@ -246,7 +246,7 @@ func TestUnique(t *testing.T) {
list.Unique()
assert.Equal(true, expected.Equtal(list))
assert.Equal(true, expected.Equal(list))
}
func TestUnion(t *testing.T) {
@@ -257,7 +257,7 @@ func TestUnion(t *testing.T) {
expected := NewList([]int{1, 2, 3, 4, 5, 6})
list3 := list1.Union(list2)
assert.Equal(true, expected.Equtal(list3))
assert.Equal(true, expected.Equal(list3))
}
func TestIntersection(t *testing.T) {
@@ -268,5 +268,5 @@ func TestIntersection(t *testing.T) {
expected := NewList([]int{4})
list3 := list1.Intersection(list2)
assert.Equal(true, expected.Equtal(list3))
assert.Equal(true, expected.Equal(list3))
}

View File

@@ -24,7 +24,7 @@ func NewArrayQueue[T any](capacity int) *ArrayQueue[T] {
}
}
// Data return queue data
// Data return slice of queue data
func (q *ArrayQueue[T]) Data() []T {
items := []T{}
for i := q.head; i < q.tail; i++ {
@@ -33,7 +33,7 @@ func (q *ArrayQueue[T]) Data() []T {
return items
}
// Size return length of queue data
// Size return number of elements in queue
func (q *ArrayQueue[T]) Size() int {
return q.size
}
@@ -43,6 +43,11 @@ func (q *ArrayQueue[T]) IsEmpty() bool {
return q.size == 0
}
// IsFull checks if queue is full or not
func (q *ArrayQueue[T]) IsFull() bool {
return q.size == q.capacity
}
// Front return front value of queue
func (q *ArrayQueue[T]) Front() T {
return q.items[0]

View File

@@ -100,3 +100,14 @@ func TestArrayQueue_Clear(t *testing.T) {
assert.Equal(true, queue.IsEmpty())
assert.Equal(0, queue.Size())
}
func TestArrayQueue_IsFull(t *testing.T) {
assert := internal.NewAssert(t, "TestArrayQueue_IsFull")
queue := NewArrayQueue[int](3)
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
assert.Equal(true, queue.IsFull())
}

View File

@@ -7,21 +7,21 @@ import (
)
// CircularQueue implements circular queue with slice,
// last index of CircularQueue don't contain value, so acturl capacity is size - 1
// last index of CircularQueue don't contain value, so acturl capacity is capacity - 1
type CircularQueue[T any] struct {
data []T
front int
rear int
size int
data []T
front int
rear int
capacity 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}
func NewCircularQueue[T any](capacity int) *CircularQueue[T] {
data := make([]T, capacity)
return &CircularQueue[T]{data: data, front: 0, rear: 0, capacity: capacity}
}
// Data return queue data
// Data return slice of queue data
func (q *CircularQueue[T]) Data() []T {
data := []T{}
@@ -37,12 +37,12 @@ func (q *CircularQueue[T]) Data() []T {
return data
}
// Length return current data length of queue
func (q *CircularQueue[T]) Length() int {
if q.size == 0 {
// Size return number of elements in circular queue
func (q *CircularQueue[T]) Size() int {
if q.capacity == 0 {
return 0
}
return (q.rear - q.front + q.size) % q.size
return (q.rear - q.front + q.capacity) % q.capacity
}
// IsEmpty checks if queue is empty or not
@@ -52,7 +52,7 @@ func (q *CircularQueue[T]) IsEmpty() bool {
// IsFull checks if queue is full or not
func (q *CircularQueue[T]) IsFull() bool {
return (q.rear+1)%q.size == q.front
return (q.rear+1)%q.capacity == q.front
}
// Front return front value of queue
@@ -65,23 +65,23 @@ func (q *CircularQueue[T]) Back() T {
if q.rear-1 >= 0 {
return q.data[q.rear-1]
}
return q.data[q.size-1]
return q.data[q.capacity-1]
}
// EnQueue put element into queue
func (q *CircularQueue[T]) EnQueue(value T) error {
// 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
q.rear = (q.rear + 1) % q.capacity
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) {
// 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")
}
@@ -89,7 +89,7 @@ func (q *CircularQueue[T]) DeQueue() (*T, error) {
headItem := q.data[q.front]
var t T
q.data[q.front] = t
q.front = (q.front + 1) % q.size
q.front = (q.front + 1) % q.capacity
return &headItem, nil
}
@@ -99,7 +99,7 @@ func (q *CircularQueue[T]) Clear() {
q.data = []T{}
q.front = 0
q.rear = 0
q.size = 0
q.capacity = 0
}
// Contain checks if the value is in queue or not

View File

@@ -6,47 +6,47 @@ import (
"github.com/duke-git/lancet/v2/internal"
)
func TestCircularQueue_EnQueue(t *testing.T) {
assert := internal.NewAssert(t, "TestCircularQueue_EnQueue")
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.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())
assert.Equal([]int{1, 2, 3, 4, 5}, queue.Data())
assert.Equal(5, queue.Size())
err := queue.EnQueue(6)
err := queue.Enqueue(6)
assert.IsNotNil(err)
}
func TestCircularQueue_DeQueue(t *testing.T) {
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)
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
queue.Enqueue(4)
queue.Enqueue(5)
val, err := queue.DeQueue()
val, err := queue.Dequeue()
assert.IsNil(err)
assert.Equal(1, *val)
assert.Equal(false, queue.IsFull())
val, _ = queue.DeQueue()
val, _ = queue.Dequeue()
queue.Print()
assert.Equal(2, *val)
queue.EnQueue(6)
queue.Enqueue(6)
queue.Print()
assert.Equal(false, queue.IsFull())
}
@@ -55,24 +55,24 @@ 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.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.Dequeue()
queue.Dequeue()
queue.Enqueue(6)
queue.Enqueue(7)
queue.Print()
val := queue.Front()
assert.Equal(3, val)
assert.Equal(5, queue.Length())
assert.Equal(5, queue.Size())
}
func TestCircularQueue_Back(t *testing.T) {
@@ -81,19 +81,19 @@ func TestCircularQueue_Back(t *testing.T) {
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.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.Dequeue()
queue.Dequeue()
queue.Enqueue(6)
queue.Enqueue(7)
queue.Print()
assert.Equal(7, queue.Back())
@@ -103,7 +103,7 @@ func TestCircularQueue_Contain(t *testing.T) {
assert := internal.NewAssert(t, "TestCircularQueue_Contain")
queue := NewCircularQueue[int](2)
queue.EnQueue(1)
queue.Enqueue(1)
assert.Equal(true, queue.Contain(1))
assert.Equal(false, queue.Contain(2))
}
@@ -113,34 +113,34 @@ func TestCircularQueue_Clear(t *testing.T) {
queue := NewCircularQueue[int](3)
assert.Equal(true, queue.IsEmpty())
assert.Equal(0, queue.Length())
assert.Equal(0, queue.Size())
queue.EnQueue(1)
queue.Enqueue(1)
assert.Equal(false, queue.IsEmpty())
assert.Equal(1, queue.Length())
assert.Equal(1, queue.Size())
queue.Clear()
assert.Equal(true, queue.IsEmpty())
assert.Equal(0, queue.Length())
assert.Equal(0, queue.Size())
}
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.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.Dequeue()
queue.Dequeue()
queue.Enqueue(6)
queue.Enqueue(7)
queue.Print()
assert.Equal([]int{3, 4, 5, 6, 7}, queue.Data())

View File

@@ -3,6 +3,7 @@ package datastructure
import (
"errors"
"fmt"
"reflect"
"github.com/duke-git/lancet/v2/datastructure"
)
@@ -19,7 +20,7 @@ func NewLinkedQueue[T any]() *LinkedQueue[T] {
return &LinkedQueue[T]{head: nil, tail: nil, length: 0}
}
// Data return queue data
// Data return slice of queue data
func (q *LinkedQueue[T]) Data() []T {
res := []T{}
current := q.head
@@ -41,8 +42,8 @@ func (q *LinkedQueue[T]) IsEmpty() bool {
return q.length == 0
}
// EnQueue add element into queue
func (q *LinkedQueue[T]) EnQueue(value T) {
// Enqueue put element into queue
func (q *LinkedQueue[T]) Enqueue(value T) {
newNode := datastructure.NewQueueNode(value)
if q.IsEmpty() {
@@ -55,8 +56,8 @@ func (q *LinkedQueue[T]) EnQueue(value T) {
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) {
// 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")
}
@@ -102,3 +103,15 @@ func (q *LinkedQueue[T]) Print() {
info += " ]"
fmt.Println(info)
}
// Contain checks if the value is in queue or not
func (q *LinkedQueue[T]) Contain(value T) bool {
current := q.head
for current != nil {
if reflect.DeepEqual(current.Value, value) {
return true
}
current = current.Next
}
return false
}

View File

@@ -6,13 +6,13 @@ import (
"github.com/duke-git/lancet/v2/internal"
)
func TestLinkedQueue_EnQueue(t *testing.T) {
assert := internal.NewAssert(t, "TestLinkedQueue_EnQueue")
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.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
queue.Print()
@@ -20,15 +20,15 @@ func TestLinkedQueue_EnQueue(t *testing.T) {
assert.Equal(3, queue.Size())
}
func TestLinkedQueue_DeQueue(t *testing.T) {
func TestLinkedQueue_Dequeue(t *testing.T) {
assert := internal.NewAssert(t, "TestLinkedQueue_DeQueue")
queue := NewLinkedQueue[int]()
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
val, _ := queue.DeQueue()
val, _ := queue.Dequeue()
queue.Print()
@@ -43,9 +43,9 @@ func TestLinkedQueue_Front(t *testing.T) {
_, err := queue.Front()
assert.IsNotNil(err)
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
val, err := queue.Front()
assert.Equal(1, *val)
@@ -59,9 +59,9 @@ func TestLinkedQueue_Back(t *testing.T) {
_, err := queue.Back()
assert.IsNotNil(err)
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
val, err := queue.Back()
assert.Equal(3, *val)
@@ -74,11 +74,24 @@ func TestLinkedQueue_Clear(t *testing.T) {
queue := NewLinkedQueue[int]()
assert.Equal(true, queue.IsEmpty())
queue.EnQueue(1)
queue.EnQueue(2)
queue.EnQueue(3)
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
assert.Equal(false, queue.IsEmpty())
queue.Clear()
assert.Equal(true, queue.IsEmpty())
}
func TestLinkedQueue_Contain(t *testing.T) {
assert := internal.NewAssert(t, "TestLinkedQueue_Contain")
queue := NewLinkedQueue[int]()
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
assert.Equal(true, queue.Contain(1))
assert.Equal(false, queue.Contain(4))
}

View File

@@ -29,12 +29,17 @@ func (q *PriorityQueue[T]) IsEmpty() bool {
return q.size == 0
}
// Size get number of items in the queue
func (q *PriorityQueue[T]) Size() int {
return q.size
}
// IsFull checks if the queue capacity is full or not
func (q *PriorityQueue[T]) IsFull() bool {
return q.size == len(q.items)-1
}
// Data return data slice in the queue
// Data return a slice of queue data
func (q *PriorityQueue[T]) Data() []T {
data := make([]T, q.size)
for i := 1; i < q.size+1; i++ {

View File

@@ -52,9 +52,13 @@ func TestPriorityQueue_Dequeue(t *testing.T) {
pq.Enqueue(i)
}
assert.Equal(10, pq.Size())
val, ok := pq.Dequeue()
assert.Equal(true, ok)
assert.Equal(10, val)
assert.Equal([]int{9, 8, 6, 7, 3, 2, 5, 1, 4}, pq.Data())
assert.Equal(9, pq.Size())
}

View File

@@ -23,7 +23,7 @@ func (s Set[T]) Contain(value T) bool {
return ok
}
// Contain checks if set contains other set
// ContainAll checks if set contains other set
func (s Set[T]) ContainAll(other Set[T]) bool {
for k := range other {
_, ok := s[k]

View File

@@ -47,7 +47,7 @@ func (s *ArrayStack[T]) Pop() (*T, error) {
return &topItem, nil
}
// Peak return the top element of stack then return it
// Peak return the top element of stack
func (s *ArrayStack[T]) Peak() (*T, error) {
if s.IsEmpty() {
return nil, errors.New("stack is empty")

View File

@@ -24,7 +24,7 @@ func NewBSTree[T any](rootData T, comparator lancetconstraints.Comparator) *BSTr
}
// InsertNode insert data into BSTree
func (t *BSTree[T]) InsertNode(data T) {
func (t *BSTree[T]) Insert(data T) {
root := t.root
newNode := datastructure.NewTreeNode(data)
if root == nil {
@@ -35,7 +35,7 @@ func (t *BSTree[T]) InsertNode(data T) {
}
// DeletetNode delete data into BSTree
func (t *BSTree[T]) DeletetNode(data T) {
func (t *BSTree[T]) Delete(data T) {
deleteTreeNode(t.root, data, t.comparator)
}

View File

@@ -20,13 +20,13 @@ func (c *intComparator) Compare(v1, v2 any) int {
return 0
}
func TestBSTree_InsertNode(t *testing.T) {
func TestBSTree_Insert(t *testing.T) {
bstree := NewBSTree(6, &intComparator{})
bstree.InsertNode(7)
bstree.InsertNode(5)
bstree.InsertNode(2)
bstree.InsertNode(4)
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
bstree.Print()
}
@@ -36,10 +36,10 @@ func TestBSTree_PreOrderTraverse(t *testing.T) {
bstree := NewBSTree(6, &intComparator{})
bstree.InsertNode(7)
bstree.InsertNode(5)
bstree.InsertNode(2)
bstree.InsertNode(4)
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
acturl := bstree.PreOrderTraverse()
t.Log(acturl)
@@ -51,10 +51,10 @@ func TestBSTree_PostOrderTraverse(t *testing.T) {
bstree := NewBSTree(6, &intComparator{})
bstree.InsertNode(7)
bstree.InsertNode(5)
bstree.InsertNode(2)
bstree.InsertNode(4)
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
acturl := bstree.PostOrderTraverse()
t.Log(acturl)
@@ -66,10 +66,10 @@ func TestBSTree_InOrderTraverse(t *testing.T) {
bstree := NewBSTree(6, &intComparator{})
bstree.InsertNode(7)
bstree.InsertNode(5)
bstree.InsertNode(2)
bstree.InsertNode(4)
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
acturl := bstree.InOrderTraverse()
t.Log(acturl)
@@ -81,10 +81,10 @@ func TestBSTree_LevelOrderTraverse(t *testing.T) {
bstree := NewBSTree(6, &intComparator{})
bstree.InsertNode(7)
bstree.InsertNode(5)
bstree.InsertNode(2)
bstree.InsertNode(4)
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
bstree.Print()
@@ -93,19 +93,19 @@ func TestBSTree_LevelOrderTraverse(t *testing.T) {
assert.Equal([]int{6, 5, 7, 2, 4}, acturl)
}
func TestBSTree_DeletetNode(t *testing.T) {
assert := internal.NewAssert(t, "TestBSTree_DeletetNode")
func TestBSTree_Delete(t *testing.T) {
assert := internal.NewAssert(t, "TestBSTree_Delete")
bstree := NewBSTree(6, &intComparator{})
bstree.InsertNode(7)
bstree.InsertNode(5)
bstree.InsertNode(2)
bstree.InsertNode(4)
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
bstree.Print()
bstree.DeletetNode(4)
bstree.Delete(4)
bstree.Print()
acturl1 := bstree.InOrderTraverse()
t.Log(acturl1)
@@ -124,10 +124,10 @@ func TestBSTree_Depth(t *testing.T) {
bstree := NewBSTree(6, &intComparator{})
bstree.InsertNode(7)
bstree.InsertNode(5)
bstree.InsertNode(2)
bstree.InsertNode(4)
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
bstree.Print()
@@ -138,17 +138,17 @@ func TestBSTree_IsSubTree(t *testing.T) {
assert := internal.NewAssert(t, "TestBSTree_IsSubTree")
superTree := NewBSTree(8, &intComparator{})
superTree.InsertNode(4)
superTree.InsertNode(5)
superTree.InsertNode(6)
superTree.InsertNode(9)
superTree.InsertNode(4)
superTree.Insert(4)
superTree.Insert(5)
superTree.Insert(6)
superTree.Insert(9)
superTree.Insert(4)
superTree.Print()
subTree := NewBSTree(5, &intComparator{})
subTree.InsertNode(4)
subTree.InsertNode(6)
subTree.Insert(4)
subTree.Insert(6)
subTree.Print()

View File

@@ -21,23 +21,20 @@ import (
<div STYLE="page-break-after: always;"></div>
## Index
- [Algorithm](#algorithm)
- [Source](#source)
- [Usage](#usage)
- [Index](#index)
- [Documentation](#documentation)
- [<span id="BubbleSort">BubbleSort</span>](#bubblesort)
- [<span id="InsertionSort">InsertionSort</span>](#insertionsort)
- [<span id="SelectionSort">SelectionSort</span>](#selectionsort)
- [<span id="ShellSort">ShellSort</span>](#shellsort)
- [<span id="QuickSort">QuickSort</span>](#quicksort)
- [<span id="HeapSort">HeapSort</span>](#heapsort)
- [<span id="MergeSort">MergeSort</span>](#mergesort)
- [<span id="CountSort">CountSort</span>](#countsort)
- [<span id="BinarySearch">BinarySearch</span>](#binarysearch)
- [<span id="BinaryIterativeSearch">BinaryIterativeSearch</span>](#binaryiterativesearch)
- [<span id="LinearSearch">LinearSearch</span>](#linearsearch)
- [<span id="LRUCache">LRUCache</span>](#lrucache)
- [BubbleSort](#BubbleSort)
- [InsertionSort](#InsertionSort)
- [SelectionSort](#SelectionSort)
- [ShellSort](#ShellSort)
- [QuickSort](#QuickSort)
- [HeapSort](#HeapSort)
- [MergeSort](#MergeSort)
- [CountSort](#CountSort)
- [BinarySearch](#BinarySearch)
- [BinaryIterativeSearch](#BinaryIterativeSearch)
- [LinearSearch](#LinearSearch)
- [LRUCache](#LRUCache)
<div STYLE="page-break-after: always;"></div>

View File

@@ -21,23 +21,21 @@ import (
<div STYLE="page-break-after: always;"></div>
## 目录
- [Algorithm](#algorithm)
- [源码](#源码)
- [用法](#用法)
- [目录](#目录)
- [文档](#文档)
- [<span id="BubbleSort">BubbleSort</span>](#bubblesort)
- [<span id="InsertionSort">InsertionSort</span>](#insertionsort)
- [<span id="SelectionSort">SelectionSort</span>](#selectionsort)
- [<span id="ShellSort">ShellSort</span>](#shellsort)
- [<span id="QuickSort">QuickSort</span>](#quicksort)
- [<span id="HeapSort">HeapSort</span>](#heapsort)
- [<span id="MergeSort">MergeSort</span>](#mergesort)
- [<span id="CountSort">CountSort</span>](#countsort)
- [<span id="BinarySearch">BinarySearch</span>](#binarysearch)
- [<span id="BinaryIterativeSearch">BinaryIterativeSearch</span>](#binaryiterativesearch)
- [<span id="LinearSearch">LinearSearch</span>](#linearsearch)
- [<span id="LRUCache">LRUCache</span>](#lrucache)
- [BubbleSort](#BubbleSort)
- [InsertionSort](#InsertionSort)
- [SelectionSort](#SelectionSort)
- [ShellSort](#ShellSort)
- [QuickSort](#QuickSort)
- [HeapSort](#HeapSort)
- [MergeSort](#MergeSort)
- [CountSort](#CountSort)
- [BinarySearch](#BinarySearch)
- [BinaryIterativeSearch](#BinaryIterativeSearch)
- [LinearSearch](#LinearSearch)
- [LRUCache](#LRUCache)
<div STYLE="page-break-after: always;"></div>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

713
docs/datastructure/list.md Normal file
View File

@@ -0,0 +1,713 @@
# List
List is a linear table, implemented with slice.
<div STYLE="page-break-after: always;"></div>
## Source
- [https://github.com/duke-git/lancet/blob/main/datastructure/list/list.go](https://github.com/duke-git/lancet/blob/main/datastructure/list/list.go)
<div STYLE="page-break-after: always;"></div>
## Usage
```go
import (
list "github.com/duke-git/lancet/v2/datastructure/list"
)
```
<div STYLE="page-break-after: always;"></div>
## Index
- [NewList](#NewList)
- [Contain](#Contain)
- [Data](#Data)
- [ValueOf](#ValueOf)
- [IndexOf](#IndexOf)
- [Push](#Push)
- [PopFirst](#PopFirst)
- [PopLast](#PopLast)
- [DeleteAt](#DeleteAt)
- [InsertAt](#InsertAt)
- [UpdateAt](#UpdateAt)
- [Equal](#Equal)
- [IsEmpty](#IsEmpty)
- [Clear](#Clear)
- [Clone](#Clone)
- [Merge](#Merge)
- [Size](#Size)
- [Swap](#Swap)
- [Reverse](#Reverse)
- [Unique](#Unique)
- [Union](#Union)
- [Intersection](#Intersection)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="NewList">NewList</span>
<p>List is a linear table, implemented with slice.
NewList function return a list pointer</p>
<b>Signature:</b>
```go
type List[T any] struct {
data []T
}
func NewList[T any](data []T) *List[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
fmt.Println(li)
}
```
### <span id="Contain">Contain</span>
<p>Check if the value in the list or not</p>
<b>Signature:</b>
```go
func (l *List[T]) Contain(value T) bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
fmt.Println(li.Contain(1)) //true
fmt.Println(li.Contain(0)) //false
}
```
### <span id="Data">Data</span>
<p>Return slice of list data</p>
<b>Signature:</b>
```go
func (l *List[T]) Data() []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
data := li.Data()
fmt.Println(data) //[]int{1, 2, 3}
}
```
### <span id="ValueOf">ValueOf</span>
<p>Return the value pointer at index in list</p>
<b>Signature:</b>
```go
func (l *List[T]) ValueOf(index int) (*T, bool)
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
v, ok := li.ValueOf(0)
fmt.Println(*v) //1
fmt.Println(ok) //true
}
```
### <span id="IndexOf">IndexOf</span>
<p>Reture the index of value in the list. if not found return -1</p>
<b>Signature:</b>
```go
func (l *List[T]) IndexOf(value T) int
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
fmt.Println(li.IndexOf(1)) //0
fmt.Println(li.IndexOf(0)) //-1
}
```
### <span id="Push">Push</span>
<p>Append value to the list</p>
<b>Signature:</b>
```go
func (l *List[T]) Push(value T)
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
li.Push(4)
fmt.Println(li.Data()) //[]int{1, 2, 3, 4}
}
```
### <span id="PopFirst">PopFirst</span>
<p>Delete the first value of list and return it</p>
<b>Signature:</b>
```go
func (l *List[T]) PopFirst() (*T, bool)
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
v, ok := li.PopFirst()
fmt.Println(*v) //1
fmt.Println(ok) //true
fmt.Println(li.Data()) //2, 3
}
```
### <span id="PopLast">PopFirst</span>
<p>Delete the last value of list and return it</p>
<b>Signature:</b>
```go
func (l *List[T]) PopLast() (*T, bool)
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
v, ok := li.PopLast()
fmt.Println(*v) //3
fmt.Println(ok) //true
fmt.Println(li.Data()) //1, 2
}
```
### <span id="DeleteAt">DeleteAt</span>
<p>Delete the value of list at index, if index is not between 0 and length of list data, do nothing</p>
<b>Signature:</b>
```go
func (l *List[T]) DeleteAt(index int)
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3, 4})
li.DeleteAt(-1)
fmt.Println(li.Data()) //1,2,3,4
li.DeleteAt(4)
fmt.Println(li.Data()) //1,2,3,4
li.DeleteAt(0)
fmt.Println(li.Data()) //2,3,4
li.DeleteAt(2)
fmt.Println(li.Data()) //2,3
}
```
### <span id="InsertAt">InsertAt</span>
<p>Insert value into list at index, if index is not between 0 and length of list data, do nothing</p>
<b>Signature:</b>
```go
func (l *List[T]) InsertAt(index int, value T)
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
li.InsertAt(-1, 0)
fmt.Println(li.Data()) //1,2,3
li.InsertAt(4, 0)
fmt.Println(li.Data()) //1,2,3
li.InsertAt(3, 4)
fmt.Println(li.Data()) //1,2,3,4
// li.InsertAt(2, 4)
// fmt.Println(li.Data()) //1,2,4,3
}
```
### <span id="UpdateAt">UpdateAt</span>
<p>Update value of list at index, index shoud between 0 and list size - 1</p>
<b>Signature:</b>
```go
func (l *List[T]) UpdateAt(index int, value T)
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
li.UpdateAt(-1, 0)
fmt.Println(li.Data()) //1,2,3
li.UpdateAt(2, 4)
fmt.Println(li.Data()) //1,2,4
li.UpdateAt(3, 5)
fmt.Println(li.Data()) //1,2,4
}
```
### <span id="Equal">Equal</span>
<p>Compare a list to another list, use reflect.DeepEqual on every element</p>
<b>Signature:</b>
```go
func (l *List[T]) Equal(other *List[T]) bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li1 := list.NewList([]int{1, 2, 3, 4})
li2 := list.NewList([]int{1, 2, 3, 4})
li3 := list.NewList([]int{1, 2, 3})
fmt.Println(li1.Equal(li2)) //true
fmt.Println(li1.Equal(li3)) //false
}
```
### <span id="IsEmpty">IsEmpty</span>
<p>Check if a list is empty or not</p>
<b>Signature:</b>
```go
func (l *List[T]) IsEmpty() bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li1 := list.NewList([]int{1, 2, 3})
li2 := list.NewList([]int{})
fmt.Println(li1.IsEmpty()) //false
fmt.Println(li2.IsEmpty()) //true
}
```
### <span id="Clear">Clear</span>
<p>Clear the data of list</p>
<b>Signature:</b>
```go
func (l *List[T]) Clear()
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
li.Clear()
fmt.Println(li.Data()) // empty
}
```
### <span id="Clone">Clone</span>
<p>Return a copy of list</p>
<b>Signature:</b>
```go
func (l *List[T]) Clone() *List[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
cloneList := li.Clone()
fmt.Println(cloneList.Data()) // 1,2,3
}
```
### <span id="Merge">Merge</span>
<p>Merge two list, return new list, don't change original list</p>
<b>Signature:</b>
```go
func (l *List[T]) Merge(other *List[T]) *List[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li1 := list.NewList([]int{1, 2, 3, 4})
li2 := list.NewList([]int{4, 5, 6})
li3 := li1.Merge(li2)
fmt.Println(li3.Data()) //1, 2, 3, 4, 4, 5, 6
}
```
### <span id="Size">Size</span>
<p>Return number of list data items</p>
<b>Signature:</b>
```go
func (l *List[T]) Size() int
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3, 4})
fmt.Println(li.Size()) //4
}
```
### <span id="Swap">Swap</span>
<p>Swap the value at two index in list</p>
<b>Signature:</b>
```go
func (l *List[T]) Swap(i, j int)
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3, 4})
li.Swap(0, 3)
fmt.Println(li.Data()) //4, 2, 3, 1
}
```
### <span id="Reverse">Reverse</span>
<p>Reverse the data item order of list</p>
<b>Signature:</b>
```go
func (l *List[T]) Reverse()
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3, 4})
li.Reverse()
fmt.Println(li.Data()) //4, 3, 2, 1
}
```
### <span id="Unique">Unique</span>
<p>Remove duplicate items in list</p>
<b>Signature:</b>
```go
func (l *List[T]) Unique()
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 2, 3, 4})
li.Unique()
fmt.Println(li.Data()) //1,2,3,4
}
```
### <span id="Union">Union</span>
<p>Creates a new list contain all elements in list l and other, remove duplicate element</p>
<b>Signature:</b>
```go
func (l *List[T]) Union(other *List[T]) *List[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li1 := list.NewList([]int{1, 2, 3, 4})
li2 := list.NewList([]int{4, 5, 6})
li3 := li1.Union(li2)
fmt.Println(li3.Data()) //1,2,3,4,5,6
}
```
### <span id="Intersection">Intersection</span>
<p>Creates a new list whose element both be contained in list l and other</p>
<b>Signature:</b>
```go
func (l *List[T]) Intersection(other *List[T]) *List[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li1 := list.NewList([]int{1, 2, 3, 4})
li2 := list.NewList([]int{4, 5, 6})
li3 := li1.Intersection(li2)
fmt.Println(li3.Data()) //4
}
```

View File

@@ -0,0 +1,712 @@
# List
List是线性表数据结构, 用go切片实现。
<div STYLE="page-break-after: always;"></div>
## 源码
- [https://github.com/duke-git/lancet/blob/main/datastructure/list/list.go](https://github.com/duke-git/lancet/blob/main/datastructure/list/list.go)
<div STYLE="page-break-after: always;"></div>
## 用法
```go
import (
"github.com/duke-git/lancet/v2/datastructure"
)
```
<div STYLE="page-break-after: always;"></div>
## 目录
- [NewList](#NewList)
- [Contain](#Contain)
- [Data](#Data)
- [ValueOf](#ValueOf)
- [IndexOf](#IndexOf)
- [Push](#Push)
- [PopFirst](#PopFirst)
- [PopLast](#PopLast)
- [DeleteAt](#DeleteAt)
- [InsertAt](#InsertAt)
- [UpdateAt](#UpdateAt)
- [Equal](#Equal)
- [IsEmpty](#IsEmpty)
- [Clear](#Clear)
- [Clone](#Clone)
- [Merge](#Merge)
- [Size](#Size)
- [Swap](#Swap)
- [Reverse](#Reverse)
- [Unique](#Unique)
- [Union](#Union)
- [Intersection](#Intersection)
<div STYLE="page-break-after: always;"></div>
## 文档
### <span id="NewList">NewList</span>
<p>返回List指针实例</p>
<b>函数签名:</b>
```go
type List[T any] struct {
data []T
}
func NewList[T any](data []T) *List[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
fmt.Println(li)
}
```
### <span id="Contain">Contain</span>
<p>判断列表中是否包含特定值</p>
<b>函数签名:</b>
```go
func (l *List[T]) Contain(value T) bool
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
fmt.Println(li.Contain(1)) //true
fmt.Println(li.Contain(0)) //false
}
```
### <span id="Data">Data</span>
<p>返回List中所有数据切片</p>
<b>函数签名:</b>
```go
func (l *List[T]) Data() []T
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
data := li.Data()
fmt.Println(data) //[]int{1, 2, 3}
}
```
### <span id="ValueOf">ValueOf</span>
<p>返回列表中索引处的值指针</p>
<b>函数签名:</b>
```go
func (l *List[T]) ValueOf(index int) (*T, bool)
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
v, ok := li.ValueOf(0)
fmt.Println(*v) //1
fmt.Println(ok) //true
}
```
### <span id="IndexOf">IndexOf</span>
<p>返回列表中值的索引,如果没有找到返回-1</p>
<b>函数签名:</b>
```go
func (l *List[T]) IndexOf(value T) int
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
fmt.Println(li.IndexOf(1)) //0
fmt.Println(li.IndexOf(0)) //-1
}
```
### <span id="Push">Push</span>
<p>将值附加到列表末尾</p>
<b>函数签名:</b>
```go
func (l *List[T]) Push(value T)
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
li.Push(4)
fmt.Println(li.Data()) //[]int{1, 2, 3, 4}
}
```
### <span id="PopFirst">PopFirst</span>
<p>删除列表的第一个值并返回该值</p>
<b>函数签名:</b>
```go
func (l *List[T]) PopFirst() (*T, bool)
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
v, ok := li.PopFirst()
fmt.Println(*v) //1
fmt.Println(ok) //true
fmt.Println(li.Data()) //2, 3
}
```
### <span id="PopLast">PopFirst</span>
<p>删除列表的最后一个值并返回该值</p>
<b>函数签名:</b>
```go
func (l *List[T]) PopLast() (*T, bool)
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
v, ok := li.PopLast()
fmt.Println(*v) //3
fmt.Println(ok) //true
fmt.Println(li.Data()) //1, 2
}
```
### <span id="DeleteAt">DeleteAt</span>
<p>删除索引处列表的值如果索引不在0和列表数据长度之间则不执行任何操作</p>
<b>函数签名:</b>
```go
func (l *List[T]) DeleteAt(index int)
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3, 4})
li.DeleteAt(-1)
fmt.Println(li.Data()) //1,2,3,4
li.DeleteAt(4)
fmt.Println(li.Data()) //1,2,3,4
li.DeleteAt(0)
fmt.Println(li.Data()) //2,3,4
li.DeleteAt(2)
fmt.Println(li.Data()) //2,3
}
```
### <span id="InsertAt">InsertAt</span>
<p>在索引处插入值到列表中,如果索引不在 0 和列表数据长度之间,则不执行任何操作</p>
<b>函数签名:</b>
```go
func (l *List[T]) InsertAt(index int, value T)
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
li.InsertAt(-1, 0)
fmt.Println(li.Data()) //1,2,3
li.InsertAt(4, 0)
fmt.Println(li.Data()) //1,2,3
li.InsertAt(3, 4)
fmt.Println(li.Data()) //1,2,3,4
// li.InsertAt(2, 4)
// fmt.Println(li.Data()) //1,2,4,3
}
```
### <span id="UpdateAt">UpdateAt</span>
<p>更新索引处列表的值索引应该在0和列表数据长度-1之间</p>
<b>函数签名:</b>
```go
func (l *List[T]) UpdateAt(index int, value T)
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
li.UpdateAt(-1, 0)
fmt.Println(li.Data()) //1,2,3
li.UpdateAt(2, 4)
fmt.Println(li.Data()) //1,2,4
li.UpdateAt(3, 5)
fmt.Println(li.Data()) //1,2,4
}
```
### <span id="Equal">Equal</span>
<p>比较一个列表和另一个列表,在每个元素上使用 reflect.DeepEqual</p>
<b>函数签名:</b>
```go
func (l *List[T]) Equal(other *List[T]) bool
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li1 := list.NewList([]int{1, 2, 3, 4})
li2 := list.NewList([]int{1, 2, 3, 4})
li3 := list.NewList([]int{1, 2, 3})
fmt.Println(li1.Equal(li2)) //true
fmt.Println(li1.Equal(li3)) //false
}
```
### <span id="IsEmpty">IsEmpty</span>
<p>判断列表是否为空</p>
<b>函数签名:</b>
```go
func (l *List[T]) IsEmpty() bool
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li1 := list.NewList([]int{1, 2, 3})
li2 := list.NewList([]int{})
fmt.Println(li1.IsEmpty()) //false
fmt.Println(li2.IsEmpty()) //true
}
```
### <span id="Clear">Clear</span>
<p>清空列表数据</p>
<b>函数签名:</b>
```go
func (l *List[T]) Clear()
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
li.Clear()
fmt.Println(li.Data()) // empty
}
```
### <span id="Clone">Clone</span>
<p>返回列表的一个拷贝</p>
<b>函数签名:</b>
```go
func (l *List[T]) Clone() *List[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3})
cloneList := li.Clone()
fmt.Println(cloneList.Data()) // 1,2,3
}
```
### <span id="Merge">Merge</span>
<p>合并两个列表,返回新的列表</p>
<b>函数签名:</b>
```go
func (l *List[T]) Merge(other *List[T]) *List[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li1 := list.NewList([]int{1, 2, 3, 4})
li2 := list.NewList([]int{4, 5, 6})
li3 := li1.Merge(li2)
fmt.Println(li3.Data()) //1, 2, 3, 4, 4, 5, 6
}
```
### <span id="Size">Size</span>
<p>返回列表数据项的数量</p>
<b>函数签名:</b>
```go
func (l *List[T]) Size() int
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3, 4})
fmt.Println(li.Size()) //4
}
```
### <span id="Swap">Swap</span>
<p>交换列表中两个索引位置的值</p>
<b>函数签名:</b>
```go
func (l *List[T]) Swap(i, j int)
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3, 4})
li.Swap(0, 3)
fmt.Println(li.Data()) //4, 2, 3, 1
}
```
### <span id="Reverse">Reverse</span>
<p>反转列表的数据项顺序</p>
<b>函数签名:</b>
```go
func (l *List[T]) Reverse()
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 3, 4})
li.Reverse()
fmt.Println(li.Data()) //4, 3, 2, 1
}
```
### <span id="Unique">Unique</span>
<p>列表去除重复数据项</p>
<b>函数签名:</b>
```go
func (l *List[T]) Unique()
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li := list.NewList([]int{1, 2, 2, 3, 4})
li.Unique()
fmt.Println(li.Data()) //1,2,3,4
}
```
### <span id="Union">Union</span>
<p>两个列表取并集,去除重复数据项</p>
<b>函数签名:</b>
```go
func (l *List[T]) Union(other *List[T]) *List[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li1 := list.NewList([]int{1, 2, 3, 4})
li2 := list.NewList([]int{4, 5, 6})
li3 := li1.Union(li2)
fmt.Println(li3.Data()) //1,2,3,4,5,6
}
```
### <span id="Intersection">Intersection</span>
<p>两个列表取交集</p>
<b>函数签名:</b>
```go
func (l *List[T]) Intersection(other *List[T]) *List[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
list "github.com/duke-git/lancet/v2/datastructure/list"
)
func main() {
li1 := list.NewList([]int{1, 2, 3, 4})
li2 := list.NewList([]int{4, 5, 6})
li3 := li1.Intersection(li2)
fmt.Println(li3.Data()) //4
}
```

1387
docs/datastructure/queue.md Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

489
docs/datastructure/set.md Normal file
View File

@@ -0,0 +1,489 @@
# Set
Set is a data container, like list, but elements of set is not duplicate.
<div STYLE="page-break-after: always;"></div>
## Source
- [https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go](https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go)
<div STYLE="page-break-after: always;"></div>
## Usage
```go
import (
set "github.com/duke-git/lancet/v2/datastructure/set"
)
```
<div STYLE="page-break-after: always;"></div>
## Index
- [NewSet](#NewSet)
- [Values](#Values)
- [Add](#Add)
- [Delete](#Delete)
- [Contain](#Contain)
- [ContainAll](#ContainAll)
- [Clone](#Clone)
- [Size](#Size)
- [Equal](#Equal)
- [Iterate](#Iterate)
- [IsEmpty](#IsEmpty)
- [Union](#Union)
- [Intersection](#Intersection)
- [SymmetricDifference](#SymmetricDifference)
- [Minus](#Minus)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="NewSet">NewSet</span>
<p>Make a Set instance</p>
<b>Signature:</b>
```go
type Set[T comparable] map[T]bool
func NewSet[T comparable](values ...T) Set[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
st := set.NewSet[int](1,2,2,3)
fmt.Println(st.Values()) //1,2,3
}
```
### <span id="Values">Values</span>
<p>Return slice of all set data</p>
<b>Signature:</b>
```go
func (s Set[T]) Values() []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
st := set.NewSet[int](1,2,2,3)
fmt.Println(st.Values()) //1,2,3
}
```
### <span id="Add">Add</span>
<p>Add value to set</p>
<b>Signature:</b>
```go
func (s Set[T]) Add(values ...T)
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
st := set.NewSet[int]()
st.Add(1, 2, 3)
fmt.Println(st.Values()) //1,2,3
}
```
### <span id="Delete">Delete</span>
<p>Delete value in set</p>
<b>Signature:</b>
```go
func (s Set[T]) Delete(values ...T)
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
st := set.NewSet[int]()
st.Add(1, 2, 3)
set.Delete(3)
fmt.Println(st.Values()) //1,2
}
```
### <span id="Contain">Contain</span>
<p>Check if value is in set or not</p>
<b>Signature:</b>
```go
func (s Set[T]) Contain(value T) bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
st := set.NewSet[int]()
st.Add(1, 2, 3)
fmt.Println(st.Contain(1)) //true
fmt.Println(st.Contain(4)) //false
}
```
### <span id="ContainAll">ContainAll</span>
<p>Checks if set contains another set</p>
<b>Signature:</b>
```go
func (s Set[T]) ContainAll(other Set[T]) bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet(1, 2)
set3 := set.NewSet(1, 2, 3, 4)
fmt.Println(set1.ContainAll(set2)) //true
fmt.Println(set1.ContainAll(set3)) //false
}
```
### <span id="Size">Size</span>
<p>Get the number of elements in set</p>
<b>Signature:</b>
```go
func (s Set[T]) Size() int
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
fmt.Println(set1.Size()) //3
}
```
### <span id="Clone">Clone</span>
<p>Make a copy of set</p>
<b>Signature:</b>
```go
func (s Set[T]) Clone() Set[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set1.Clone()
fmt.Println(set1.Size() == set2.Size()) //true
fmt.Println(set1.ContainAll(set2)) //true
}
```
### <span id="Equal">Equal</span>
<p>Check if two sets has same elements or not</p>
<b>Signature:</b>
```go
func (s Set[T]) Equal(other Set[T]) bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet(1, 2, 3)
set3 := set.NewSet(1, 2, 3, 4)
fmt.Println(set1.Equal(set2)) //true
fmt.Println(set1.Equal(set3)) //false
}
```
### <span id="Iterate">Iterate</span>
<p>Call function by every element of set</p>
<b>Signature:</b>
```go
func (s Set[T]) Iterate(fn func(value T))
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
arr := []int{}
set.Iterate(func(value int) {
arr = append(arr, value)
})
fmt.Println(arr) //1,2,3
}
```
### <span id="IsEmpty">IsEmpty</span>
<p>Check if the set is empty or not</p>
<b>Signature:</b>
```go
func (s Set[T]) IsEmpty() bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet()
fmt.Println(set1.IsEmpty()) //false
fmt.Println(set2.IsEmpty()) //true
}
```
### <span id="Union">Union</span>
<p>Create a new set contain all element of set s and other</p>
<b>Signature:</b>
```go
func (s Set[T]) Union(other Set[T]) Set[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet(2, 3, 4, 5)
set3 := set1.Union(set2)
fmt.Println(set3.Values()) //1,2,3,4,5
}
```
### <span id="Intersection">Intersection</span>
<p>Create a new set whose element both be contained in set s and other</p>
<b>Signature:</b>
```go
func (s Set[T]) Intersection(other Set[T]) Set[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet(2, 3, 4, 5)
set3 := set1.Intersection(set2)
fmt.Println(set3.Values()) //2,3
}
```
### <span id="SymmetricDifference">SymmetricDifference</span>
<p>Create a new set whose element is in set1 or set2, but not in both set1 and set2</p>
<b>Signature:</b>
```go
func (s Set[T]) SymmetricDifference(other Set[T]) Set[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet(2, 3, 4, 5)
set3 := set1.SymmetricDifference(set2)
fmt.Println(set3.Values()) //1,4,5
}
```
### <span id="Minus">Minus</span>
<p>Create an set of whose element in origin set but not in compared set</p>
<b>Signature:</b>
```go
func (s Set[T]) Minus(comparedSet Set[T]) Set[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet(2, 3, 4, 5)
set3 := set.NewSet(2, 3)
res1 := set1.Minus(set2)
fmt.Println(res1.Values()) //1
res2 := set2.Minus(set3)
fmt.Println(res2.Values()) //4,5
}
```

View File

@@ -0,0 +1,489 @@
# Set
Set集合数据结构类似列表。Set中元素不重复。
<div STYLE="page-break-after: always;"></div>
## 源码
- [https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go](https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go)
<div STYLE="page-break-after: always;"></div>
## 用法
```go
import (
set "github.com/duke-git/lancet/v2/datastructure/set"
)
```
<div STYLE="page-break-after: always;"></div>
## 目录
- [NewSet](#NewSet)
- [Values](#Values)
- [Add](#Add)
- [Delete](#Delete)
- [Contain](#Contain)
- [ContainAll](#ContainAll)
- [Clone](#Clone)
- [Size](#Size)
- [Equal](#Equal)
- [Iterate](#Iterate)
- [IsEmpty](#IsEmpty)
- [Union](#Union)
- [Intersection](#Intersection)
- [SymmetricDifference](#SymmetricDifference)
- [Minus](#Minus)
<div STYLE="page-break-after: always;"></div>
## 文档
### <span id="NewSet">NewSet</span>
<p>返回Set结构体对象</p>
<b>函数签名:</b>
```go
type Set[T comparable] map[T]bool
func NewSet[T comparable](values ...T) Set[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
st := set.NewSet[int](1,2,2,3)
fmt.Println(st.Values()) //1,2,3
}
```
### <span id="Values">Values</span>
<p>获取集合中所有元素的切片</p>
<b>函数签名:</b>
```go
func (s Set[T]) Values() []T
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
st := set.NewSet[int](1,2,2,3)
fmt.Println(st.Values()) //1,2,3
}
```
### <span id="Add">Add</span>
<p>向集合中添加元素</p>
<b>函数签名:</b>
```go
func (s Set[T]) Add(values ...T)
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
st := set.NewSet[int]()
st.Add(1, 2, 3)
fmt.Println(st.Values()) //1,2,3
}
```
### <span id="Delete">Delete</span>
<p>删除集合中元素</p>
<b>函数签名:</b>
```go
func (s Set[T]) Delete(values ...T)
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
st := set.NewSet[int]()
st.Add(1, 2, 3)
set.Delete(3)
fmt.Println(st.Values()) //1,2
}
```
### <span id="Contain">Contain</span>
<p>判断集合是否包含某个值</p>
<b>函数签名:</b>
```go
func (s Set[T]) Contain(value T) bool
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
st := set.NewSet[int]()
st.Add(1, 2, 3)
fmt.Println(st.Contain(1)) //true
fmt.Println(st.Contain(4)) //false
}
```
### <span id="ContainAll">ContainAll</span>
<p>判断集合是否包含另一个集合</p>
<b>函数签名:</b>
```go
func (s Set[T]) ContainAll(other Set[T]) bool
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet(1, 2)
set3 := set.NewSet(1, 2, 3, 4)
fmt.Println(set1.ContainAll(set2)) //true
fmt.Println(set1.ContainAll(set3)) //false
}
```
### <span id="Size">Size</span>
<p>获取集合中元素的个数</p>
<b>函数签名:</b>
```go
func (s Set[T]) Size() int
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
fmt.Println(set1.Size()) //3
}
```
### <span id="Clone">Clone</span>
<p>克隆一个集合</p>
<b>函数签名:</b>
```go
func (s Set[T]) Clone() Set[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set1.Clone()
fmt.Println(set1.Size() == set2.Size()) //true
fmt.Println(set1.ContainAll(set2)) //true
}
```
### <span id="Equal">Equal</span>
<p>比较两个集合是否相等,包含相同元素为相等</p>
<b>函数签名:</b>
```go
func (s Set[T]) Equal(other Set[T]) bool
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet(1, 2, 3)
set3 := set.NewSet(1, 2, 3, 4)
fmt.Println(set1.Equal(set2)) //true
fmt.Println(set1.Equal(set3)) //false
}
```
### <span id="Iterate">Iterate</span>
<p>迭代结合,在每个元素上调用函数</p>
<b>函数签名:</b>
```go
func (s Set[T]) Iterate(fn func(value T))
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
arr := []int{}
set.Iterate(func(value int) {
arr = append(arr, value)
})
fmt.Println(arr) //1,2,3
}
```
### <span id="IsEmpty">IsEmpty</span>
<p>判断集合是否为空</p>
<b>函数签名:</b>
```go
func (s Set[T]) IsEmpty() bool
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet()
fmt.Println(set1.IsEmpty()) //false
fmt.Println(set2.IsEmpty()) //true
}
```
### <span id="Union">Union</span>
<p>求两个集合的并集</p>
<b>函数签名:</b>
```go
func (s Set[T]) Union(other Set[T]) Set[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet(2, 3, 4, 5)
set3 := set1.Union(set2)
fmt.Println(set3.Values()) //1,2,3,4,5
}
```
### <span id="Intersection">Intersection</span>
<p>求两个集合的交集</p>
<b>函数签名:</b>
```go
func (s Set[T]) Intersection(other Set[T]) Set[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet(2, 3, 4, 5)
set3 := set1.Intersection(set2)
fmt.Println(set3.Values()) //2,3
}
```
### <span id="SymmetricDifference">SymmetricDifference</span>
<p>返回一个集合,其中元素在第一个集合或第二个集合中,且不同时存在于两个集合中</p>
<b>函数签名:</b>
```go
func (s Set[T]) SymmetricDifference(other Set[T]) Set[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet(2, 3, 4, 5)
set3 := set1.SymmetricDifference(set2)
fmt.Println(set3.Values()) //1,4,5
}
```
### <span id="Minus">Minus</span>
<p>创建一个集合,其元素在原始集中但不在比较集中</p>
<b>函数签名:</b>
```go
func (s Set[T]) Minus(comparedSet Set[T]) Set[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
set "github.com/duke-git/lancet/v2/datastructure/set"
)
func main() {
set1 := set.NewSet(1, 2, 3)
set2 := set.NewSet(2, 3, 4, 5)
set3 := set.NewSet(2, 3)
res1 := set1.Minus(set2)
fmt.Println(res1.Values()) //1
res2 := set2.Minus(set3)
fmt.Println(res2.Values()) //4,5
}
```

611
docs/datastructure/stack.md Normal file
View File

@@ -0,0 +1,611 @@
# Stack
Stack is an abstract data type that serves as a collection of elements. Elements follow the LIFO principle. FIFO is last-in, first-out, meaning that the most recently produced items are recorded as sold first.
<div STYLE="page-break-after: always;"></div>
## Source
- [https://github.com/duke-git/lancet/blob/main/datastructure/stack/arraystack.go](https://github.com/duke-git/lancet/blob/main/datastructure/stack/arraystack.go)
- [https://github.com/duke-git/lancet/blob/main/datastructure/stack/linkedstack.go](https://github.com/duke-git/lancet/blob/main/datastructure/stack/linkedstack.go)
<div STYLE="page-break-after: always;"></div>
## Usage
```go
import (
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
```
<div STYLE="page-break-after: always;"></div>
## Index
### 1. ArrayStack
- [NewArrayStack](#NewArrayStack)
- [Push](#ArrayStack_Push)
- [Pop](#ArrayStack_Pop)
- [Peak](#ArrayStack_Peak)
- [Data](#ArrayStack_Data)
- [Size](#ArrayStack_Size)
- [IsEmpty](#ArrayStack_IsEmpty)
- [Clear](#ArrayStack_Clear)
### 2. LinkedStack
- [NewLinkedStack](#NewLinkedStack)
- [Push](#LinkedStack_Push)
- [Pop](#LinkedStack_Pop)
- [Peak](#LinkedStack_Peak)
- [Data](#LinkedStack_Data)
- [Size](#LinkedStack_Size)
- [IsEmpty](#LinkedStack_IsEmpty)
- [Clear](#LinkedStack_Clear)
- [Print](#LinkedStack_Print)
<div STYLE="page-break-after: always;"></div>
## Documentation
### 1. ArrayStack
ArrayStack is a stack implemented by slice.
### <span id="NewArrayStack">NewArrayStack</span>
<p>Return a empty ArrayStack pointer</p>
<b>Signature:</b>
```go
type ArrayStack[T any] struct {
data []T
length int
}
func NewArrayStack[T any]() *ArrayStack[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
fmt.Println(sk)
}
```
### <span id="ArrayStack_Push">Push</span>
<p>Push element into array stack</p>
<b>Signature:</b>
```go
func (s *ArrayStack[T]) Push(value T)
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.Data()) //[]int{3, 2, 1}
}
```
### <span id="ArrayStack_Pop">Pop</span>
<p>Delete the top element of stack then return it, if stack is empty, return nil and error</p>
<b>Signature:</b>
```go
func (s *ArrayStack[T]) Pop() (*T, error)
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
val, err := sk.Pop()
fmt.Println(err) //nil
fmt.Println(*val) //3
fmt.Println(sk.Data()) //[]int{2, 1}
}
```
### <span id="ArrayStack_Peak">Peak</span>
<p>Return the top element of array stack</p>
<b>Signature:</b>
```go
func (s *ArrayStack[T]) Peak() (*T, error)
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
val, err := sk.Peak()
fmt.Println(err) //nil
fmt.Println(*val) //3
fmt.Println(sk.Data()) //[]int{3, 2, 1}
}
```
### <span id="ArrayStack_Data">Data</span>
<p>Return a slice of all data in array stack</p>
<b>Signature:</b>
```go
func (s *ArrayStack[T]) Data() []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.Data()) //[]int{3, 2, 1}
}
```
### <span id="ArrayStack_Size">Size</span>
<p>Return number of elements in array stack</p>
<b>Signature:</b>
```go
func (s *ArrayStack[T]) Size() int
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.Size()) //3
}
```
### <span id="ArrayStack_IsEmpty">IsEmpty</span>
<p>Check if array stack is empty or not</p>
<b>Signature:</b>
```go
func (s *ArrayStack[T]) IsEmpty() bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
fmt.Println(sk.IsEmpty()) //true
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.IsEmpty()) //false
}
```
### <span id="ArrayStack_Clear">Clear</span>
<p>Clear all elments in array stack</p>
<b>Signature:</b>
```go
func (s *ArrayStack[T]) Clear()
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
sk.Clear()
fmt.Println(sk.Data()) //[]int{}
}
```
### 2. LinkedStack
LinkedStack is a stack implemented by linked list.
### <span id="NewLinkedStack">NewLinkedStack</span>
<p>Return a empty LinkedStack pointer</p>
<b>Signature:</b>
```go
type StackNode[T any] struct {
Value T
Next *StackNode[T]
}
type LinkedStack[T any] struct {
top *datastructure.StackNode[T]
length int
}
func NewLinkedStack[T any]() *LinkedStack[T]
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
fmt.Println(sk)
}
```
### <span id="LinkedStack_Push">Push</span>
<p>Push element into linked stack</p>
<b>Signature:</b>
```go
func (s *LinkedStack[T]) Push(value T)
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.Data()) //[]int{3, 2, 1}
}
```
### <span id="LinkedStack_Pop">Pop</span>
<p>Delete the top element of stack then return it, if stack is empty, return nil and error</p>
<b>Signature:</b>
```go
func (s *LinkedStack[T]) Pop() (*T, error)
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
val, err := sk.Pop()
fmt.Println(err) //nil
fmt.Println(*val) //3
fmt.Println(sk.Data()) //[]int{2, 1}
}
```
### <span id="LinkedStack_Peak">Peak</span>
<p>Return the top element of linked stack</p>
<b>Signature:</b>
```go
func (s *LinkedStack[T]) Peak() (*T, error)
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
val, err := sk.Peak()
fmt.Println(err) //nil
fmt.Println(*val) //3
fmt.Println(sk.Data()) //[]int{3, 2, 1}
}
```
### <span id="LinkedStack_Data">Data</span>
<p>Return a slice of all data in linked stack</p>
<b>Signature:</b>
```go
func (s *LinkedStack[T]) Data() []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.Data()) //[]int{3, 2, 1}
}
```
### <span id="LinkedStack_Size">Size</span>
<p>Return number of elements in linked stack</p>
<b>Signature:</b>
```go
func (s *LinkedStack[T]) Size() int
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.Size()) //3
}
```
### <span id="LinkedStack_IsEmpty">IsEmpty</span>
<p>Check if linked stack is empty or not</p>
<b>Signature:</b>
```go
func (s *LinkedStack[T]) IsEmpty() bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
fmt.Println(sk.IsEmpty()) //true
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.IsEmpty()) //false
}
```
### <span id="LinkedStack_Clear">Clear</span>
<p>Clear all elments in linked stack</p>
<b>Signature:</b>
```go
func (s *LinkedStack[T]) Clear()
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
sk.Clear()
fmt.Println(sk.Data()) //[]int{}
}
```
### <span id="LinkedStack_Print">Print</span>
<p>Print the structure of a linked stack</p>
<b>Signature:</b>
```go
func (s *LinkedStack[T]) Print()
```
<b>Example:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
sk.Print() //[ &{Value:3 Next:0xc000010260}, &{Value:2 Next:0xc000010250}, &{Value:1 Next:<nil>}, ]
}
```

View File

@@ -0,0 +1,611 @@
# Stack
栈数据结构包括ArrayStack数组栈和LinkedStack链表栈
<div STYLE="page-break-after: always;"></div>
## 源码
- [https://github.com/duke-git/lancet/blob/main/datastructure/stack/arraystack.go](https://github.com/duke-git/lancet/blob/main/datastructure/stack/arraystack.go)
- [https://github.com/duke-git/lancet/blob/main/datastructure/stack/linkedstack.go](https://github.com/duke-git/lancet/blob/main/datastructure/stack/linkedstack.go)
<div STYLE="page-break-after: always;"></div>
## 用法
```go
import (
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
```
<div STYLE="page-break-after: always;"></div>
## 目录
### 1. ArrayStack数组栈
- [NewArrayStack](#NewArrayStack)
- [Push](#ArrayStack_Push)
- [Pop](#ArrayStack_Pop)
- [Peak](#ArrayStack_Peak)
- [Data](#ArrayStack_Data)
- [Size](#ArrayStack_Size)
- [IsEmpty](#ArrayStack_IsEmpty)
- [Clear](#ArrayStack_Clear)
### 2. LinkedStack链表栈
- [NewLinkedStack](#NewLinkedStack)
- [Push](#LinkedStack_Push)
- [Pop](#LinkedStack_Pop)
- [Peak](#LinkedStack_Peak)
- [Data](#LinkedStack_Data)
- [Size](#LinkedStack_Size)
- [IsEmpty](#LinkedStack_IsEmpty)
- [Clear](#LinkedStack_Clear)
- [Print](#LinkedStack_Print)
<div STYLE="page-break-after: always;"></div>
## 文档
### 1. ArrayStack
用切片实现栈结构
### <span id="NewArrayStack">NewArrayStack</span>
<p>返回ArrayStack指针实例</p>
<b>函数签名:</b>
```go
type ArrayStack[T any] struct {
data []T
length int
}
func NewArrayStack[T any]() *ArrayStack[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
fmt.Println(sk)
}
```
### <span id="ArrayStack_Push">Push</span>
<p>将元素加入数组栈</p>
<b>函数签名:</b>
```go
func (s *ArrayStack[T]) Push(value T)
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.Data()) //[]int{3, 2, 1}
}
```
### <span id="ArrayStack_Pop">Pop</span>
<p>删除栈顶元素并返回该元素指针</p>
<b>函数签名:</b>
```go
func (s *ArrayStack[T]) Pop() (*T, error)
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
val, err := sk.Pop()
fmt.Println(err) //nil
fmt.Println(*val) //3
fmt.Println(sk.Data()) //[]int{2, 1}
}
```
### <span id="ArrayStack_Peak">Peak</span>
<p>返回栈顶元素指针</p>
<b>函数签名:</b>
```go
func (s *ArrayStack[T]) Peak() (*T, error)
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
val, err := sk.Peak()
fmt.Println(err) //nil
fmt.Println(*val) //3
fmt.Println(sk.Data()) //[]int{3, 2, 1}
}
```
### <span id="ArrayStack_Data">Data</span>
<p>返回栈中所有元素组成的切片</p>
<b>函数签名:</b>
```go
func (s *ArrayStack[T]) Data() []T
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.Data()) //[]int{3, 2, 1}
}
```
### <span id="ArrayStack_Size">Size</span>
<p>返回栈中元素的数量</p>
<b>函数签名:</b>
```go
func (s *ArrayStack[T]) Size() int
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.Size()) //3
}
```
### <span id="ArrayStack_IsEmpty">IsEmpty</span>
<p>判断栈是否为空</p>
<b>函数签名:</b>
```go
func (s *ArrayStack[T]) IsEmpty() bool
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
fmt.Println(sk.IsEmpty()) //true
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.IsEmpty()) //false
}
```
### <span id="ArrayStack_Clear">Clear</span>
<p>清空栈元素,使栈为空</p>
<b>函数签名:</b>
```go
func (s *ArrayStack[T]) Clear()
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewArrayStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
sk.Clear()
fmt.Println(sk.Data()) //[]int{}
}
```
### 2. LinkedStack
链表实现的栈结构。
### <span id="NewLinkedStack">NewLinkedStack</span>
<p>返回LinkedStack指针实例</p>
<b>函数签名:</b>
```go
type StackNode[T any] struct {
Value T
Next *StackNode[T]
}
type LinkedStack[T any] struct {
top *datastructure.StackNode[T]
length int
}
func NewLinkedStack[T any]() *LinkedStack[T]
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
fmt.Println(sk)
}
```
### <span id="LinkedStack_Push">Push</span>
<p>将元素加入链表栈</p>
<b>函数签名:</b>
```go
func (s *LinkedStack[T]) Push(value T)
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.Data()) //[]int{3, 2, 1}
}
```
### <span id="LinkedStack_Pop">Pop</span>
<p>删除栈顶元素并返回该元素指针</p>
<b>函数签名:</b>
```go
func (s *LinkedStack[T]) Pop() (*T, error)
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
val, err := sk.Pop()
fmt.Println(err) //nil
fmt.Println(*val) //3
fmt.Println(sk.Data()) //[]int{2, 1}
}
```
### <span id="LinkedStack_Peak">Peak</span>
<p>返回栈顶元素指针</p>
<b>函数签名:</b>
```go
func (s *LinkedStack[T]) Peak() (*T, error)
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
val, err := sk.Peak()
fmt.Println(err) //nil
fmt.Println(*val) //3
fmt.Println(sk.Data()) //[]int{3, 2, 1}
}
```
### <span id="LinkedStack_Data">Data</span>
<p>返回栈中所有元素组成的切片</p>
<b>函数签名:</b>
```go
func (s *LinkedStack[T]) Data() []T
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.Data()) //[]int{3, 2, 1}
}
```
### <span id="LinkedStack_Size">Size</span>
<p>返回栈中元素的数量</p>
<b>函数签名:</b>
```go
func (s *LinkedStack[T]) Size() int
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.Size()) //3
}
```
### <span id="LinkedStack_IsEmpty">IsEmpty</span>
<p>判断栈是否为空</p>
<b>函数签名:</b>
```go
func (s *LinkedStack[T]) IsEmpty() bool
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
fmt.Println(sk.IsEmpty()) //true
sk.Push(1)
sk.Push(2)
sk.Push(3)
fmt.Println(sk.IsEmpty()) //false
}
```
### <span id="LinkedStack_Clear">Clear</span>
<p>清空栈元素,使栈为空</p>
<b>函数签名:</b>
```go
func (s *LinkedStack[T]) Clear()
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
sk.Clear()
fmt.Println(sk.Data()) //[]int{}
}
```
### <span id="LinkedStack_Print">Print</span>
<p>打印链表栈结构</p>
<b>函数签名:</b>
```go
func (s *LinkedStack[T]) Print()
```
<b>例子:</b>
```go
package main
import (
"fmt"
stack "github.com/duke-git/lancet/v2/datastructure/stack"
)
func main() {
sk := stack.NewLinkedStack[int]()
sk.Push(1)
sk.Push(2)
sk.Push(3)
sk.Print() //[ &{Value:3 Next:0xc000010260}, &{Value:2 Next:0xc000010250}, &{Value:1 Next:<nil>}, ]
}
```

527
docs/datastructure/tree.md Normal file
View File

@@ -0,0 +1,527 @@
# Tree
Tree is a collection of tree nodes. Each tree node has a value, a left pointer point to left node and a right pointer point to right node.
<div STYLE="page-break-after: always;"></div>
## Source
- [https://github.com/duke-git/lancet/blob/main/datastructure/tree/bstree.go](https://github.com/duke-git/lancet/blob/main/datastructure/tree/bstree.go)
<div STYLE="page-break-after: always;"></div>
## Usage
```go
import (
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
```
<div STYLE="page-break-after: always;"></div>
## Index
### 1. BSTree
- [NewBSTree](#NewBSTree)
- [Insert](#BSTree_Insert)
- [Delete](#BSTree_Delete)
- [PreOrderTraverse](#BSTree_PreOrderTraverse)
- [InOrderTraverse](#BSTree_InOrderTraverse)
- [PostOrderTraverse](#BSTree_PostOrderTraverse)
- [LevelOrderTraverse](#BSTree_LevelOrderTraverse)
- [Depth](#BSTree_Depth)
- [HasSubTree](#BSTree_HasSubTree)
- [Print](#BSTree_Print)
<div STYLE="page-break-after: always;"></div>
## Documentation
## 1. BSTree
BSTree is a binary search tree data structure in which each node has at 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.
### <span id="NewBSTree">NewBSTree</span>
<p>Make a BSTree pointer instance</p>
<b>Signature:</b>
```go
func NewBSTree[T any](rootData T, comparator lancetconstraints.Comparator) *BSTree[T]
type BSTree[T any] struct {
root *datastructure.TreeNode[T]
comparator lancetconstraints.Comparator
}
type TreeNode[T any] struct {
Value T
Left *TreeNode[T]
Right *TreeNode[T]
}
```
<b>Example:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
fmt.Println(bstree) //
}
```
### <span id="BSTree_Insert">Insert</span>
<p>Insert value into binary search tree</p>
<b>Signature:</b>
```go
func (t *BSTree[T]) Insert(data T)
```
<b>Example:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.PreOrderTraverse()) //6, 5, 2, 4, 7
}
```
### <span id="BSTree_Delete">Delete</span>
<p>Delete value of binary search tree</p>
<b>Signature:</b>
```go
func (t *BSTree[T]) Delete(data T)
```
<b>Example:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
bstree.Delete(4)
fmt.Println(bstree.PreOrderTraverse()) //2, 5, 6, 7
}
```
### <span id="BSTree_PreOrderTraverse">PreOrderTraverse</span>
<p>Traverse tree nodes in pre order</p>
<b>Signature:</b>
```go
func (t *BSTree[T]) PreOrderTraverse() []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.PreOrderTraverse()) //6, 5, 2, 4, 7
}
```
### <span id="BSTree_InOrderTraverse">InOrderTraverse</span>
<p>Traverse tree nodes in middle order</p>
<b>Signature:</b>
```go
func (t *BSTree[T]) InOrderTraverse() []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.InOrderTraverse()) //2, 4, 5, 6, 7
}
```
### <span id="BSTree_PostOrderTraverse">PostOrderTraverse</span>
<p>Traverse tree nodes in post order</p>
<b>Signature:</b>
```go
func (t *BSTree[T]) PostOrderTraverse() []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.PostOrderTraverse()) //5, 2, 4, 7, 6
}
```
### <span id="BSTree_LevelOrderTraverse">LevelOrderTraverse</span>
<p>Traverse tree nodes in node level order</p>
<b>Signature:</b>
```go
func (t *BSTree[T]) LevelOrderTraverse() []T
```
<b>Example:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.LevelOrderTraverse()) //6, 5, 7, 2, 4
}
```
### <span id="BSTree_Depth">Depth</span>
<p>Get the depth of a binary saerch tree</p>
<b>Signature:</b>
```go
func (t *BSTree[T]) Depth() int
```
<b>Example:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.Depth()) //4
}
```
### <span id="BSTree_HasSubTree">HasSubTree</span>
<p>Check if the given tree is sub tree of origin tree or not</p>
<b>Signature:</b>
```go
func (t *BSTree[T]) HasSubTree(subTree *BSTree[T]) bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
superTree := tree.NewBSTree(8, &intComparator{})
superTree.Insert(4)
superTree.Insert(5)
superTree.Insert(6)
superTree.Insert(9)
superTree.Insert(4)
subTree := tree.NewBSTree(5, &intComparator{})
subTree.Insert(4)
subTree.Insert(6)
fmt.Println(superTree.HasSubTree(subTree)) //true
fmt.Println(subTree.HasSubTree(superTree)) //false
}
```
### <span id="BSTree_Print">Print</span>
<p>Print the structure of binary saerch tree</p>
<b>Signature:</b>
```go
func (t *BSTree[T]) Print()
```
<b>Example:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.Print())
// 6
// / \
// / \
// / \
// / \
// 5 7
// /
// /
// 2
// \
// 4
}
```

View File

@@ -0,0 +1,527 @@
# Tree
树是树节点的集合。 每个树节点都有一个值,一个指向左节点的左指针和一个指向右节点的右指针。
<div STYLE="page-break-after: always;"></div>
## 源码
- [https://github.com/duke-git/lancet/blob/main/datastructure/tree/bstree.go](https://github.com/duke-git/lancet/blob/main/datastructure/tree/bstree.go)
<div STYLE="page-break-after: always;"></div>
## 用法
```go
import (
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
```
<div STYLE="page-break-after: always;"></div>
## 目录
### 1. BSTree
- [NewBSTree](#NewBSTree)
- [Insert](#BSTree_Insert)
- [Delete](#BSTree_Delete)
- [PreOrderTraverse](#BSTree_PreOrderTraverse)
- [InOrderTraverse](#BSTree_InOrderTraverse)
- [PostOrderTraverse](#BSTree_PostOrderTraverse)
- [LevelOrderTraverse](#BSTree_LevelOrderTraverse)
- [Depth](#BSTree_Depth)
- [HasSubTree](#BSTree_HasSubTree)
- [Print](#BSTree_Print)
<div STYLE="page-break-after: always;"></div>
## 文档
## 1. BSTree
BSTree是一种二叉搜索树数据结构其中每个节点有两个孩子分别称为左孩子和右孩子。 在 BSTree 中leftNode < rootNode < rightNode。 T类型应该实现lancetconstraints.Comparator。
### <span id="NewBSTree">NewBSTree</span>
<p>返回BSTree指针实例</p>
<b>函数签名:</b>
```go
func NewBSTree[T any](rootData T, comparator lancetconstraints.Comparator) *BSTree[T]
type BSTree[T any] struct {
root *datastructure.TreeNode[T]
comparator lancetconstraints.Comparator
}
type TreeNode[T any] struct {
Value T
Left *TreeNode[T]
Right *TreeNode[T]
}
```
<b>例子:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
fmt.Println(bstree) //
}
```
### <span id="BSTree_Insert">Insert</span>
<p>将值插入二叉搜索树</p>
<b>函数签名:</b>
```go
func (t *BSTree[T]) Insert(data T)
```
<b>例子:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.PreOrderTraverse()) //6, 5, 2, 4, 7
}
```
### <span id="BSTree_Delete">Delete</span>
<p>删除插入二叉搜索树中指定的值</p>
<b>函数签名:</b>
```go
func (t *BSTree[T]) Delete(data T)
```
<b>例子:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
bstree.Delete(4)
fmt.Println(bstree.PreOrderTraverse()) //2, 5, 6, 7
}
```
### <span id="BSTree_PreOrderTraverse">PreOrderTraverse</span>
<p>按前序遍历树节点</p>
<b>函数签名:</b>
```go
func (t *BSTree[T]) PreOrderTraverse() []T
```
<b>例子:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.PreOrderTraverse()) //6, 5, 2, 4, 7
}
```
### <span id="BSTree_InOrderTraverse">InOrderTraverse</span>
<p>按中序遍历树节点</p>
<b>函数签名:</b>
```go
func (t *BSTree[T]) InOrderTraverse() []T
```
<b>例子:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.InOrderTraverse()) //2, 4, 5, 6, 7
}
```
### <span id="BSTree_PostOrderTraverse">PostOrderTraverse</span>
<p>按后序遍历树节点</p>
<b>函数签名:</b>
```go
func (t *BSTree[T]) PostOrderTraverse() []T
```
<b>例子:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.PostOrderTraverse()) //5, 2, 4, 7, 6
}
```
### <span id="BSTree_LevelOrderTraverse">LevelOrderTraverse</span>
<p>按节点层次遍历树节点</p>
<b>函数签名:</b>
```go
func (t *BSTree[T]) LevelOrderTraverse() []T
```
<b>例子:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.LevelOrderTraverse()) //6, 5, 7, 2, 4
}
```
### <span id="BSTree_Depth">Depth</span>
<p>获取树的深度</p>
<b>函数签名:</b>
```go
func (t *BSTree[T]) Depth() int
```
<b>例子:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.Depth()) //4
}
```
### <span id="BSTree_HasSubTree">HasSubTree</span>
<p>判断给定树是否是子树</p>
<b>函数签名:</b>
```go
func (t *BSTree[T]) HasSubTree(subTree *BSTree[T]) bool
```
<b>例子:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
superTree := tree.NewBSTree(8, &intComparator{})
superTree.Insert(4)
superTree.Insert(5)
superTree.Insert(6)
superTree.Insert(9)
superTree.Insert(4)
subTree := tree.NewBSTree(5, &intComparator{})
subTree.Insert(4)
subTree.Insert(6)
fmt.Println(superTree.HasSubTree(subTree)) //true
fmt.Println(subTree.HasSubTree(superTree)) //false
}
```
### <span id="BSTree_Print">Print</span>
<p>打印树结构</p>
<b>函数签名:</b>
```go
func (t *BSTree[T]) Print()
```
<b>例子:</b>
```go
package main
import (
"fmt"
tree "github.com/duke-git/lancet/v2/datastructure/tree"
)
type intComparator struct{}
func (c *intComparator) Compare(v1, v2 any) int {
val1, _ := v1.(int)
val2, _ := v2.(int)
if val1 < val2 {
return -1
} else if val1 > val2 {
return 1
}
return 0
}
func main() {
bstree := tree.NewBSTree(6, &intComparator{})
bstree.Insert(7)
bstree.Insert(5)
bstree.Insert(2)
bstree.Insert(4)
fmt.Println(bstree.Print())
// 6
// / \
// / \
// / \
// / \
// 5 7
// /
// /
// 2
// \
// 4
}
```

View File

@@ -21,18 +21,20 @@ import (
## Index
- [ClearFile](#ClearFile)
- [CreateFile](#CreateFile)
- [CreateDir](#CreateDir)
- [CopyFile](#CopyFile)
- [FileMode](#FileMode)
- [MiMeType](#MiMeType)
- [IsExist](#IsExist)
- [IsLink](#IsLink)
- [IsDir](#IsDir)
- [ListFileNames](#ListFileNames)
- [RemoveFile](#RemoveFile)
- [ReadFileToString](#ReadFileToString)
- [ReadFileByLine](#ReadFileByLine)
- [Zip](#Zip)
- [UnZip](#UnZip)
- [UnZip](#UnZip)
<div STYLE="page-break-after: always;"></div>
@@ -92,6 +94,32 @@ func main() {
```
### <span id="CreateDir">CreateDir</span>
<p>Create directory in absolute path. param `absPath` like /a/, /a/b/.</p>
<b>Signature:</b>
```go
func CreateDir(absPath string) error
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/fileutil"
)
func main() {
err := fileutil.CreateDir("/a/")
fmt.Println(err)
}
```
### <span id="CopyFile">CopyFile</span>
<p>Copy src file to dest file. If dest file exist will overwrite it.</p>

View File

@@ -21,6 +21,7 @@ import (
## 目录
- [ClearFile](#ClearFile)
- [CreateFile](#CreateFile)
- [CreateDir](#CreateDir)
- [CopyFile](#CopyFile)
- [FileMode](#FileMode)
- [MiMeType](#MiMeType)
@@ -92,6 +93,32 @@ func main() {
```
### <span id="CreateDir">CreateDir</span>
<p>使用绝对路径创建嵌套目录,例如/a/, /a/b/</p>
<b>函数签名:</b>
```go
func CreateDir(absPath string) error
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/fileutil"
)
func main() {
err := fileutil.CreateDir("/a/")
fmt.Println(err)
}
```
### <span id="CopyFile">CopyFile</span>
<p>拷贝文件,会覆盖原有的拷贝文件</p>

View File

@@ -31,6 +31,8 @@ import (
- [DifferenceWith](#DifferenceWith)
- [DeleteAt](#DeleteAt)
- [Drop](#Drop)
- [Equal](#Equal)
- [EqualWith](#EqualWith)
- [Every](#Every)
- [Filter](#Filter)
- [Find](#Find)
@@ -55,6 +57,7 @@ import (
- [StringSlice](#StringSlice)
- [SymmetricDifference](#SymmetricDifference)
- [Unique](#Unique)
- [UniqueBy](#UniqueBy)
- [Union](#Union)
- [UpdateAt](#UpdateAt)
- [Without](#Without)
@@ -250,7 +253,7 @@ func main() {
<b>Signature:</b>
```go
func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, t T) T) []T
func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T
```
<b>Example:</b>
@@ -360,6 +363,68 @@ func main() {
### <span id="Equal">Equal</span>
<p>Check if two slices are equal: the same length and all elements' order and value are equal.</p>
<b>Signature:</b>
```go
func Equal[T comparable](slice1, slice2 []T) bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}
slice3 := []int{3, 2, 1}
res1 := slice.Equal(slice1, slice2)
res2 := slice.Equal(slice1, slice3)
fmt.Println(res1) //true
fmt.Println(res2) //false
}
```
### <span id="EqualWith">EqualWith</span>
<p>Check if two slices are equal with comparator func.</p>
<b>Signature:</b>
```go
func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{2, 4, 6}
isDouble := func(a, b int) bool {
return b == a*2
}
res := slice.EqualWith(slice1, slice2, isDouble)
fmt.Println(res) //true
}
```
### <span id="Every">Every</span>
<p>Return true if all of the values in the slice pass the predicate function.</p>
@@ -367,7 +432,7 @@ func main() {
<b>Signature:</b>
```go
func Every[T any](slice []T, predicate func(index int, t T) bool) bool
func Every[T any](slice []T, predicate func(index int, item T) bool) bool
```
<b>Example:</b>
@@ -397,7 +462,7 @@ func main() {
<b>Signature:</b>
```go
func Filter[T any](slice []T, predicate func(index int, t T) bool) []T
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T
```
<b>Example:</b>
@@ -426,7 +491,7 @@ func main() {
<b>Signature:</b>
```go
func Find[T any](slice []T, predicate func(index int, t T) bool) (*T, bool)
func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
```
<b>Example:</b>
@@ -457,7 +522,7 @@ func main() {
<b>Signature:</b>
```go
func FindLast[T any](slice []T, predicate func(index int, t T) bool) (*T, bool)
func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
```
<b>Example:</b>
@@ -514,7 +579,7 @@ func main() {
<b>Signature:</b>
```go
func ForEach[T any](slice []T, iteratee func(index int, t T))
func ForEach[T any](slice []T, iteratee func(index int, item T))
```
<b>Example:</b>
@@ -543,7 +608,7 @@ func main() {
<b>Signature:</b>
```go
func GroupBy[T any](slice []T, groupFn func(index int, t T) bool) ([]T, []T)
func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T)
```
<b>Example:</b>
@@ -769,7 +834,7 @@ func main() {
<b>Signature:</b>
```go
func Map[T any, U any](slice []T, iteratee func(index int, t T) U) []U
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U
```
<b>Example:</b>
@@ -823,7 +888,7 @@ func main() {
<b>Signature:</b>
```go
func Reduce[T any](slice []T, iteratee func(index int, t1, t2 T) T, initial T) T
func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T
```
<b>Example:</b>
@@ -920,7 +985,7 @@ func main() {
<b>Signature:</b>
```go
func Some[T any](slice []T, predicate func(index int, t T) bool) bool
func Some[T any](slice []T, predicate func(index int, item T) bool) bool
```
<b>Example:</b>
@@ -1022,7 +1087,33 @@ func main() {
### <span id="Union">Unique</span>
### <span id="UniqueBy">UniqueBy</span>
<p>Call iteratee func with every item of slice, then remove duplicated.</p>
<b>Signature:</b>
```go
func UniqueBy[T any](slice []T, iteratee func(item T) T) []T
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
res := slice.UniqueBy([]int{1, 2, 3, 4, 5, 6}, func(val int) int {
return val % 4
})
fmt.Println(res) //[]int{1, 2, 3, 0}
}
```
### <span id="Union">Union</span>
<p>Creates a slice of unique values, in order, from all given slices. using == for equality comparisons.</p>
<b>Signature:</b>

View File

@@ -32,6 +32,8 @@ import (
- [DeleteAt](#DeleteAt)
- [Drop](#Drop)
- [Every](#Every)
- [Equal](#Equal)
- [EqualWith](#EqualWith)
- [Filter](#Filter)
- [Find](#Find)
- [FindLast](#FindLast)
@@ -55,6 +57,7 @@ import (
- [StringSlice](#StringSlice)
- [SymmetricDifference](#SymmetricDifference)
- [Unique](#Unique)
- [UniqueBy](#UniqueBy)
- [Union](#Union)
- [UpdateAt](#UpdateAt)
- [Without](#Without)
@@ -250,7 +253,7 @@ func main() {
<b>函数签名:</b>
```go
func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, t T) T) []T
func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T
```
<b>例子:</b>
@@ -369,7 +372,7 @@ func main() {
<b>函数签名:</b>
```go
func Every[T any](slice []T, predicate func(index int, t T) bool) bool
func Every[T any](slice []T, predicate func(index int, item T) bool) bool
```
<b>例子:</b>
@@ -393,13 +396,76 @@ func main() {
### <span id="Filter">Filter</span>
<p>返回与函数匹配的所有元素。 函数签名应该是 func(index int, value any) bool</p>
### <span id="Equal">Equal</span>
<p>检查两个切片是否相等,相等条件:切片长度相同,元素顺序和值都相同</p>
<b>函数签名:</b>
```go
func Filter[T any](slice []T, predicate func(index int, t T) bool) []T
func Equal[T comparable](slice1, slice2 []T) bool
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}
slice3 := []int{3, 2, 1}
res1 := slice.Equal(slice1, slice2)
res2 := slice.Equal(slice1, slice3)
fmt.Println(res1) //true
fmt.Println(res2) //false
}
```
### <span id="EqualWith">EqualWith</span>
<p>检查两个切片是否相等相等条件对两个切片的元素调用比较函数comparator返回true</p>
<b>函数签名:</b>
```go
func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{2, 4, 6}
isDouble := func(a, b int) bool {
return b == a*2
}
res := slice.EqualWith(slice1, slice2, isDouble)
fmt.Println(res) //true
}
```
### <span id="Filter">Filter</span>
<p>返回切片中通过predicate函数真值测试的所有元素</p>
<b>函数签名:</b>
```go
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T
```
<b>例子:</b>
@@ -423,12 +489,12 @@ func main() {
### <span id="Find">Find</span>
<p>遍历slice的元素,返回第一个通过function真值测试的元素</p>
<p>遍历切片的元素,返回第一个通过predicate函数真值测试的元素</p>
<b>函数签名:</b>
```go
func Find[T any](slice []T, predicate func(index int, t T) bool) (*T, bool)
func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
```
<b>例子:</b>
@@ -454,12 +520,12 @@ func main() {
### <span id="FindLast">FindLast</span>
<p>从头到尾遍历 slice 的元素,返回最后一个通过函数真值测试的元素。</p>
<p>从头到尾遍历slice的元素返回最后一个通过predicate函数真值测试的元素。</p>
<b>函数签名:</b>
```go
func FindLast[T any](slice []T, predicate func(index int, t T) bool) (*T, bool)
func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
```
<b>例子:</b>
@@ -511,12 +577,12 @@ func main() {
### <span id="ForEach">ForEach</span>
<p>遍历slice的元素并为每个元素调用函数</p>
<p>遍历切片的元素并为每个元素调用iteratee函数</p>
<b>函数签名:</b>
```go
func ForEach[T any](slice []T, iteratee func(index int, t T))
func ForEach[T any](slice []T, iteratee func(index int, item T))
```
<b>例子:</b>
@@ -545,7 +611,7 @@ func main() {
<b>函数签名:</b>
```go
func GroupBy[T any](slice []T, groupFn func(index int, t T) bool) ([]T, []T)
func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T)
```
<b>例子:</b>
@@ -768,7 +834,7 @@ func main() {
<b>函数签名:</b>
```go
func Map[T any, U any](slice []T, iteratee func(index int, t T) U) []U
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U
```
<b>例子:</b>
@@ -817,12 +883,12 @@ func main() {
### <span id="Reduce">Reduce</span>
<p>将slice中的元素依次运行函数,返回运行结果</p>
<p>将切片中的元素依次运行iteratee函数,返回运行结果</p>
<b>函数签名:</b>
```go
func Reduce[T any](slice []T, iteratee func(index int, t1, t2 T) T, initial T) T
func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T
```
<b>例子:</b>
@@ -919,7 +985,7 @@ func main() {
<b>函数签名:</b>
```go
func Some[T any](slice []T, predicate func(index int, t T) bool) bool
func Some[T any](slice []T, predicate func(index int, item T) bool) bool
```
<b>例子:</b>
@@ -1020,8 +1086,34 @@ func main() {
### <span id="Union">Unique</span>
<p>从所有给定的切片按顺序创建一个唯一值切片。 使用 == 进行相等比较。</p>
### <span id="UniqueBy">UniqueBy</span>
<p>对切片的每个元素调用iteratee函数然后删除重复元素</p>
<b>函数签名:</b>
```go
func UniqueBy[T any](slice []T, iteratee func(item T) T) []T
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
res := slice.UniqueBy([]int{1, 2, 3, 4, 5, 6}, func(val int) int {
return val % 4
})
fmt.Println(res) //[]int{1, 2, 3, 0}
}
```
### <span id="Union">Union</span>
<p>从所有给定的切片按顺序创建一个唯一值切片,使用==进行相等比较</p>
<b>函数签名:</b>
@@ -1048,7 +1140,7 @@ func main() {
### <span id="UpdateAt">UpdateAt</span>
<p>更新索引处的切片元素。 如果 param index < 0 或 index >= len(slice),将返回错误</p>
<p>更新索引处的切片元素。 如果index < 0或 index >= len(slice),将返回错误</p>
<b>函数签名:</b>

View File

@@ -13,6 +13,7 @@ import (
"io/ioutil"
"net/http"
"os"
"path"
"path/filepath"
"strings"
)
@@ -40,6 +41,11 @@ func CreateFile(path string) bool {
return true
}
// CreateDir create directory in absolute path. param `absPath` like /a/, /a/b/
func CreateDir(absPath string) error {
return os.MkdirAll(path.Dir(absPath), os.ModePerm)
}
// IsDir checks if the path is directory or not
func IsDir(path string) bool {
file, err := os.Stat(path)

View File

@@ -33,6 +33,27 @@ func TestCreateFile(t *testing.T) {
os.Remove(f)
}
func TestCreateDir(t *testing.T) {
assert := internal.NewAssert(t, "TestCreateDir")
pwd, err := os.Getwd()
if err != nil {
t.Error(err)
t.FailNow()
}
dirPath := pwd + "/a/"
err = CreateDir(dirPath)
if err != nil {
t.Error(err)
t.FailNow()
}
assert.Equal(true, IsExist(dirPath))
os.Remove(dirPath)
assert.Equal(false, IsExist(dirPath))
}
func TestIsDir(t *testing.T) {
assert := internal.NewAssert(t, "TestIsDir")

View File

@@ -108,7 +108,7 @@ func Difference[T comparable](slice, comparedSlice []T) []T {
// DifferenceBy it accepts iteratee which is invoked for each element of slice
// and values to generate the criterion by which they're compared.
// like lodash.js differenceBy: https://lodash.com/docs/4.17.15#differenceBy,
func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, t T) T) []T {
func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T {
orginSliceAfterMap := Map(slice, iteratee)
comparedSliceAfterMap := Map(comparedSlice, iteratee)
@@ -147,8 +147,39 @@ func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value,
return res
}
// Equal checks if two slices are equal: the same length and all elements' order and value are equal
func Equal[T comparable](slice1, slice2 []T) bool {
if len(slice1) != len(slice2) {
return false
}
for i := range slice1 {
if slice1[i] != slice2[i] {
return false
}
}
return true
}
// EqualWith checks if two slices are equal with comparator func
func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool {
if len(slice1) != len(slice2) {
return false
}
for i, v1 := range slice1 {
v2 := slice2[i]
if !comparator(v1, v2) {
return false
}
}
return true
}
// Every return true if all of the values in the slice pass the predicate function.
func Every[T any](slice []T, predicate func(index int, t T) bool) bool {
func Every[T any](slice []T, predicate func(index int, item T) bool) bool {
if predicate == nil {
panic("predicate func is missing")
}
@@ -164,7 +195,7 @@ func Every[T any](slice []T, predicate func(index int, t T) bool) bool {
}
// None return true if all the values in the slice mismatch the criteria
func None[T any](slice []T, predicate func(index int, t T) bool) bool {
func None[T any](slice []T, predicate func(index int, item T) bool) bool {
if predicate == nil {
panic("predicate func is missing")
}
@@ -180,7 +211,7 @@ func None[T any](slice []T, predicate func(index int, t T) bool) bool {
}
// Some return true if any of the values in the list pass the predicate function.
func Some[T any](slice []T, predicate func(index int, t T) bool) bool {
func Some[T any](slice []T, predicate func(index int, item T) bool) bool {
if predicate == nil {
panic("predicate func is missing")
}
@@ -194,7 +225,7 @@ func Some[T any](slice []T, predicate func(index int, t T) bool) bool {
}
// Filter iterates over elements of slice, returning an slice of all elements pass the predicate function
func Filter[T any](slice []T, predicate func(index int, t T) bool) []T {
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T {
if predicate == nil {
panic("predicate func is missing")
}
@@ -209,7 +240,7 @@ func Filter[T any](slice []T, predicate func(index int, t T) bool) []T {
}
// Count iterates over elements of slice, returns a count of all matched elements
func Count[T any](slice []T, predicate func(index int, t T) bool) int {
func Count[T any](slice []T, predicate func(index int, item T) bool) int {
if predicate == nil {
panic("predicate func is missing")
}
@@ -229,7 +260,7 @@ func Count[T any](slice []T, predicate func(index int, t T) bool) int {
}
// GroupBy iterate over elements of the slice, each element will be group by criteria, returns two slices
func GroupBy[T any](slice []T, groupFn func(index int, t T) bool) ([]T, []T) {
func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T) {
if groupFn == nil {
panic("groupFn func is missing")
}
@@ -274,7 +305,7 @@ func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T {
// Find iterates over elements of slice, returning the first one that passes a truth test on predicate function.
// If return T is nil then no items matched the predicate func
func Find[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) {
func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) {
if predicate == nil {
panic("predicate func is missing")
}
@@ -300,7 +331,7 @@ func Find[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) {
// FindLast iterates over elements of slice from end to begin, returning the first one that passes a truth test on predicate function.
// If return T is nil then no items matched the predicate func
func FindLast[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) {
func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) {
if predicate == nil {
panic("predicate func is missing")
}
@@ -349,7 +380,7 @@ func flattenRecursive(value reflect.Value, result reflect.Value) reflect.Value {
}
// ForEach iterates over elements of slice and invokes function for each element
func ForEach[T any](slice []T, iteratee func(index int, t T)) {
func ForEach[T any](slice []T, iteratee func(index int, item T)) {
if iteratee == nil {
panic("iteratee func is missing")
}
@@ -360,7 +391,7 @@ func ForEach[T any](slice []T, iteratee func(index int, t T)) {
}
// Map creates an slice of values by running each element of slice thru iteratee function.
func Map[T any, U any](slice []T, iteratee func(index int, t T) U) []U {
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U {
if iteratee == nil {
panic("iteratee func is missing")
}
@@ -374,7 +405,7 @@ func Map[T any, U any](slice []T, iteratee func(index int, t T) U) []U {
}
// Reduce creates an slice of values by running each element of slice thru iteratee function.
func Reduce[T any](slice []T, iteratee func(index int, t1, t2 T) T, initial T) T {
func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T {
if iteratee == nil {
panic("iteratee func is missing")
}
@@ -551,6 +582,21 @@ func Unique[T any](slice []T) []T {
return res
}
// UniqueBy call iteratee func with every item of slice, then remove duplicated.
func UniqueBy[T any](slice []T, iteratee func(item T) T) []T {
if len(slice) == 0 {
return []T{}
}
var res []T
for _, v := range slice {
val := iteratee(v)
res = append(res, val)
}
return Unique(res)
}
// Union creates a slice of unique values, in order, from all given slices. using == for equality comparisons.
func Union[T any](slices ...[]T) []T {
if len(slices) == 0 {

View File

@@ -61,11 +61,39 @@ func TestCompact(t *testing.T) {
func TestConcat(t *testing.T) {
assert := internal.NewAssert(t, "Concat")
// 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}, []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}, 5))
}
func TestEqual(t *testing.T) {
assert := internal.NewAssert(t, "TestEqual")
slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}
slice3 := []int{3, 2, 1}
assert.Equal(true, Equal(slice1, slice2))
assert.Equal(false, Equal(slice1, slice3))
}
// go test -fuzz=Fuzz -fuzztime=10s .
func FuzzEqual(f *testing.F) {
f.Fuzz(func(t *testing.T, a, b []byte) {
Equal(a, b)
})
}
func TestEqualWith(t *testing.T) {
assert := internal.NewAssert(t, "TestEqualWith")
slice1 := []int{1, 2, 3}
slice2 := []int{2, 4, 6}
isDouble := func(a, b int) bool {
return b == a*2
}
assert.Equal(true, EqualWith(slice1, slice2, isDouble))
}
func TestEvery(t *testing.T) {
@@ -371,6 +399,15 @@ func TestUnique(t *testing.T) {
assert.Equal([]string{"a", "b", "c"}, Unique([]string{"a", "a", "b", "c"}))
}
func TestUniqueBy(t *testing.T) {
assert := internal.NewAssert(t, "TestUniqueBy")
actual := UniqueBy([]int{1, 2, 3, 4, 5, 6}, func(val int) int {
return val % 4
})
assert.Equal([]int{1, 2, 3, 0}, actual)
}
func TestUnion(t *testing.T) {
assert := internal.NewAssert(t, "TestUnion")