mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-09 07:02:29 +08:00
Compare commits
110 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a783de57a8 | ||
|
|
a622959a78 | ||
|
|
f709dd53ce | ||
|
|
ee9e9625e2 | ||
|
|
84da7d4f27 | ||
|
|
089fd4e13c | ||
|
|
6c40e02324 | ||
|
|
a270b1b634 | ||
|
|
260fb795d3 | ||
|
|
8c036f830c | ||
|
|
bf332b9f1c | ||
|
|
6b6cd66f9f | ||
|
|
5399c2290e | ||
|
|
6248293c49 | ||
|
|
eced25b76d | ||
|
|
96a4327aa7 | ||
|
|
fcfbdea597 | ||
|
|
87896f917a | ||
|
|
b8563ed646 | ||
|
|
1ccf0af2b3 | ||
|
|
6314889c6a | ||
|
|
294bd5a5ed | ||
|
|
ca44815fd5 | ||
|
|
bcd1cabf80 | ||
|
|
4edefcca67 | ||
|
|
fab24c8d12 | ||
|
|
604acd9b07 | ||
|
|
531cb19fd1 | ||
|
|
4f0161ca53 | ||
|
|
73362b7f69 | ||
|
|
b289f2975b | ||
|
|
90ce2705ca | ||
|
|
35e1d09ce3 | ||
|
|
d67d8fad3a | ||
|
|
c5e6d01a31 | ||
|
|
6d6c3f692f | ||
|
|
c695837b16 | ||
|
|
ef28b52963 | ||
|
|
18b2b6ff7c | ||
|
|
6a05a123f4 | ||
|
|
f7c33f258d | ||
|
|
04058dd7da | ||
|
|
72e1d92fa1 | ||
|
|
063df0f0d1 | ||
|
|
fc10689b25 | ||
|
|
9239bcfdc3 | ||
|
|
c984815dea | ||
|
|
301cb5db87 | ||
|
|
cc1bacff74 | ||
|
|
f49f75b371 | ||
|
|
b30f4a7bab | ||
|
|
982cb8932b | ||
|
|
9107eb4b32 | ||
|
|
1acf977b24 | ||
|
|
5c878d0873 | ||
|
|
ab0716a472 | ||
|
|
3c2e0ca5b3 | ||
|
|
551e66ba29 | ||
|
|
4eeeabb227 | ||
|
|
b3437fdddf | ||
|
|
312dcab369 | ||
|
|
0cb89f4f46 | ||
|
|
a2dec87995 | ||
|
|
9094cb29bf | ||
|
|
ddb992ad2f | ||
|
|
24f18aaaec | ||
|
|
36169874e5 | ||
|
|
23aeb6ac99 | ||
|
|
a1984f0a59 | ||
|
|
c95db23d2c | ||
|
|
fbf251d805 | ||
|
|
337f08a04b | ||
|
|
c6a7371049 | ||
|
|
b697858038 | ||
|
|
5446f7e33c | ||
|
|
553f63e76b | ||
|
|
fc3e94df58 | ||
|
|
5c66f38a5b | ||
|
|
70e213b3f7 | ||
|
|
c1b7500bcb | ||
|
|
3d7600a9e4 | ||
|
|
0299c454ab | ||
|
|
741af66404 | ||
|
|
ef5d0379a1 | ||
|
|
105ab49763 | ||
|
|
b5ba9ba573 | ||
|
|
ac3baac5c6 | ||
|
|
a82b5dd206 | ||
|
|
ac0fb5ef25 | ||
|
|
9bd1c205fe | ||
|
|
6ccf9fd3cf | ||
|
|
c02ef2c62d | ||
|
|
6414031754 | ||
|
|
5336130570 | ||
|
|
bfa46d46a2 | ||
|
|
aab28b914c | ||
|
|
336e454ce7 | ||
|
|
35a50bd792 | ||
|
|
2fd23f02f6 | ||
|
|
aad5b447c9 | ||
|
|
cece13e929 | ||
|
|
ecf325a06c | ||
|
|
44370aef5e | ||
|
|
1782b11ec4 | ||
|
|
fe6495123c | ||
|
|
d442f564ce | ||
|
|
f35446cc13 | ||
|
|
506a8b4776 | ||
|
|
47ecfbfd5f | ||
|
|
82f7401368 |
148
README.md
148
README.md
@@ -1,15 +1,16 @@
|
|||||||
<div align=center>
|
<div align=center>
|
||||||
<img src="./logo.png" width="200" height="200"/>
|
<a href="https://uvdream.github.io/lancet-docs/en/"><img src="./logo.png" width="200" height="200"/></a>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||

|

|
||||||
[](https://github.com/duke-git/lancet/releases)
|
[](https://github.com/duke-git/lancet/releases)
|
||||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||||
[](https://codecov.io/gh/duke-git/lancet)
|
[](https://codecov.io/gh/duke-git/lancet)
|
||||||
[](https://github.com/duke-git/lancet/blob/main/LICENSE)
|
[](https://github.com/duke-git/lancet/blob/main/LICENSE)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -28,16 +29,19 @@ English | [简体中文](./README_zh-CN.md)
|
|||||||
- 🌍 Unit test for every exported function.
|
- 🌍 Unit test for every exported function.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### Note:
|
### Note:
|
||||||
|
|
||||||
1. <b>For users who use go1.18 and above, it is recommended to install lancet v2.x.x. Cause v2.x.x rewrite all functions with generics of go1.18.</b>
|
1. <b>For users who use go1.18 and above, it is recommended to install lancet v2.x.x. Cause v2.x.x rewrite all functions with generics of go1.18.</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
go get github.com/duke-git/lancet/v2 // will install latest version of v2.x.x
|
go get github.com/duke-git/lancet/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.3.0. </b>
|
2. <b>For users who use version below go1.18, you should install v1.x.x. now latest v1 is v1.3.3. </b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
go get github.com/duke-git/lancet@v1.3.0 // below go1.18, install latest version of v1.x.x
|
go get github.com/duke-git/lancet@v1.3.3 // below go1.18, install latest version of v1.x.x
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -50,7 +54,7 @@ import "github.com/duke-git/lancet/v2/strutil"
|
|||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
Here takes the string function ReverseStr (reverse order string) as an example, and the strutil package needs to be imported.
|
Here takes the string function Reverse (reverse order string) as an example, and the strutil package needs to be imported.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -62,19 +66,23 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := "hello"
|
s := "hello"
|
||||||
rs := strutil.ReverseStr(s)
|
rs := strutil.Reverse(s)
|
||||||
fmt.Println(rs) //olleh
|
fmt.Println(rs) //olleh
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## API Documentation
|
## API Documentation
|
||||||
|
|
||||||
|
## [lancet API doc](https://uvdream.github.io/lancet-docs/) Thanks [@UvDream](https://github.com/UvDream) for contributing.
|
||||||
|
|
||||||
### 1. Algorithm package implements some basic algorithm. eg. sort, search.
|
### 1. Algorithm package implements some basic algorithm. eg. sort, search.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/algorithm"
|
import "github.com/duke-git/lancet/v2/algorithm"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [BubbleSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#BubbleSort)
|
- [BubbleSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#BubbleSort)
|
||||||
- [CountSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#CountSort)
|
- [CountSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#CountSort)
|
||||||
- [HeapSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#HeapSort)
|
- [HeapSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#HeapSort)
|
||||||
@@ -88,14 +96,14 @@ import "github.com/duke-git/lancet/v2/algorithm"
|
|||||||
- [LinearSearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#LinearSearch)
|
- [LinearSearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#LinearSearch)
|
||||||
- [LRUCache](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#LRUCache)
|
- [LRUCache](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#LRUCache)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 2. Concurrency package contain some functions to support concurrent programming. eg, goroutine, channel, async.
|
### 2. Concurrency package contain some functions to support concurrent programming. eg, goroutine, channel, async.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/concurrency"
|
import "github.com/duke-git/lancet/v2/concurrency"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [NewChannel](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#NewChannel)
|
- [NewChannel](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#NewChannel)
|
||||||
- [Bridge](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Bridge)
|
- [Bridge](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Bridge)
|
||||||
- [FanIn](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#FanIn)
|
- [FanIn](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#FanIn)
|
||||||
@@ -107,12 +115,30 @@ import "github.com/duke-git/lancet/v2/concurrency"
|
|||||||
- [Take](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Take)
|
- [Take](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Take)
|
||||||
- [Tee](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Tee)
|
- [Tee](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Tee)
|
||||||
|
|
||||||
### 3. Convertor package contains some functions for data convertion.
|
### 3. Condition package contains some functions for conditional judgment. eg. And, Or, TernaryOperator...
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/v2/condition"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Function list:
|
||||||
|
|
||||||
|
- [Bool](https://github.com/duke-git/lancet/blob/main/docs/condition.md#Bool)
|
||||||
|
- [And](https://github.com/duke-git/lancet/blob/main/docs/condition.md#And)
|
||||||
|
- [Or](https://github.com/duke-git/lancet/blob/main/docs/condition.md#Or)
|
||||||
|
- [Xor](https://github.com/duke-git/lancet/blob/main/docs/condition.md#Xor)
|
||||||
|
- [Nor](https://github.com/duke-git/lancet/blob/main/docs/condition.md#Nor)
|
||||||
|
- [Nand](https://github.com/duke-git/lancet/blob/main/docs/condition.md#Nand)
|
||||||
|
- [TernaryOperator](https://github.com/duke-git/lancet/blob/main/docs/condition.md#TernaryOperator)
|
||||||
|
|
||||||
|
### 4. Convertor package contains some functions for data convertion.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/convertor"
|
import "github.com/duke-git/lancet/v2/convertor"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ColorHexToRGB)
|
- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ColorHexToRGB)
|
||||||
- [ColorRGBToHex](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ColorRGBToHex)
|
- [ColorRGBToHex](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ColorRGBToHex)
|
||||||
- [ToBool](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToBool)
|
- [ToBool](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToBool)
|
||||||
@@ -127,14 +153,17 @@ import "github.com/duke-git/lancet/v2/convertor"
|
|||||||
- [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToString)
|
- [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToString)
|
||||||
- [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#StructToMap)
|
- [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#StructToMap)
|
||||||
- [MapToSlice](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#MapToSlice)
|
- [MapToSlice](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#MapToSlice)
|
||||||
|
- [EncodeByte](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#EncodeByte)
|
||||||
|
- [DecodeByte](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#DecodeByte)
|
||||||
|
|
||||||
### 4. Cryptor package is for data encryption and decryption.
|
### 5. Cryptor package is for data encryption and decryption.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/cryptor"
|
import "github.com/duke-git/lancet/v2/cryptor"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbEncrypt)
|
- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbEncrypt)
|
||||||
- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbDecrypt)
|
- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbDecrypt)
|
||||||
- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCbcEncrypt)
|
- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCbcEncrypt)
|
||||||
@@ -168,13 +197,14 @@ import "github.com/duke-git/lancet/v2/cryptor"
|
|||||||
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaEncrypt)
|
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaEncrypt)
|
||||||
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaDecrypt)
|
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaDecrypt)
|
||||||
|
|
||||||
### 5. Datetime package supports date and time format and compare.
|
### 6. Datetime package supports date and time format and compare.
|
||||||
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/datetime"
|
import "github.com/duke-git/lancet/v2/datetime"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddDay)
|
- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddDay)
|
||||||
- [AddHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddHour)
|
- [AddHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddHour)
|
||||||
- [AddMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddMinute)
|
- [AddMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddMinute)
|
||||||
@@ -206,10 +236,7 @@ import "github.com/duke-git/lancet/v2/datetime"
|
|||||||
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToFormatForTpl)
|
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToFormatForTpl)
|
||||||
- [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToIso8601)
|
- [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToIso8601)
|
||||||
|
|
||||||
|
### 7. Datastructure package constains some common data structure. eg. list, linklist, stack, queue, set, tree, graph.
|
||||||
|
|
||||||
### 6. Datastructure package constains some common data structure. eg. list, linklist, stack, queue, set, tree, graph.
|
|
||||||
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import list "github.com/duke-git/lancet/v2/datastructure/list"
|
import list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
@@ -219,8 +246,11 @@ import queue "github.com/duke-git/lancet/v2/datastructure/queue"
|
|||||||
import set "github.com/duke-git/lancet/v2/datastructure/set"
|
import set "github.com/duke-git/lancet/v2/datastructure/set"
|
||||||
import tree "github.com/duke-git/lancet/v2/datastructure/tree"
|
import tree "github.com/duke-git/lancet/v2/datastructure/tree"
|
||||||
import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
||||||
|
import hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [List](https://github.com/duke-git/lancet/blob/main/docs/datastructure/list.md)
|
- [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)
|
- [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)
|
- [Stack](https://github.com/duke-git/lancet/blob/main/docs/datastructure/stack.md)
|
||||||
@@ -228,9 +258,9 @@ import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
|||||||
- [Set](https://github.com/duke-git/lancet/blob/main/docs/datastructure/set.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)
|
- [Tree](https://github.com/duke-git/lancet/blob/main/docs/datastructure/tree.md)
|
||||||
- [Heap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/heap.md)
|
- [Heap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/heap.md)
|
||||||
|
- [HashMap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/hashmap.md)
|
||||||
|
|
||||||
|
### 8. Fileutil package implements some basic functions for file operations.
|
||||||
### 7. Fileutil package implements some basic functions for file operations.
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/fileutil"
|
import "github.com/duke-git/lancet/v2/fileutil"
|
||||||
@@ -254,37 +284,41 @@ import "github.com/duke-git/lancet/v2/fileutil"
|
|||||||
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#Zip)
|
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#Zip)
|
||||||
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#UnZip)
|
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#UnZip)
|
||||||
|
|
||||||
### 8. Formatter contains some functions for data formatting.
|
### 9. Formatter contains some functions for data formatting.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/formatter"
|
import "github.com/duke-git/lancet/v2/formatter"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#Comma)
|
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#Comma)
|
||||||
|
|
||||||
### 9. Function package can control the flow of function execution and support part of functional programming
|
### 10. Function package can control the flow of function execution and support part of functional programming
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/function"
|
import "github.com/duke-git/lancet/v2/function"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [After](https://github.com/duke-git/lancet/blob/main/docs/function.md#After)
|
- [After](https://github.com/duke-git/lancet/blob/main/docs/function.md#After)
|
||||||
- [Before](https://github.com/duke-git/lancet/blob/main/docs/function.md#Before)
|
- [Before](https://github.com/duke-git/lancet/blob/main/docs/function.md#Before)
|
||||||
- [Curry](https://github.com/duke-git/lancet/blob/main/docs/function.md#Curry)
|
- [Curry](https://github.com/duke-git/lancet/blob/main/docs/function.md#Curry)
|
||||||
- [Compose](https://github.com/duke-git/lancet/blob/main/docs/function.md#Compose)
|
- [Compose](https://github.com/duke-git/lancet/blob/main/docs/function.md#Compose)
|
||||||
- [Debounced](https://github.com/duke-git/lancet/blob/main/docs/function.md#Debounced)
|
- [Debounced](https://github.com/duke-git/lancet/blob/main/docs/function.md#Debounced)
|
||||||
- [Delay](https://github.com/duke-git/lancet/blob/main/docs/function.md#Delay)
|
- [Delay](https://github.com/duke-git/lancet/blob/main/docs/function.md#Delay)
|
||||||
|
- [Pipeline](https://github.com/duke-git/lancet/blob/main/docs/function.md#Pipeline)
|
||||||
- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function.md#Watcher)
|
- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function.md#Watcher)
|
||||||
|
|
||||||
|
### 11. Maputil package includes some functions to manipulate map.
|
||||||
### 10. Maputil package includes some functions to manipulate map.
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/maputil"
|
import "github.com/duke-git/lancet/v2/maputil"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#ForEach)
|
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#ForEach)
|
||||||
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Filter)
|
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Filter)
|
||||||
- [Intersect](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Intersect)
|
- [Intersect](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Intersect)
|
||||||
@@ -292,15 +326,16 @@ import "github.com/duke-git/lancet/v2/maputil"
|
|||||||
- [Merge](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Merge)
|
- [Merge](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Merge)
|
||||||
- [Minus](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Minus)
|
- [Minus](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Minus)
|
||||||
- [Values](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Values)
|
- [Values](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Values)
|
||||||
|
- [IsDisjoint](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#IsDisjoint)
|
||||||
|
|
||||||
|
### 12. Mathutil package implements some functions for math calculation.
|
||||||
### 11. Mathutil package implements some functions for math calculation.
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/mathutil"
|
import "github.com/duke-git/lancet/v2/mathutil"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [Average](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Average)
|
- [Average](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Average)
|
||||||
- [Exponent](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Exponent)
|
- [Exponent](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Exponent)
|
||||||
- [Fibonacci](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Fibonacci)
|
- [Fibonacci](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Fibonacci)
|
||||||
@@ -314,61 +349,76 @@ import "github.com/duke-git/lancet/v2/mathutil"
|
|||||||
- [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RoundToString)
|
- [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RoundToString)
|
||||||
- [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#TruncRound)
|
- [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#TruncRound)
|
||||||
|
|
||||||
|
### 13. 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
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/netutil"
|
import "github.com/duke-git/lancet/v2/netutil"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ConvertMapToQueryString)
|
- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ConvertMapToQueryString)
|
||||||
|
- [EncodeUrl](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#EncodeUrl)
|
||||||
- [GetInternalIp](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetInternalIp)
|
- [GetInternalIp](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetInternalIp)
|
||||||
- [GetIps](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetIps)
|
- [GetIps](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetIps)
|
||||||
- [GetMacAddrs](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetMacAddrs)
|
- [GetMacAddrs](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetMacAddrs)
|
||||||
- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetPublicIpInfo)
|
- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetPublicIpInfo)
|
||||||
- [GetRequestPublicIp](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetRequestPublicIp)
|
- [GetRequestPublicIp](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetRequestPublicIp)
|
||||||
- [IsPublicIP](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#IsPublicIP)
|
- [IsPublicIP](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#IsPublicIP)
|
||||||
- [IsInternalIP](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#IsInternalIP)
|
- [IsInternalIP](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#IsInternalIP)
|
||||||
- [HttpGet](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpGet)
|
- [HttpRequest](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpRequest)
|
||||||
- [HttpDelete](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpDelete)
|
- [HttpClient](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpClient)
|
||||||
- [HttpPost](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPost)
|
- [SendRequest](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#SendRequest)
|
||||||
- [HttpPut](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPut)
|
- [DecodeResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#DecodeResponse)
|
||||||
- [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPatch)
|
- [StructToUrlValues](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#StructToUrlValues)
|
||||||
|
|
||||||
|
- [HttpGet<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpGet)
|
||||||
|
- [HttpDelete<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpDelete)
|
||||||
|
- [HttpPost<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPost)
|
||||||
|
- [HttpPut<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPut)
|
||||||
|
- [HttpPatch<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPatch)
|
||||||
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ParseHttpResponse)
|
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ParseHttpResponse)
|
||||||
|
|
||||||
### 13. Random package implements some basic functions to generate random int and string.
|
### 14. Random package implements some basic functions to generate random int and string.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/random"
|
import "github.com/duke-git/lancet/v2/random"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [RandBytes](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandBytes)
|
- [RandBytes](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandBytes)
|
||||||
- [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandInt)
|
- [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandInt)
|
||||||
- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandString)
|
- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandString)
|
||||||
|
- [RandUpper](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandUpper)
|
||||||
|
- [RandLower](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandLower)
|
||||||
|
- [RandNumeral](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandNumeral)
|
||||||
|
- [RandNumeralOrLetter](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandNumeralOrLetter)
|
||||||
- [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4)
|
- [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4)
|
||||||
|
|
||||||
### 14. Retry package is for executing a function repeatedly until it was successful or canceled by the context.
|
### 15. Retry package is for executing a function repeatedly until it was successful or canceled by the context.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/retry"
|
import "github.com/duke-git/lancet/v2/retry"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [Context](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Context)
|
- [Context](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Context)
|
||||||
- [Retry](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Retry)
|
- [Retry](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Retry)
|
||||||
- [RetryFunc](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryFunc)
|
- [RetryFunc](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryFunc)
|
||||||
- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryDuration)
|
- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryDuration)
|
||||||
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryTimes)
|
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryTimes)
|
||||||
|
|
||||||
### 15. Slice contains some functions to manipulate slice.
|
### 16. Slice contains some functions to manipulate slice.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/slice"
|
import "github.com/duke-git/lancet/v2/slice"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
|
- [AppendIfAbsent](https://github.com/duke-git/lancet/blob/main/docs/slice.md#AppendIfAbsent)
|
||||||
- [Contain](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Contain)
|
- [Contain](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Contain)
|
||||||
- [ContainSubSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ContainSubSlice)
|
- [ContainSubSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ContainSubSlice)
|
||||||
- [Chunk](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Chunk)
|
- [Chunk](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Chunk)
|
||||||
@@ -386,7 +436,8 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Filter)
|
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Filter)
|
||||||
- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Find)
|
- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Find)
|
||||||
- [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice.md#FindLast)
|
- [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice.md#FindLast)
|
||||||
- [FlattenDeep](#FlattenDeep)
|
- [Flatten](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Flatten)
|
||||||
|
- [FlattenDeep](https://github.com/duke-git/lancet/blob/main/docs/slice.md#FlattenDeep)
|
||||||
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ForEach)
|
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ForEach)
|
||||||
- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupBy)
|
- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupBy)
|
||||||
- [GroupWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupWith)
|
- [GroupWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupWith)
|
||||||
@@ -399,6 +450,8 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Map)
|
- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Map)
|
||||||
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reverse)
|
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reverse)
|
||||||
- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reduce)
|
- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reduce)
|
||||||
|
- [Replace](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Replace)
|
||||||
|
- [ReplaceAll](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ReplaceAll)
|
||||||
- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Shuffle)
|
- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Shuffle)
|
||||||
- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SortByField)
|
- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SortByField)
|
||||||
- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Some)
|
- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Some)
|
||||||
@@ -409,10 +462,13 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Unique)
|
- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Unique)
|
||||||
- [UniqueBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UniqueBy)
|
- [UniqueBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UniqueBy)
|
||||||
- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Union)
|
- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Union)
|
||||||
|
- [UnionBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UnionBy)
|
||||||
- [UpdateAt](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UpdateAt)
|
- [UpdateAt](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UpdateAt)
|
||||||
- [Without](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Without)
|
- [Without](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Without)
|
||||||
|
- [KeyBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#KeyBy)
|
||||||
|
|
||||||
|
### 17. Strutil package contains some functions to manipulate string.
|
||||||
|
|
||||||
### 16. Strutil package contains some functions to manipulate string.
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/strutil"
|
import "github.com/duke-git/lancet/v2/strutil"
|
||||||
```
|
```
|
||||||
@@ -431,18 +487,20 @@ import "github.com/duke-git/lancet/v2/strutil"
|
|||||||
- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#UpperFirst)
|
- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#UpperFirst)
|
||||||
- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadEnd)
|
- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadEnd)
|
||||||
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadStart)
|
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadStart)
|
||||||
- [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#ReverseStr)
|
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Reverse)
|
||||||
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SnakeCase)
|
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SnakeCase)
|
||||||
- [SplitEx](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SplitEx)
|
- [SplitEx](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SplitEx)
|
||||||
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Wrap)
|
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Wrap)
|
||||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Unwrap)
|
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Unwrap)
|
||||||
|
|
||||||
### 17. System package contain some functions about os, runtime, shell command.
|
### 19. System package contain some functions about os, runtime, shell command.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/system"
|
import "github.com/duke-git/lancet/v2/system"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [IsWindows](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsWindows)
|
- [IsWindows](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsWindows)
|
||||||
- [IsLinux](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsLinux)
|
- [IsLinux](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsLinux)
|
||||||
- [IsMac](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsMac)
|
- [IsMac](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsMac)
|
||||||
@@ -451,8 +509,9 @@ import "github.com/duke-git/lancet/v2/system"
|
|||||||
- [RemoveOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#RemoveOsEnv)
|
- [RemoveOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#RemoveOsEnv)
|
||||||
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#CompareOsEnv)
|
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#CompareOsEnv)
|
||||||
- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system.md#ExecCommand)
|
- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system.md#ExecCommand)
|
||||||
|
- [GetOsBits](https://github.com/duke-git/lancet/blob/main/docs/system.md#GetOsBits)
|
||||||
|
|
||||||
### 18. Validator package contains some functions for data validation.
|
### 19. Validator package contains some functions for data validation.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/validator"
|
import "github.com/duke-git/lancet/v2/validator"
|
||||||
@@ -486,14 +545,17 @@ import "github.com/duke-git/lancet/v2/validator"
|
|||||||
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsStrongPassword)
|
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsStrongPassword)
|
||||||
- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsUrl)
|
- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsUrl)
|
||||||
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsWeakPassword)
|
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsWeakPassword)
|
||||||
### 19. xerror package implements helpers for errors.
|
- [IsZeroValue](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsZeroValue)
|
||||||
|
|
||||||
|
### 20. xerror package implements helpers for errors.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/xerror"
|
import "github.com/duke-git/lancet/v2/xerror"
|
||||||
```
|
```
|
||||||
#### Function list:
|
|
||||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#Unwrap)
|
|
||||||
|
|
||||||
|
#### Function list:
|
||||||
|
|
||||||
|
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#Unwrap)
|
||||||
|
|
||||||
## How to Contribute
|
## How to Contribute
|
||||||
|
|
||||||
|
|||||||
147
README_zh-CN.md
147
README_zh-CN.md
@@ -1,15 +1,16 @@
|
|||||||
<div align=center>
|
<div align=center>
|
||||||
<img src="./logo.png" width="200" height="200"/>
|
<a href="https://uvdream.github.io/lancet-docs/"><img src="./logo.png" width="200" height="200"/><a/>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||

|

|
||||||
[](https://github.com/duke-git/lancet/releases)
|
[](https://github.com/duke-git/lancet/releases)
|
||||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||||
[](https://codecov.io/gh/duke-git/lancet)
|
[](https://codecov.io/gh/duke-git/lancet)
|
||||||
[](https://github.com/duke-git/lancet/blob/main/LICENSE)
|
[](https://github.com/duke-git/lancet/blob/main/LICENSE)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -19,7 +20,6 @@
|
|||||||
|
|
||||||
简体中文 | [English](./README.md)
|
简体中文 | [English](./README.md)
|
||||||
|
|
||||||
|
|
||||||
## 特性
|
## 特性
|
||||||
|
|
||||||
- 👏 全面、高效、可复用
|
- 👏 全面、高效、可复用
|
||||||
@@ -28,16 +28,19 @@
|
|||||||
- 🌍 所有导出函数单元测试覆盖率 100%
|
- 🌍 所有导出函数单元测试覆盖率 100%
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
### Note:
|
### Note:
|
||||||
|
|
||||||
1. <b>对于使用 go1.18 及以上的用户,建议安装 v2.x.x。 因为 v2.x.x 用 go1.18 的泛型重写了大部分函数。</b>
|
1. <b>对于使用 go1.18 及以上的用户,建议安装 v2.x.x。 因为 v2.x.x 用 go1.18 的泛型重写了大部分函数。</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
|
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
|
||||||
```
|
```
|
||||||
|
|
||||||
2. <b>使用go1.18以下版本的用户,必须安装v1.x.x。目前最新的v1版本是v1.3.0。</b>
|
2. <b>使用 go1.18 以下版本的用户,必须安装 v1.x.x。目前最新的 v1 版本是 v1.3.3。</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
go get github.com/duke-git/lancet@v1.3.0 // 使用go1.18以下版本, 必须安装v1.x.x版本
|
go get github.com/duke-git/lancet@v1.3.3 // 使用go1.18以下版本, 必须安装v1.x.x版本
|
||||||
```
|
```
|
||||||
|
|
||||||
## 用法
|
## 用法
|
||||||
@@ -50,7 +53,7 @@ import "github.com/duke-git/lancet/v2/strutil"
|
|||||||
|
|
||||||
## 例子
|
## 例子
|
||||||
|
|
||||||
此处以字符串工具函数ReverseStr(逆序字符串)为例,需要导入strutil包:
|
此处以字符串工具函数 Reverse(逆序字符串)为例,需要导入 strutil 包:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -62,19 +65,23 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := "hello"
|
s := "hello"
|
||||||
rs := strutil.ReverseStr(s)
|
rs := strutil.Reverse(s)
|
||||||
fmt.Println(rs) //olleh
|
fmt.Println(rs) //olleh
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## API 文档
|
## API 文档
|
||||||
|
|
||||||
|
## [lancet API doc](https://uvdream.github.io/lancet-docs/) 感谢[@UvDream](https://github.com/UvDream)整理
|
||||||
|
|
||||||
### 1. algorithm 算法包实现一些基本算法。eg. sort, search.
|
### 1. algorithm 算法包实现一些基本算法。eg. sort, search.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/algorithm"
|
import "github.com/duke-git/lancet/v2/algorithm"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [BubbleSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#BubbleSort)
|
- [BubbleSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#BubbleSort)
|
||||||
- [CountSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#CountSort)
|
- [CountSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#CountSort)
|
||||||
- [HeapSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#HeapSort)
|
- [HeapSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#HeapSort)
|
||||||
@@ -88,13 +95,14 @@ import "github.com/duke-git/lancet/v2/algorithm"
|
|||||||
- [LinearSearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#LinearSearch)
|
- [LinearSearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#LinearSearch)
|
||||||
- [LRUCache](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#LRUCache)
|
- [LRUCache](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#LRUCache)
|
||||||
|
|
||||||
|
### 2. concurrency 并发包包含一些支持并发编程的功能。例如:goroutine, channel, async 等。
|
||||||
### 2. 并发包包含一些支持并发编程的功能。例如:goroutine, channel, async等。
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/concurrency"
|
import "github.com/duke-git/lancet/v2/concurrency"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [NewChannel](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#NewChannel)
|
- [NewChannel](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#NewChannel)
|
||||||
- [Bridge](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Bridge)
|
- [Bridge](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Bridge)
|
||||||
- [FanIn](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#FanIn)
|
- [FanIn](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#FanIn)
|
||||||
@@ -106,12 +114,30 @@ import "github.com/duke-git/lancet/v2/concurrency"
|
|||||||
- [Take](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Take)
|
- [Take](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Take)
|
||||||
- [Tee](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Tee)
|
- [Tee](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Tee)
|
||||||
|
|
||||||
### 3. convertor转换器包支持一些常见的数据类型转换。
|
### 3. condition 条件包含一些用于条件判断的函数。eg. And, Or, TernaryOperator...
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/v2/condition"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Function list:
|
||||||
|
|
||||||
|
- [Bool](https://github.com/duke-git/lancet/blob/main/docs/condition_zh-CN.md#Bool)
|
||||||
|
- [And](https://github.com/duke-git/lancet/blob/main/docs/condition_zh-CN.md#And)
|
||||||
|
- [Or](https://github.com/duke-git/lancet/blob/main/docs/condition_zh-CN.md#Or)
|
||||||
|
- [Xor](https://github.com/duke-git/lancet/blob/main/docs/condition_zh-CN.md#Xor)
|
||||||
|
- [Nor](https://github.com/duke-git/lancet/blob/main/docs/condition_zh-CN.md#Nor)
|
||||||
|
- [Nand](https://github.com/duke-git/lancet/blob/main/docs/condition_zh-CN.md#Nand)
|
||||||
|
- [TernaryOperator](https://github.com/duke-git/lancet/blob/main/docs/condition_zh-CN.md#TernaryOperator)
|
||||||
|
|
||||||
|
### 4. convertor 转换器包支持一些常见的数据类型转换。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/convertor"
|
import "github.com/duke-git/lancet/v2/convertor"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ColorHexToRGB)
|
- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ColorHexToRGB)
|
||||||
- [ColorRGBToHex](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ColorRGBToHex)
|
- [ColorRGBToHex](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ColorRGBToHex)
|
||||||
- [ToBool](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToBool)
|
- [ToBool](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToBool)
|
||||||
@@ -126,13 +152,17 @@ import "github.com/duke-git/lancet/v2/convertor"
|
|||||||
- [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToString)
|
- [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToString)
|
||||||
- [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#StructToMap)
|
- [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#StructToMap)
|
||||||
- [MapToSlice](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#MapToSlice)
|
- [MapToSlice](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#MapToSlice)
|
||||||
### 4. cryptor加密包支持数据加密和解密,获取md5,hash值。支持base64, md5, hmac, aes, des, rsa。
|
- [EncodeByte](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#EncodeByte)
|
||||||
|
- [DecodeByte](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#DecodeByte)
|
||||||
|
|
||||||
|
### 5. cryptor 加密包支持数据加密和解密,获取 md5,hash 值。支持 base64, md5, hmac, aes, des, rsa。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/cryptor"
|
import "github.com/duke-git/lancet/v2/cryptor"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbEncrypt)
|
- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbEncrypt)
|
||||||
- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbDecrypt)
|
- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbDecrypt)
|
||||||
- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCbcEncrypt)
|
- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCbcEncrypt)
|
||||||
@@ -166,13 +196,14 @@ import "github.com/duke-git/lancet/v2/cryptor"
|
|||||||
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaEncrypt)
|
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaEncrypt)
|
||||||
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaDecrypt)
|
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaDecrypt)
|
||||||
|
|
||||||
### 5. datetime日期时间处理包,格式化日期,比较日期。
|
### 6. datetime 日期时间处理包,格式化日期,比较日期。
|
||||||
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/datetime"
|
import "github.com/duke-git/lancet/v2/datetime"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddDay)
|
- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddDay)
|
||||||
- [AddHour](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddHour)
|
- [AddHour](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddHour)
|
||||||
- [AddMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddMinute)
|
- [AddMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddMinute)
|
||||||
@@ -204,9 +235,7 @@ import "github.com/duke-git/lancet/v2/datetime"
|
|||||||
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormatForTpl)
|
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormatForTpl)
|
||||||
- [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToIso8601)
|
- [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToIso8601)
|
||||||
|
|
||||||
|
### 7. datastructure 包含一些普通的数据结构实现。例如:list, linklist, stack, queue, set, tree, graph.
|
||||||
### 6. datastructure包含一些普通的数据结构实现。例如:list, linklist, stack, queue, set, tree, graph.
|
|
||||||
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import list "github.com/duke-git/lancet/v2/datastructure/list"
|
import list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
@@ -216,8 +245,11 @@ import queue "github.com/duke-git/lancet/v2/datastructure/queue"
|
|||||||
import set "github.com/duke-git/lancet/v2/datastructure/set"
|
import set "github.com/duke-git/lancet/v2/datastructure/set"
|
||||||
import tree "github.com/duke-git/lancet/v2/datastructure/tree"
|
import tree "github.com/duke-git/lancet/v2/datastructure/tree"
|
||||||
import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
||||||
|
import hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [List](https://github.com/duke-git/lancet/blob/main/docs/datastructure/list_zh-CN.md)
|
- [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)
|
- [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)
|
- [Stack](https://github.com/duke-git/lancet/blob/main/docs/datastructure/stack_zh-CN.md)
|
||||||
@@ -225,9 +257,9 @@ import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
|||||||
- [Set](https://github.com/duke-git/lancet/blob/main/docs/datastructure/set_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)
|
- [Tree](https://github.com/duke-git/lancet/blob/main/docs/datastructure/tree_zh-CN.md)
|
||||||
- [Heap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/heap.md)
|
- [Heap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/heap.md)
|
||||||
|
- [HashMap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/hashmap.md)
|
||||||
|
|
||||||
|
### 8. fileutil 包支持文件基本操作。
|
||||||
### 7. fileutil包支持文件基本操作。
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/fileutil"
|
import "github.com/duke-git/lancet/v2/fileutil"
|
||||||
@@ -251,38 +283,41 @@ import "github.com/duke-git/lancet/v2/fileutil"
|
|||||||
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#Zip)
|
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#Zip)
|
||||||
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#UnZip)
|
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#UnZip)
|
||||||
|
|
||||||
### 8. formatter格式化器包含一些数据格式化处理方法。
|
### 9. formatter 格式化器包含一些数据格式化处理方法。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/formatter"
|
import "github.com/duke-git/lancet/v2/formatter"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#Comma)
|
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#Comma)
|
||||||
|
|
||||||
|
### 10. function 函数包控制函数执行流程,包含部分函数式编程。
|
||||||
### 9. function函数包控制函数执行流程,包含部分函数式编程。
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/function"
|
import "github.com/duke-git/lancet/v2/function"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [After](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#After)
|
- [After](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#After)
|
||||||
- [Before](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Before)
|
- [Before](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Before)
|
||||||
- [Curry](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Curry)
|
- [Curry](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Curry)
|
||||||
- [Compose](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Compose)
|
- [Compose](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Compose)
|
||||||
- [Debounced](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Debounced)
|
- [Debounced](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Debounced)
|
||||||
- [Delay](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Delay)
|
- [Delay](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Delay)
|
||||||
|
- [Pipeline](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Pipeline)
|
||||||
- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Watcher)
|
- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Watcher)
|
||||||
|
|
||||||
|
### 11. maputil 包包括一些操作 map 的函数.
|
||||||
### 10. maputil包包括一些操作map的函数.
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/maputil"
|
import "github.com/duke-git/lancet/v2/maputil"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#ForEach)
|
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#ForEach)
|
||||||
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Filter)
|
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Filter)
|
||||||
- [Intersect](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Intersect)
|
- [Intersect](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Intersect)
|
||||||
@@ -290,14 +325,16 @@ import "github.com/duke-git/lancet/v2/maputil"
|
|||||||
- [Merge](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Merge)
|
- [Merge](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Merge)
|
||||||
- [Minus](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Minus)
|
- [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)
|
- [Values](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Values)
|
||||||
|
- [IsDisjoint](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#IsDisjoint)
|
||||||
|
|
||||||
### 11. mathutil包实现了一些数学计算的函数。
|
### 12. mathutil 包实现了一些数学计算的函数。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/mathutil"
|
import "github.com/duke-git/lancet/v2/mathutil"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [Average](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Average)
|
- [Average](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Average)
|
||||||
- [Exponent](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Exponent)
|
- [Exponent](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Exponent)
|
||||||
- [Fibonacci](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Fibonacci)
|
- [Fibonacci](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Fibonacci)
|
||||||
@@ -311,60 +348,76 @@ import "github.com/duke-git/lancet/v2/mathutil"
|
|||||||
- [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToString)
|
- [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToString)
|
||||||
- [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#TruncRound)
|
- [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#TruncRound)
|
||||||
|
|
||||||
### 12. netutil网络包支持获取ip地址,发送http请求。
|
### 13. netutil 网络包支持获取 ip 地址,发送 http 请求。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/netutil"
|
import "github.com/duke-git/lancet/v2/netutil"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ConvertMapToQueryString)
|
- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ConvertMapToQueryString)
|
||||||
- [GetInternalIp](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetInternalIp)
|
- [GetInternalIp](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetInternalIp)
|
||||||
|
- [EncodeUrl](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#EncodeUrl)
|
||||||
- [GetIps](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetIps)
|
- [GetIps](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetIps)
|
||||||
- [GetMacAddrs](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetMacAddrs)
|
- [GetMacAddrs](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetMacAddrs)
|
||||||
- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetPublicIpInfo)
|
- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetPublicIpInfo)
|
||||||
- [GetRequestPublicIp](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetRequestPublicIp)
|
- [GetRequestPublicIp](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetRequestPublicIp)
|
||||||
- [IsPublicIP](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#IsPublicIP)
|
- [IsPublicIP](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#IsPublicIP)
|
||||||
- [IsInternalIP](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#IsInternalIP)
|
- [IsInternalIP](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#IsInternalIP)
|
||||||
- [HttpGet](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpGet)
|
- [HttpRequest](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpRequest)
|
||||||
- [HttpDelete](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpDelete)
|
- [HttpClient](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpClient)
|
||||||
- [HttpPost](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPost)
|
- [SendRequest](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#SendRequest)
|
||||||
- [HttpPut](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPut)
|
- [DecodeResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#DecodeResponse)
|
||||||
- [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPatch)
|
- [StructToUrlValues](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#StructToUrlValues)
|
||||||
|
|
||||||
|
- [HttpGet<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpGet)
|
||||||
|
- [HttpDelete<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpDelete)
|
||||||
|
- [HttpPost<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPost)
|
||||||
|
- [HttpPut<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPut)
|
||||||
|
- [HttpPatch<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPatch)
|
||||||
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ParseHttpResponse)
|
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ParseHttpResponse)
|
||||||
|
|
||||||
### 13. random随机数生成器包,可以生成随机[]bytes, int, string。
|
### 14. random 随机数生成器包,可以生成随机[]bytes, int, string。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/random"
|
import "github.com/duke-git/lancet/v2/random"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [RandBytes](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandBytes)
|
- [RandBytes](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandBytes)
|
||||||
- [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandInt)
|
- [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandInt)
|
||||||
- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandString)
|
- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandString)
|
||||||
|
- [RandUpper](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandUpper)
|
||||||
|
- [RandLower](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandLower)
|
||||||
|
- [RandNumeral](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandNumeral)
|
||||||
|
- [RandNumeralOrLetter](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandNumeralOrLetter)
|
||||||
- [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4)
|
- [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4)
|
||||||
### 14. retry重试执行函数直到函数运行成功或被context cancel。
|
|
||||||
|
### 15. retry 重试执行函数直到函数运行成功或被 context cancel。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/retry"
|
import "github.com/duke-git/lancet/v2/retry"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [Context](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Context)
|
- [Context](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Context)
|
||||||
- [Retry](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Retry)
|
- [Retry](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Retry)
|
||||||
- [RetryFunc](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryFunc)
|
- [RetryFunc](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryFunc)
|
||||||
- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryDuration)
|
- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryDuration)
|
||||||
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryTimes)
|
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryTimes)
|
||||||
|
|
||||||
|
### 16. slice 包包含操作切片的方法集合。
|
||||||
### 15. slice包包含操作切片的方法集合。
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/slice"
|
import "github.com/duke-git/lancet/v2/slice"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
|
- [AppendIfAbsent](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#AppendIfAbsent)
|
||||||
- [Contain](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Contain)
|
- [Contain](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Contain)
|
||||||
- [ContainSubSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ContainSubSlice)
|
- [ContainSubSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ContainSubSlice)
|
||||||
- [Chunk](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Chunk)
|
- [Chunk](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Chunk)
|
||||||
@@ -380,7 +433,8 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Filter)
|
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Filter)
|
||||||
- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Find)
|
- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Find)
|
||||||
- [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#FindLast)
|
- [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#FindLast)
|
||||||
- [FlattenDeep](#FlattenDeep)
|
- [Flatten](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Flatten)
|
||||||
|
- [FlattenDeep](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#FlattenDeep)
|
||||||
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ForEach)
|
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ForEach)
|
||||||
- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupBy)
|
- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupBy)
|
||||||
- [GroupWith](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupWith)
|
- [GroupWith](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupWith)
|
||||||
@@ -393,6 +447,8 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Map)
|
- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Map)
|
||||||
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reverse)
|
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reverse)
|
||||||
- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reduce)
|
- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reduce)
|
||||||
|
- [Replace](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Replace)
|
||||||
|
- [ReplaceAll](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ReplaceAll)
|
||||||
- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Shuffle)
|
- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Shuffle)
|
||||||
- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SortByField)
|
- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SortByField)
|
||||||
- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Some)
|
- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Some)
|
||||||
@@ -403,11 +459,12 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Unique)
|
- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Unique)
|
||||||
- [UniqueBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UniqueBy)
|
- [UniqueBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UniqueBy)
|
||||||
- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Union)
|
- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Union)
|
||||||
|
- [UniqueBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UniqueBy)
|
||||||
- [UpdateAt](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UpdateAt)
|
- [UpdateAt](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UpdateAt)
|
||||||
- [Without](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Without)
|
- [Without](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Without)
|
||||||
|
- [KeyBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#KeyBy)
|
||||||
|
|
||||||
|
### 17. strutil 包含处理字符串的相关函数。
|
||||||
### 16. strutil包含处理字符串的相关函数。
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/strutil"
|
import "github.com/duke-git/lancet/v2/strutil"
|
||||||
@@ -427,20 +484,20 @@ import "github.com/duke-git/lancet/v2/strutil"
|
|||||||
- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#UpperFirst)
|
- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#UpperFirst)
|
||||||
- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadEnd)
|
- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadEnd)
|
||||||
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadStart)
|
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadStart)
|
||||||
- [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#ReverseStr)
|
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Reverse)
|
||||||
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SnakeCase)
|
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SnakeCase)
|
||||||
- [SplitEx](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SplitEx)
|
- [SplitEx](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SplitEx)
|
||||||
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Wrap)
|
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Wrap)
|
||||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Unwrap)
|
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Unwrap)
|
||||||
|
|
||||||
|
### 18. system 包含 os, runtime, shell command 相关函数。
|
||||||
### 17. system包含os, runtime, shell command相关函数。
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/system"
|
import "github.com/duke-git/lancet/v2/system"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [IsWindows](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsWindows)
|
- [IsWindows](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsWindows)
|
||||||
- [IsLinux](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsLinux)
|
- [IsLinux](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsLinux)
|
||||||
- [IsMac](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsMac)
|
- [IsMac](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsMac)
|
||||||
@@ -449,12 +506,14 @@ import "github.com/duke-git/lancet/v2/system"
|
|||||||
- [RemoveOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#RemoveOsEnv)
|
- [RemoveOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#RemoveOsEnv)
|
||||||
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#CompareOsEnv)
|
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#CompareOsEnv)
|
||||||
- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#ExecCommand)
|
- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#ExecCommand)
|
||||||
|
- [GetOsBits](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#GetOsBits)
|
||||||
|
|
||||||
### 18. validator验证器包,包含常用字符串格式验证函数。
|
### 19. validator 验证器包,包含常用字符串格式验证函数。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/validator"
|
import "github.com/duke-git/lancet/v2/validator"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [ContainChinese](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainChinese)
|
- [ContainChinese](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainChinese)
|
||||||
@@ -483,14 +542,16 @@ import "github.com/duke-git/lancet/v2/validator"
|
|||||||
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsStrongPassword)
|
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsStrongPassword)
|
||||||
- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsUrl)
|
- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsUrl)
|
||||||
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsWeakPassword)
|
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsWeakPassword)
|
||||||
|
- [IsZeroValue](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsZeroValue)
|
||||||
|
|
||||||
validator.md#IsWeakPassword)
|
### 20. xerror 包实现一些错误处理函数
|
||||||
### 19. xerror包实现一些错误处理函数
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/xerror"
|
import "github.com/duke-git/lancet/v2/xerror"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)
|
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)
|
||||||
|
|
||||||
## 如何贡献代码
|
## 如何贡献代码
|
||||||
|
|||||||
@@ -65,11 +65,15 @@ func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// QuickSort quick sorting for slice, lowIndex is 0 and highIndex is len(slice)-1
|
// QuickSort quick sorting for slice, lowIndex is 0 and highIndex is len(slice)-1
|
||||||
func QuickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) {
|
func QuickSort[T any](slice []T, comparator lancetconstraints.Comparator) {
|
||||||
|
quickSort(slice, 0, len(slice)-1, comparator)
|
||||||
|
}
|
||||||
|
|
||||||
|
func quickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) {
|
||||||
if lowIndex < highIndex {
|
if lowIndex < highIndex {
|
||||||
p := partition(slice, lowIndex, highIndex, comparator)
|
p := partition(slice, lowIndex, highIndex, comparator)
|
||||||
QuickSort(slice, lowIndex, p-1, comparator)
|
quickSort(slice, lowIndex, p-1, comparator)
|
||||||
QuickSort(slice, p+1, highIndex, comparator)
|
quickSort(slice, p+1, highIndex, comparator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,14 +30,6 @@ func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// var peoples = []people{
|
|
||||||
// {Name: "a", Age: 20},
|
|
||||||
// {Name: "b", Age: 10},
|
|
||||||
// {Name: "c", Age: 17},
|
|
||||||
// {Name: "d", Age: 8},
|
|
||||||
// {Name: "e", Age: 28},
|
|
||||||
// }
|
|
||||||
|
|
||||||
type intComparator struct{}
|
type intComparator struct{}
|
||||||
|
|
||||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||||
@@ -53,8 +45,6 @@ func (c *intComparator) Compare(v1 any, v2 any) int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// var intSlice = []int{2, 1, 5, 3, 6, 4}
|
|
||||||
|
|
||||||
func TestBubbleSortForStructSlice(t *testing.T) {
|
func TestBubbleSortForStructSlice(t *testing.T) {
|
||||||
asssert := internal.NewAssert(t, "TestBubbleSortForStructSlice")
|
asssert := internal.NewAssert(t, "TestBubbleSortForStructSlice")
|
||||||
|
|
||||||
@@ -151,7 +141,7 @@ func TestQuickSort(t *testing.T) {
|
|||||||
{Name: "e", Age: 28},
|
{Name: "e", Age: 28},
|
||||||
}
|
}
|
||||||
comparator := &peopleAgeComparator{}
|
comparator := &peopleAgeComparator{}
|
||||||
QuickSort(peoples, 0, len(peoples)-1, comparator)
|
QuickSort(peoples, comparator)
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
||||||
actual := fmt.Sprintf("%v", peoples)
|
actual := fmt.Sprintf("%v", peoples)
|
||||||
77
condition/condition.go
Normal file
77
condition/condition.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
// Package condition contains some functions for conditional judgment. eg. And, Or, TernaryOperator ...
|
||||||
|
// The implementation of this package refers to the implementation of carlmjohnson's truthy package, you may find more
|
||||||
|
// useful information in truthy(https://github.com/carlmjohnson/truthy), thanks carlmjohnson.
|
||||||
|
package condition
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
// Bool returns the truthy value of anything.
|
||||||
|
// If the value's type has a Bool() bool method, the method is called and returned.
|
||||||
|
// If the type has an IsZero() bool method, the opposite value is returned.
|
||||||
|
// Slices and maps are truthy if they have a length greater than zero.
|
||||||
|
// All other types are truthy if they are not their zero value.
|
||||||
|
func Bool[T any](value T) bool {
|
||||||
|
switch m := any(value).(type) {
|
||||||
|
case interface{ Bool() bool }:
|
||||||
|
return m.Bool()
|
||||||
|
case interface{ IsZero() bool }:
|
||||||
|
return !m.IsZero()
|
||||||
|
}
|
||||||
|
return reflectValue(&value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func reflectValue(vp any) bool {
|
||||||
|
switch rv := reflect.ValueOf(vp).Elem(); rv.Kind() {
|
||||||
|
case reflect.Map, reflect.Slice:
|
||||||
|
return rv.Len() != 0
|
||||||
|
default:
|
||||||
|
is := rv.IsZero()
|
||||||
|
return !is
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// And returns true if both a and b are truthy.
|
||||||
|
func And[T, U any](a T, b U) bool {
|
||||||
|
return Bool(a) && Bool(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Or returns false iff neither a nor b is truthy.
|
||||||
|
func Or[T, U any](a T, b U) bool {
|
||||||
|
return Bool(a) || Bool(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Xor returns true iff a or b but not both is truthy.
|
||||||
|
func Xor[T, U any](a T, b U) bool {
|
||||||
|
valA := Bool(a)
|
||||||
|
valB := Bool(b)
|
||||||
|
return (valA || valB) && valA != valB
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nor returns true iff neither a nor b is truthy.
|
||||||
|
func Nor[T, U any](a T, b U) bool {
|
||||||
|
return !(Bool(a) || Bool(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Xnor returns true iff both a and b or neither a nor b are truthy.
|
||||||
|
func Xnor[T, U any](a T, b U) bool {
|
||||||
|
valA := Bool(a)
|
||||||
|
valB := Bool(b)
|
||||||
|
return (valA && valB) || (!valA && !valB)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nand returns false iff both a and b are truthy.
|
||||||
|
func Nand[T, U any](a T, b U) bool {
|
||||||
|
return !Bool(a) || !Bool(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TernaryOperator checks the value of param `isTrue`, if true return ifValue else return elseValue
|
||||||
|
func TernaryOperator[T, U any](isTrue T, ifValue U, elseValue U) U {
|
||||||
|
if Bool(isTrue) {
|
||||||
|
return ifValue
|
||||||
|
} else {
|
||||||
|
return elseValue
|
||||||
|
}
|
||||||
|
}
|
||||||
119
condition/condition_test.go
Normal file
119
condition/condition_test.go
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
package condition
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestStruct struct{}
|
||||||
|
|
||||||
|
func TestBool(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestBool")
|
||||||
|
|
||||||
|
// bool
|
||||||
|
assert.Equal(false, Bool(false))
|
||||||
|
assert.Equal(true, Bool(true))
|
||||||
|
|
||||||
|
// integer
|
||||||
|
assert.Equal(false, Bool(0))
|
||||||
|
assert.Equal(true, Bool(1))
|
||||||
|
|
||||||
|
// float
|
||||||
|
assert.Equal(false, Bool(0.0))
|
||||||
|
assert.Equal(true, Bool(0.1))
|
||||||
|
|
||||||
|
// string
|
||||||
|
assert.Equal(false, Bool(""))
|
||||||
|
assert.Equal(true, Bool(" "))
|
||||||
|
assert.Equal(true, Bool("0"))
|
||||||
|
|
||||||
|
// slice
|
||||||
|
var nums [2]int
|
||||||
|
assert.Equal(false, Bool(nums))
|
||||||
|
nums = [2]int{0, 1}
|
||||||
|
assert.Equal(true, Bool(nums))
|
||||||
|
|
||||||
|
// map
|
||||||
|
assert.Equal(false, Bool(map[string]string{}))
|
||||||
|
assert.Equal(true, Bool(map[string]string{"a": "a"}))
|
||||||
|
|
||||||
|
// channel
|
||||||
|
var ch chan int
|
||||||
|
assert.Equal(false, Bool(ch))
|
||||||
|
ch = make(chan int)
|
||||||
|
assert.Equal(true, Bool(ch))
|
||||||
|
|
||||||
|
// interface
|
||||||
|
var err error
|
||||||
|
assert.Equal(false, Bool(err))
|
||||||
|
err = errors.New("error message")
|
||||||
|
assert.Equal(true, Bool(err))
|
||||||
|
|
||||||
|
// struct
|
||||||
|
assert.Equal(false, Bool(struct{}{}))
|
||||||
|
assert.Equal(true, Bool(time.Now()))
|
||||||
|
|
||||||
|
// struct pointer
|
||||||
|
ts := TestStruct{}
|
||||||
|
assert.Equal(false, Bool(ts))
|
||||||
|
assert.Equal(true, Bool(&ts))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnd(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestAnd")
|
||||||
|
assert.Equal(false, And(0, 1))
|
||||||
|
assert.Equal(false, And(0, ""))
|
||||||
|
assert.Equal(false, And(0, "0"))
|
||||||
|
assert.Equal(true, And(1, "0"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOr(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestOr")
|
||||||
|
assert.Equal(false, Or(0, ""))
|
||||||
|
assert.Equal(true, Or(0, 1))
|
||||||
|
assert.Equal(true, Or(0, "0"))
|
||||||
|
assert.Equal(true, Or(1, "0"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXor(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestOr")
|
||||||
|
assert.Equal(false, Xor(0, 0))
|
||||||
|
assert.Equal(true, Xor(0, 1))
|
||||||
|
assert.Equal(true, Xor(1, 0))
|
||||||
|
assert.Equal(false, Xor(1, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNor(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestNor")
|
||||||
|
assert.Equal(true, Nor(0, 0))
|
||||||
|
assert.Equal(false, Nor(0, 1))
|
||||||
|
assert.Equal(false, Nor(1, 0))
|
||||||
|
assert.Equal(false, Nor(1, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXnor(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestXnor")
|
||||||
|
assert.Equal(true, Xnor(0, 0))
|
||||||
|
assert.Equal(false, Xnor(0, 1))
|
||||||
|
assert.Equal(false, Xnor(1, 0))
|
||||||
|
assert.Equal(true, Xnor(1, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNand(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestNand")
|
||||||
|
assert.Equal(true, Nand(0, 0))
|
||||||
|
assert.Equal(true, Nand(0, 1))
|
||||||
|
assert.Equal(true, Nand(1, 0))
|
||||||
|
assert.Equal(false, Nand(1, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTernaryOperator(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TernaryOperator")
|
||||||
|
trueValue := "1"
|
||||||
|
falseValue := "0"
|
||||||
|
|
||||||
|
assert.Equal(trueValue, TernaryOperator(true, trueValue, falseValue))
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ package convertor
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/gob"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
@@ -90,70 +91,70 @@ func ToChannel[T any](array []T) <-chan T {
|
|||||||
|
|
||||||
// ToString convert value to string
|
// ToString convert value to string
|
||||||
func ToString(value any) string {
|
func ToString(value any) string {
|
||||||
res := ""
|
result := ""
|
||||||
if value == nil {
|
if value == nil {
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
v := reflect.ValueOf(value)
|
v := reflect.ValueOf(value)
|
||||||
|
|
||||||
switch value.(type) {
|
switch value.(type) {
|
||||||
case float32, float64:
|
case float32, float64:
|
||||||
res = strconv.FormatFloat(v.Float(), 'f', -1, 64)
|
result = strconv.FormatFloat(v.Float(), 'f', -1, 64)
|
||||||
return res
|
return result
|
||||||
case int, int8, int16, int32, int64:
|
case int, int8, int16, int32, int64:
|
||||||
res = strconv.FormatInt(v.Int(), 10)
|
result = strconv.FormatInt(v.Int(), 10)
|
||||||
return res
|
return result
|
||||||
case uint, uint8, uint16, uint32, uint64:
|
case uint, uint8, uint16, uint32, uint64:
|
||||||
res = strconv.FormatUint(v.Uint(), 10)
|
result = strconv.FormatUint(v.Uint(), 10)
|
||||||
return res
|
return result
|
||||||
case string:
|
case string:
|
||||||
res = v.String()
|
result = v.String()
|
||||||
return res
|
return result
|
||||||
case []byte:
|
case []byte:
|
||||||
res = string(v.Bytes())
|
result = string(v.Bytes())
|
||||||
return res
|
return result
|
||||||
default:
|
default:
|
||||||
newValue, _ := json.Marshal(value)
|
newValue, _ := json.Marshal(value)
|
||||||
res = string(newValue)
|
result = string(newValue)
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToJson convert value to a valid json string
|
// ToJson convert value to a valid json string
|
||||||
func ToJson(value any) (string, error) {
|
func ToJson(value any) (string, error) {
|
||||||
res, err := json.Marshal(value)
|
result, err := json.Marshal(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(res), nil
|
return string(result), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToFloat convert value to a float64, if input is not a float return 0.0 and error
|
// ToFloat convert value to a float64, if input is not a float return 0.0 and error
|
||||||
func ToFloat(value any) (float64, error) {
|
func ToFloat(value any) (float64, error) {
|
||||||
v := reflect.ValueOf(value)
|
v := reflect.ValueOf(value)
|
||||||
|
|
||||||
res := 0.0
|
result := 0.0
|
||||||
err := fmt.Errorf("ToInt: unvalid interface type %T", value)
|
err := fmt.Errorf("ToInt: unvalid interface type %T", value)
|
||||||
switch value.(type) {
|
switch value.(type) {
|
||||||
case int, int8, int16, int32, int64:
|
case int, int8, int16, int32, int64:
|
||||||
res = float64(v.Int())
|
result = float64(v.Int())
|
||||||
return res, nil
|
return result, nil
|
||||||
case uint, uint8, uint16, uint32, uint64:
|
case uint, uint8, uint16, uint32, uint64:
|
||||||
res = float64(v.Uint())
|
result = float64(v.Uint())
|
||||||
return res, nil
|
return result, nil
|
||||||
case float32, float64:
|
case float32, float64:
|
||||||
res = v.Float()
|
result = v.Float()
|
||||||
return res, nil
|
return result, nil
|
||||||
case string:
|
case string:
|
||||||
res, err = strconv.ParseFloat(v.String(), 64)
|
result, err = strconv.ParseFloat(v.String(), 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res = 0.0
|
result = 0.0
|
||||||
}
|
}
|
||||||
return res, err
|
return result, err
|
||||||
default:
|
default:
|
||||||
return res, err
|
return result, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,26 +162,26 @@ func ToFloat(value any) (float64, error) {
|
|||||||
func ToInt(value any) (int64, error) {
|
func ToInt(value any) (int64, error) {
|
||||||
v := reflect.ValueOf(value)
|
v := reflect.ValueOf(value)
|
||||||
|
|
||||||
var res int64
|
var result int64
|
||||||
err := fmt.Errorf("ToInt: invalid interface type %T", value)
|
err := fmt.Errorf("ToInt: invalid interface type %T", value)
|
||||||
switch value.(type) {
|
switch value.(type) {
|
||||||
case int, int8, int16, int32, int64:
|
case int, int8, int16, int32, int64:
|
||||||
res = v.Int()
|
result = v.Int()
|
||||||
return res, nil
|
return result, nil
|
||||||
case uint, uint8, uint16, uint32, uint64:
|
case uint, uint8, uint16, uint32, uint64:
|
||||||
res = int64(v.Uint())
|
result = int64(v.Uint())
|
||||||
return res, nil
|
return result, nil
|
||||||
case float32, float64:
|
case float32, float64:
|
||||||
res = int64(v.Float())
|
result = int64(v.Float())
|
||||||
return res, nil
|
return result, nil
|
||||||
case string:
|
case string:
|
||||||
res, err = strconv.ParseInt(v.String(), 0, 64)
|
result, err = strconv.ParseInt(v.String(), 0, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res = 0
|
result = 0
|
||||||
}
|
}
|
||||||
return res, err
|
return result, err
|
||||||
default:
|
default:
|
||||||
return res, err
|
return result, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,13 +192,13 @@ func ToPointer[T any](value T) *T {
|
|||||||
|
|
||||||
// ToMap convert a slice or an array of structs to a map based on iteratee function
|
// ToMap convert a slice or an array of structs to a map based on iteratee function
|
||||||
func ToMap[T any, K comparable, V any](array []T, iteratee func(T) (K, V)) map[K]V {
|
func ToMap[T any, K comparable, V any](array []T, iteratee func(T) (K, V)) map[K]V {
|
||||||
res := make(map[K]V, len(array))
|
result := make(map[K]V, len(array))
|
||||||
for _, item := range array {
|
for _, item := range array {
|
||||||
k, v := iteratee(item)
|
k, v := iteratee(item)
|
||||||
res[k] = v
|
result[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// StructToMap convert struct to map, only convert exported struct field
|
// StructToMap convert struct to map, only convert exported struct field
|
||||||
@@ -213,7 +214,7 @@ func StructToMap(value any) (map[string]any, error) {
|
|||||||
return nil, fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", value)
|
return nil, fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
res := make(map[string]any)
|
result := make(map[string]any)
|
||||||
|
|
||||||
fieldNum := t.NumField()
|
fieldNum := t.NumField()
|
||||||
pattern := `^[A-Z]`
|
pattern := `^[A-Z]`
|
||||||
@@ -222,23 +223,23 @@ func StructToMap(value any) (map[string]any, error) {
|
|||||||
name := t.Field(i).Name
|
name := t.Field(i).Name
|
||||||
tag := t.Field(i).Tag.Get("json")
|
tag := t.Field(i).Tag.Get("json")
|
||||||
if regex.MatchString(name) && tag != "" {
|
if regex.MatchString(name) && tag != "" {
|
||||||
//res[name] = v.Field(i).Interface()
|
//result[name] = v.Field(i).Interface()
|
||||||
res[tag] = v.Field(i).Interface()
|
result[tag] = v.Field(i).Interface()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MapToSlice convert a map to a slice based on iteratee function
|
// MapToSlice convert a map to a slice based on iteratee function
|
||||||
func MapToSlice[T any, K comparable, V any](aMap map[K]V, iteratee func(K, V) T) []T {
|
func MapToSlice[T any, K comparable, V any](aMap map[K]V, iteratee func(K, V) T) []T {
|
||||||
res := make([]T, 0, len(aMap))
|
result := make([]T, 0, len(aMap))
|
||||||
|
|
||||||
for k, v := range aMap {
|
for k, v := range aMap {
|
||||||
res = append(res, iteratee(k, v))
|
result = append(result, iteratee(k, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// ColorHexToRGB convert hex color to rgb color
|
// ColorHexToRGB convert hex color to rgb color
|
||||||
@@ -270,3 +271,21 @@ func ColorRGBToHex(red, green, blue int) string {
|
|||||||
|
|
||||||
return "#" + r + g + b
|
return "#" + r + g + b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EncodeByte encode data to byte
|
||||||
|
func EncodeByte(data any) ([]byte, error) {
|
||||||
|
buffer := bytes.NewBuffer(nil)
|
||||||
|
encoder := gob.NewEncoder(buffer)
|
||||||
|
err := encoder.Encode(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buffer.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeByte decode byte data to target object
|
||||||
|
func DecodeByte(data []byte, target any) error {
|
||||||
|
buffer := bytes.NewBuffer(data)
|
||||||
|
decoder := gob.NewDecoder(buffer)
|
||||||
|
return decoder.Decode(target)
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestToChar(t *testing.T) {
|
func TestToChar(t *testing.T) {
|
||||||
@@ -204,7 +205,10 @@ func TestMapToSlice(t *testing.T) {
|
|||||||
return key + ":" + strconv.Itoa(value)
|
return key + ":" + strconv.Itoa(value)
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.Equal([]string{"a:1", "b:2", "c:3"}, result)
|
assert.Equal(3, len(result))
|
||||||
|
assert.Equal(true, slice.Contain(result, "a:1"))
|
||||||
|
assert.Equal(true, slice.Contain(result, "b:2"))
|
||||||
|
assert.Equal(true, slice.Contain(result, "c:3"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestColorHexToRGB(t *testing.T) {
|
func TestColorHexToRGB(t *testing.T) {
|
||||||
@@ -234,3 +238,21 @@ func TestToPointer(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(*result, 123)
|
assert.Equal(*result, 123)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEncodeByte(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestEncodeByte")
|
||||||
|
|
||||||
|
byteData, _ := EncodeByte("abc")
|
||||||
|
expected := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
|
||||||
|
assert.Equal(expected, byteData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDecodeByte(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestDecodeByte")
|
||||||
|
|
||||||
|
var obj string
|
||||||
|
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
DecodeByte(byteData, &obj)
|
||||||
|
assert.Equal("abc", obj)
|
||||||
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func AesEcbEncrypt(data, key []byte) []byte {
|
|||||||
func AesEcbDecrypt(encrypted, key []byte) []byte {
|
func AesEcbDecrypt(encrypted, key []byte) []byte {
|
||||||
cipher, _ := aes.NewCipher(generateAesKey(key))
|
cipher, _ := aes.NewCipher(generateAesKey(key))
|
||||||
decrypted := make([]byte, len(encrypted))
|
decrypted := make([]byte, len(encrypted))
|
||||||
//
|
|
||||||
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||||
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
|
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
|
||||||
}
|
}
|
||||||
@@ -54,14 +54,18 @@ func AesEcbDecrypt(encrypted, key []byte) []byte {
|
|||||||
// AesCbcEncrypt encrypt data with key use AES CBC algorithm
|
// AesCbcEncrypt encrypt data with key use AES CBC algorithm
|
||||||
// len(key) should be 16, 24 or 32
|
// len(key) should be 16, 24 or 32
|
||||||
func AesCbcEncrypt(data, key []byte) []byte {
|
func AesCbcEncrypt(data, key []byte) []byte {
|
||||||
// len(key) should be 16, 24 or 32
|
|
||||||
block, _ := aes.NewCipher(key)
|
block, _ := aes.NewCipher(key)
|
||||||
blockSize := block.BlockSize()
|
data = pkcs7Padding(data, block.BlockSize())
|
||||||
data = pkcs7Padding(data, blockSize)
|
|
||||||
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
|
encrypted := make([]byte, aes.BlockSize+len(data))
|
||||||
|
iv := encrypted[:aes.BlockSize]
|
||||||
|
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mode := cipher.NewCBCEncrypter(block, iv)
|
||||||
|
mode.CryptBlocks(encrypted[aes.BlockSize:], data)
|
||||||
|
|
||||||
encrypted := make([]byte, len(data))
|
|
||||||
blockMode.CryptBlocks(encrypted, data)
|
|
||||||
return encrypted
|
return encrypted
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,12 +73,14 @@ func AesCbcEncrypt(data, key []byte) []byte {
|
|||||||
// len(key) should be 16, 24 or 32
|
// len(key) should be 16, 24 or 32
|
||||||
func AesCbcDecrypt(encrypted, key []byte) []byte {
|
func AesCbcDecrypt(encrypted, key []byte) []byte {
|
||||||
block, _ := aes.NewCipher(key)
|
block, _ := aes.NewCipher(key)
|
||||||
blockSize := block.BlockSize()
|
|
||||||
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
|
|
||||||
|
|
||||||
decrypted := make([]byte, len(encrypted))
|
iv := encrypted[:aes.BlockSize]
|
||||||
blockMode.CryptBlocks(decrypted, encrypted)
|
encrypted = encrypted[aes.BlockSize:]
|
||||||
decrypted = pkcs7UnPadding(decrypted)
|
|
||||||
|
mode := cipher.NewCBCDecrypter(block, iv)
|
||||||
|
mode.CryptBlocks(encrypted, encrypted)
|
||||||
|
|
||||||
|
decrypted := pkcs7UnPadding(encrypted)
|
||||||
return decrypted
|
return decrypted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,12 +55,16 @@ func DesEcbDecrypt(encrypted, key []byte) []byte {
|
|||||||
// len(key) should be 8
|
// len(key) should be 8
|
||||||
func DesCbcEncrypt(data, key []byte) []byte {
|
func DesCbcEncrypt(data, key []byte) []byte {
|
||||||
block, _ := des.NewCipher(key)
|
block, _ := des.NewCipher(key)
|
||||||
blockSize := block.BlockSize()
|
data = pkcs7Padding(data, block.BlockSize())
|
||||||
data = pkcs7Padding(data, blockSize)
|
|
||||||
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
|
|
||||||
|
|
||||||
encrypted := make([]byte, len(data))
|
encrypted := make([]byte, des.BlockSize+len(data))
|
||||||
blockMode.CryptBlocks(encrypted, data)
|
iv := encrypted[:des.BlockSize]
|
||||||
|
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mode := cipher.NewCBCEncrypter(block, iv)
|
||||||
|
mode.CryptBlocks(encrypted[des.BlockSize:], data)
|
||||||
|
|
||||||
return encrypted
|
return encrypted
|
||||||
}
|
}
|
||||||
@@ -69,13 +73,14 @@ func DesCbcEncrypt(data, key []byte) []byte {
|
|||||||
// len(key) should be 8
|
// len(key) should be 8
|
||||||
func DesCbcDecrypt(encrypted, key []byte) []byte {
|
func DesCbcDecrypt(encrypted, key []byte) []byte {
|
||||||
block, _ := des.NewCipher(key)
|
block, _ := des.NewCipher(key)
|
||||||
blockSize := block.BlockSize()
|
|
||||||
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
|
|
||||||
|
|
||||||
decrypted := make([]byte, len(encrypted))
|
iv := encrypted[:des.BlockSize]
|
||||||
blockMode.CryptBlocks(decrypted, encrypted)
|
encrypted = encrypted[des.BlockSize:]
|
||||||
decrypted = pkcs7UnPadding(decrypted)
|
|
||||||
|
|
||||||
|
mode := cipher.NewCBCDecrypter(block, iv)
|
||||||
|
mode.CryptBlocks(encrypted, encrypted)
|
||||||
|
|
||||||
|
decrypted := pkcs7UnPadding(encrypted)
|
||||||
return decrypted
|
return decrypted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
175
datastructure/hashmap/hashmap.go
Normal file
175
datastructure/hashmap/hashmap.go
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
// Package datastructure implements some data structure. eg. list, linklist, stack, queue, tree, graph.
|
||||||
|
package datastructure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"hash/fnv"
|
||||||
|
)
|
||||||
|
|
||||||
|
var defaultMapCapacity uint64 = 1 << 10
|
||||||
|
|
||||||
|
type mapNode struct {
|
||||||
|
key any
|
||||||
|
value any
|
||||||
|
next *mapNode
|
||||||
|
}
|
||||||
|
|
||||||
|
//HashMap implements a hash map
|
||||||
|
type HashMap struct {
|
||||||
|
capacity uint64
|
||||||
|
size uint64
|
||||||
|
table []*mapNode
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHashMap return a HashMap instance
|
||||||
|
func NewHashMap() *HashMap {
|
||||||
|
return &HashMap{
|
||||||
|
capacity: defaultMapCapacity,
|
||||||
|
table: make([]*mapNode, defaultMapCapacity),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHashMapWithCapacity return a HashMap instance with given size and capacity
|
||||||
|
func NewHashMapWithCapacity(size, capacity uint64) *HashMap {
|
||||||
|
return &HashMap{
|
||||||
|
size: size,
|
||||||
|
capacity: capacity,
|
||||||
|
table: make([]*mapNode, capacity),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get return the value of given key in hashmap
|
||||||
|
func (hm *HashMap) Get(key any) any {
|
||||||
|
hashValue := hm.hash(key)
|
||||||
|
node := hm.table[hashValue]
|
||||||
|
if node != nil {
|
||||||
|
return node.value
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put new key value in hashmap
|
||||||
|
func (hm *HashMap) Put(key any, value any) {
|
||||||
|
hm.putValue(hm.hash(key), key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hm *HashMap) putValue(hash uint64, key, value any) {
|
||||||
|
if hm.capacity == 0 {
|
||||||
|
hm.capacity = defaultMapCapacity
|
||||||
|
hm.table = make([]*mapNode, defaultMapCapacity)
|
||||||
|
}
|
||||||
|
|
||||||
|
node := hm.table[hash]
|
||||||
|
if node == nil {
|
||||||
|
hm.table[hash] = newMapNode(key, value)
|
||||||
|
} else if node.key == key {
|
||||||
|
hm.table[hash] = newMapNodeWithNext(key, value, node)
|
||||||
|
} else {
|
||||||
|
hm.resize()
|
||||||
|
hm.putValue(hash, value, value)
|
||||||
|
}
|
||||||
|
hm.size++
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete item by given key in hashmap
|
||||||
|
func (hm *HashMap) Delete(key any) {
|
||||||
|
hash := hm.hash(key)
|
||||||
|
node := hm.table[hash]
|
||||||
|
if node == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hm.table = append(hm.table[:hash], hm.table[hash+1:]...)
|
||||||
|
hm.size--
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contains checks if given key is in hashmap or not
|
||||||
|
func (hm *HashMap) Contains(key any) bool {
|
||||||
|
node := hm.table[hm.hash(key)]
|
||||||
|
return node != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate executes iteratee funcation for every key and value pair of hashmap (random order)
|
||||||
|
func (hm *HashMap) Iterate(iteratee func(key, value any)) {
|
||||||
|
if hm.size > 0 {
|
||||||
|
for i := 0; i < len(hm.table); i++ {
|
||||||
|
item := hm.table[i]
|
||||||
|
if item != nil {
|
||||||
|
iteratee(item.key, item.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keys returns a slice of the hashmap's keys (random order)
|
||||||
|
func (hm *HashMap) Keys() []any {
|
||||||
|
keys := make([]any, int(hm.size))
|
||||||
|
index := 0
|
||||||
|
if hm.size > 0 {
|
||||||
|
hm.Iterate(func(key, value any) {
|
||||||
|
keys[index] = key
|
||||||
|
index++
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values returns a slice of the hashmap's keys (random order)
|
||||||
|
func (hm *HashMap) Values() []any {
|
||||||
|
values := make([]any, int(hm.size))
|
||||||
|
index := 0
|
||||||
|
if hm.size > 0 {
|
||||||
|
hm.Iterate(func(key, value any) {
|
||||||
|
values[index] = value
|
||||||
|
index++
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hm *HashMap) resize() {
|
||||||
|
hm.capacity <<= 1
|
||||||
|
|
||||||
|
tempTable := hm.table
|
||||||
|
|
||||||
|
hm.table = make([]*mapNode, hm.capacity)
|
||||||
|
|
||||||
|
for i := 0; i < len(tempTable); i++ {
|
||||||
|
node := tempTable[i]
|
||||||
|
if node == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
hm.table[hm.hash(node.key)] = node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hm *HashMap) hash(key any) uint64 {
|
||||||
|
h := fnv.New64a()
|
||||||
|
_, _ = h.Write([]byte(fmt.Sprintf("%v", key)))
|
||||||
|
|
||||||
|
hashValue := h.Sum64()
|
||||||
|
|
||||||
|
return (hm.capacity - 1) & (hashValue ^ (hashValue >> 16))
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMapNode(key, value any) *mapNode {
|
||||||
|
return &mapNode{
|
||||||
|
key: key,
|
||||||
|
value: value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMapNodeWithNext(key, value any, next *mapNode) *mapNode {
|
||||||
|
return &mapNode{
|
||||||
|
key: key,
|
||||||
|
value: value,
|
||||||
|
next: next,
|
||||||
|
}
|
||||||
|
}
|
||||||
71
datastructure/hashmap/hashmap_test.go
Normal file
71
datastructure/hashmap/hashmap_test.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
package datastructure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHashMap_PutAndGet(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestHashMap_PutAndGet")
|
||||||
|
|
||||||
|
hm := NewHashMap()
|
||||||
|
|
||||||
|
hm.Put("abc", 3)
|
||||||
|
assert.Equal(3, hm.Get("abc"))
|
||||||
|
assert.IsNil(hm.Get("abcd"))
|
||||||
|
|
||||||
|
hm.Put("abc", 4)
|
||||||
|
assert.Equal(4, hm.Get("abc"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHashMap_Resize(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestHashMap_Resize")
|
||||||
|
|
||||||
|
hm := NewHashMapWithCapacity(3, 3)
|
||||||
|
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
hm.Put(i, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(10, hm.Get(5))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHashMap_Delete(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestHashMap_Delete")
|
||||||
|
|
||||||
|
hm := NewHashMap()
|
||||||
|
|
||||||
|
hm.Put("abc", 3)
|
||||||
|
assert.Equal(3, hm.Get("abc"))
|
||||||
|
|
||||||
|
hm.Delete("abc")
|
||||||
|
assert.IsNil(hm.Get("abc"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHashMap_Contains(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestHashMap_Contains")
|
||||||
|
|
||||||
|
hm := NewHashMap()
|
||||||
|
assert.Equal(false, hm.Contains("abc"))
|
||||||
|
|
||||||
|
hm.Put("abc", 3)
|
||||||
|
assert.Equal(true, hm.Contains("abc"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHashMap_KeysValues(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestHashMap_KeysValues")
|
||||||
|
|
||||||
|
hm := NewHashMap()
|
||||||
|
|
||||||
|
hm.Put("a", 1)
|
||||||
|
hm.Put("b", 2)
|
||||||
|
hm.Put("c", 3)
|
||||||
|
|
||||||
|
keys := hm.Keys()
|
||||||
|
values := hm.Values()
|
||||||
|
t.Log(keys, values)
|
||||||
|
|
||||||
|
assert.Equal(3, len(values))
|
||||||
|
assert.Equal(3, len(keys))
|
||||||
|
}
|
||||||
@@ -25,6 +25,20 @@ func NewMaxHeap[T any](comparator lancetconstraints.Comparator) *MaxHeap[T] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildMaxHeap builds a MaxHeap instance with data and given comparator.
|
||||||
|
func BuildMaxHeap[T any](data []T, comparator lancetconstraints.Comparator) *MaxHeap[T] {
|
||||||
|
heap := &MaxHeap[T]{
|
||||||
|
data: make([]T, 0, len(data)),
|
||||||
|
comparator: comparator,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range data {
|
||||||
|
heap.Push(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return heap
|
||||||
|
}
|
||||||
|
|
||||||
// Push value into the heap
|
// Push value into the heap
|
||||||
func (h *MaxHeap[T]) Push(value T) {
|
func (h *MaxHeap[T]) Push(value T) {
|
||||||
h.data = append(h.data, value)
|
h.data = append(h.data, value)
|
||||||
|
|||||||
@@ -20,6 +20,20 @@ func (c *intComparator) Compare(v1, v2 any) int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMaxHeap_BuildMaxHeap(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestMaxHeap_BuildMaxHeap")
|
||||||
|
|
||||||
|
values := []int{6, 5, 2, 4, 7, 10, 12, 1, 3, 8, 9, 11}
|
||||||
|
heap := BuildMaxHeap(values, &intComparator{})
|
||||||
|
|
||||||
|
expected := []int{12, 9, 11, 4, 8, 10, 7, 1, 3, 5, 6, 2}
|
||||||
|
assert.Equal(expected, heap.data)
|
||||||
|
|
||||||
|
assert.Equal(12, heap.Size())
|
||||||
|
|
||||||
|
heap.PrintStructure()
|
||||||
|
}
|
||||||
|
|
||||||
func TestMaxHeap_Push(t *testing.T) {
|
func TestMaxHeap_Push(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestMaxHeap_Push")
|
assert := internal.NewAssert(t, "TestMaxHeap_Push")
|
||||||
|
|
||||||
|
|||||||
@@ -208,13 +208,13 @@ func (link *DoublyLink[T]) Size() int {
|
|||||||
|
|
||||||
// Values return slice of all doubly linklist node value
|
// Values return slice of all doubly linklist node value
|
||||||
func (link *DoublyLink[T]) Values() []T {
|
func (link *DoublyLink[T]) Values() []T {
|
||||||
res := []T{}
|
result := []T{}
|
||||||
current := link.Head
|
current := link.Head
|
||||||
for current != nil {
|
for current != nil {
|
||||||
res = append(res, current.Value)
|
result = append(result, current.Value)
|
||||||
current = current.Next
|
current = current.Next
|
||||||
}
|
}
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print all nodes info of a linked list
|
// Print all nodes info of a linked list
|
||||||
|
|||||||
@@ -213,13 +213,13 @@ func (link *SinglyLink[T]) Size() int {
|
|||||||
|
|
||||||
// Values return slice of all singly linklist node value
|
// Values return slice of all singly linklist node value
|
||||||
func (link *SinglyLink[T]) Values() []T {
|
func (link *SinglyLink[T]) Values() []T {
|
||||||
res := []T{}
|
result := []T{}
|
||||||
current := link.Head
|
current := link.Head
|
||||||
for current != nil {
|
for current != nil {
|
||||||
res = append(res, current.Value)
|
result = append(result, current.Value)
|
||||||
current = current.Next
|
current = current.Next
|
||||||
}
|
}
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty checks if link is empty or not
|
// IsEmpty checks if link is empty or not
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ func (l *List[T]) ValueOf(index int) (*T, bool) {
|
|||||||
return &l.data[index], true
|
return &l.data[index], true
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexOf reture the index of value. if not found return -1
|
// IndexOf returns the index of value. if not found return -1
|
||||||
func (l *List[T]) IndexOf(value T) int {
|
func (l *List[T]) IndexOf(value T) int {
|
||||||
index := -1
|
index := -1
|
||||||
data := l.data
|
data := l.data
|
||||||
@@ -44,6 +44,48 @@ func (l *List[T]) IndexOf(value T) int {
|
|||||||
return index
|
return index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LastIndexOf returns the index of the last occurrence of the value in this list.
|
||||||
|
// if not found return -1
|
||||||
|
func (l *List[T]) LastIndexOf(value T) int {
|
||||||
|
index := -1
|
||||||
|
data := l.data
|
||||||
|
for i := len(data) - 1; i >= 0; i-- {
|
||||||
|
if reflect.DeepEqual(data[i], value) {
|
||||||
|
index = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
// IndexOfFunc returns the first index satisfying f(v)
|
||||||
|
// if not found return -1
|
||||||
|
func (l *List[T]) IndexOfFunc(f func(T) bool) int {
|
||||||
|
index := -1
|
||||||
|
data := l.data
|
||||||
|
for i, v := range data {
|
||||||
|
if f(v) {
|
||||||
|
index = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
// LastIndexOfFunc returns the index of the last occurrence of the value in this list satisfying f(data[i])
|
||||||
|
// if not found return -1
|
||||||
|
func (l *List[T]) LastIndexOfFunc(f func(T) bool) int {
|
||||||
|
index := -1
|
||||||
|
data := l.data
|
||||||
|
for i := len(data) - 1; i >= 0; i-- {
|
||||||
|
if f(data[i]) {
|
||||||
|
index = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
// Contain checks if the value in the list or not
|
// Contain checks if the value in the list or not
|
||||||
func (l *List[T]) Contain(value T) bool {
|
func (l *List[T]) Contain(value T) bool {
|
||||||
data := l.data
|
data := l.data
|
||||||
@@ -121,6 +163,31 @@ func (l *List[T]) DeleteAt(index int) {
|
|||||||
l.data = data
|
l.data = data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteIf delete all satisfying f(data[i]), returns count of removed elements
|
||||||
|
func (l *List[T]) DeleteIf(f func(T) bool) int {
|
||||||
|
data := l.data
|
||||||
|
size := len(data)
|
||||||
|
|
||||||
|
var c int
|
||||||
|
for index := 0; index < len(data); index++ {
|
||||||
|
if !f(data[index]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if index == size-1 {
|
||||||
|
data = append(data[:index])
|
||||||
|
} else {
|
||||||
|
data = append(data[:index], data[index+1:]...)
|
||||||
|
index--
|
||||||
|
}
|
||||||
|
c++
|
||||||
|
}
|
||||||
|
|
||||||
|
if c > 0 {
|
||||||
|
l.data = data
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateAt update value of list at index, index shoud between 0 and list size -1
|
// UpdateAt update value of list at index, index shoud between 0 and list size -1
|
||||||
func (l *List[T]) UpdateAt(index int, value T) {
|
func (l *List[T]) UpdateAt(index int, value T) {
|
||||||
data := l.data
|
data := l.data
|
||||||
@@ -181,6 +248,11 @@ func (l *List[T]) Size() int {
|
|||||||
return len(l.data)
|
return len(l.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cap return cap of the inner data
|
||||||
|
func (l *List[T]) Cap() int {
|
||||||
|
return cap(l.data)
|
||||||
|
}
|
||||||
|
|
||||||
// Swap the value of index i and j in list
|
// Swap the value of index i and j in list
|
||||||
func (l *List[T]) Swap(i, j int) {
|
func (l *List[T]) Swap(i, j int) {
|
||||||
size := len(l.data)
|
size := len(l.data)
|
||||||
@@ -222,24 +294,32 @@ func (l *List[T]) Unique() {
|
|||||||
|
|
||||||
// Union creates a new list contain all element in list l and other, remove duplicate element.
|
// Union creates a new list contain all element in list l and other, remove duplicate element.
|
||||||
func (l *List[T]) Union(other *List[T]) *List[T] {
|
func (l *List[T]) Union(other *List[T]) *List[T] {
|
||||||
res := NewList([]T{})
|
result := NewList([]T{})
|
||||||
|
|
||||||
res.data = append(res.data, l.data...)
|
result.data = append(result.data, l.data...)
|
||||||
res.data = append(res.data, other.data...)
|
result.data = append(result.data, other.data...)
|
||||||
res.Unique()
|
result.Unique()
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intersection creates a new list whose element both be contained in list l and other
|
// Intersection creates a new list whose element both be contained in list l and other
|
||||||
func (l *List[T]) Intersection(other *List[T]) *List[T] {
|
func (l *List[T]) Intersection(other *List[T]) *List[T] {
|
||||||
res := NewList(make([]T, 0, 0))
|
result := NewList(make([]T, 0, 0))
|
||||||
|
|
||||||
for _, v := range l.data {
|
for _, v := range l.data {
|
||||||
if other.Contain(v) {
|
if other.Contain(v) {
|
||||||
res.data = append(res.data, v)
|
result.data = append(result.data, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.
|
||||||
|
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T] {
|
||||||
|
data := l.data[fromIndex:toIndex]
|
||||||
|
subList := make([]T, len(data))
|
||||||
|
copy(subList, data)
|
||||||
|
return NewList(subList)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,51 @@ func TestIndexOf(t *testing.T) {
|
|||||||
assert.Equal(-1, i)
|
assert.Equal(-1, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIndexOfFunc(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIndexOf")
|
||||||
|
|
||||||
|
list := NewList([]int{1, 2, 3})
|
||||||
|
i := list.IndexOfFunc(func(a int) bool { return a == 1 })
|
||||||
|
assert.Equal(0, i)
|
||||||
|
|
||||||
|
i = list.IndexOfFunc(func(a int) bool { return a == 4 })
|
||||||
|
assert.Equal(-1, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLastIndexOf(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIndexOf")
|
||||||
|
|
||||||
|
list := NewList([]int{1, 2, 3, 3, 3, 3, 4, 5, 6, 9})
|
||||||
|
i := list.LastIndexOf(3)
|
||||||
|
assert.Equal(5, i)
|
||||||
|
|
||||||
|
i = list.LastIndexOf(10)
|
||||||
|
assert.Equal(-1, i)
|
||||||
|
|
||||||
|
i = list.LastIndexOf(4)
|
||||||
|
assert.Equal(6, i)
|
||||||
|
|
||||||
|
i = list.LastIndexOf(1)
|
||||||
|
assert.Equal(0, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLastIndexOfFunc(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIndexOf")
|
||||||
|
|
||||||
|
list := NewList([]int{1, 2, 3, 3, 3, 3, 4, 5, 6, 9})
|
||||||
|
i := list.LastIndexOfFunc(func(a int) bool { return a == 3 })
|
||||||
|
assert.Equal(5, i)
|
||||||
|
|
||||||
|
i = list.LastIndexOfFunc(func(a int) bool { return a == 10 })
|
||||||
|
assert.Equal(-1, i)
|
||||||
|
|
||||||
|
i = list.LastIndexOfFunc(func(a int) bool { return a == 4 })
|
||||||
|
assert.Equal(6, i)
|
||||||
|
|
||||||
|
i = list.LastIndexOfFunc(func(a int) bool { return a == 1 })
|
||||||
|
assert.Equal(0, i)
|
||||||
|
}
|
||||||
|
|
||||||
func TestContain(t *testing.T) {
|
func TestContain(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestContain")
|
assert := internal.NewAssert(t, "TestContain")
|
||||||
|
|
||||||
@@ -216,6 +261,18 @@ func TestSize(t *testing.T) {
|
|||||||
assert.Equal(0, empty.Size())
|
assert.Equal(0, empty.Size())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCap(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestCap")
|
||||||
|
|
||||||
|
data := make([]int, 0, 100)
|
||||||
|
list := NewList(data)
|
||||||
|
assert.Equal(100, list.Cap())
|
||||||
|
|
||||||
|
data = make([]int, 0)
|
||||||
|
list = NewList(data)
|
||||||
|
assert.Equal(0, list.Cap())
|
||||||
|
}
|
||||||
|
|
||||||
func TestSwap(t *testing.T) {
|
func TestSwap(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestSwap")
|
assert := internal.NewAssert(t, "TestSwap")
|
||||||
|
|
||||||
@@ -270,3 +327,33 @@ func TestIntersection(t *testing.T) {
|
|||||||
list3 := list1.Intersection(list2)
|
list3 := list1.Intersection(list2)
|
||||||
assert.Equal(true, expected.Equal(list3))
|
assert.Equal(true, expected.Equal(list3))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSubSlice(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestSubSlice")
|
||||||
|
|
||||||
|
list := NewList([]int{1, 2, 3, 4, 5, 8})
|
||||||
|
subList := list.SubList(2, 5)
|
||||||
|
|
||||||
|
assert.Equal([]int{3, 4, 5}, subList.Data())
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSubSlice(b *testing.B) {
|
||||||
|
list := NewList([]int{1, 2, 3, 4, 5, 8})
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
list.SubList(2, 5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteIf(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestDeleteIf")
|
||||||
|
|
||||||
|
list := NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
||||||
|
|
||||||
|
count := list.DeleteIf(func(a int) bool { return a == 1 })
|
||||||
|
assert.Equal([]int{2, 3, 4}, list.Data())
|
||||||
|
assert.Equal(12, count)
|
||||||
|
|
||||||
|
count = list.DeleteIf(func(a int) bool { return a == 5 })
|
||||||
|
assert.Equal([]int{2, 3, 4}, list.Data())
|
||||||
|
assert.Equal(0, count)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package datastructure
|
package datastructure
|
||||||
|
|
||||||
// Set is a data container, like slice, but element of set is not duplicate
|
// Set is a data container, like slice, but element of set is not duplicate
|
||||||
type Set[T comparable] map[T]bool
|
type Set[T comparable] map[T]struct{}
|
||||||
|
|
||||||
// NewSet return a instance of set
|
// NewSet return a instance of set
|
||||||
func NewSet[T comparable](values ...T) Set[T] {
|
func NewSet[T comparable](values ...T) Set[T] {
|
||||||
@@ -13,7 +13,7 @@ func NewSet[T comparable](values ...T) Set[T] {
|
|||||||
// Add value to set
|
// Add value to set
|
||||||
func (s Set[T]) Add(values ...T) {
|
func (s Set[T]) Add(values ...T) {
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
s[v] = true
|
s[v] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,20 +84,20 @@ func (t *BSTree[T]) HasSubTree(subTree *BSTree[T]) bool {
|
|||||||
|
|
||||||
func hasSubTree[T any](superTreeRoot, subTreeRoot *datastructure.TreeNode[T],
|
func hasSubTree[T any](superTreeRoot, subTreeRoot *datastructure.TreeNode[T],
|
||||||
comparator lancetconstraints.Comparator) bool {
|
comparator lancetconstraints.Comparator) bool {
|
||||||
res := false
|
result := false
|
||||||
|
|
||||||
if superTreeRoot != nil && subTreeRoot != nil {
|
if superTreeRoot != nil && subTreeRoot != nil {
|
||||||
if comparator.Compare(superTreeRoot.Value, subTreeRoot.Value) == 0 {
|
if comparator.Compare(superTreeRoot.Value, subTreeRoot.Value) == 0 {
|
||||||
res = isSubTree(superTreeRoot, subTreeRoot, comparator)
|
result = isSubTree(superTreeRoot, subTreeRoot, comparator)
|
||||||
}
|
}
|
||||||
if !res {
|
if !result {
|
||||||
res = hasSubTree(superTreeRoot.Left, subTreeRoot, comparator)
|
result = hasSubTree(superTreeRoot.Left, subTreeRoot, comparator)
|
||||||
}
|
}
|
||||||
if !res {
|
if !result {
|
||||||
res = hasSubTree(superTreeRoot.Right, subTreeRoot, comparator)
|
result = hasSubTree(superTreeRoot.Right, subTreeRoot, comparator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print the bstree structure
|
// Print the bstree structure
|
||||||
|
|||||||
@@ -226,8 +226,8 @@ func isSubTree[T any](superTreeRoot, subTreeRoot *datastructure.TreeNode[T], com
|
|||||||
if comparator.Compare(superTreeRoot.Value, subTreeRoot.Value) != 0 {
|
if comparator.Compare(superTreeRoot.Value, subTreeRoot.Value) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
res := isSubTree(superTreeRoot.Left, subTreeRoot.Left, comparator) && isSubTree(superTreeRoot.Right, subTreeRoot.Right, comparator)
|
result := isSubTree(superTreeRoot.Left, subTreeRoot.Left, comparator) && isSubTree(superTreeRoot.Right, subTreeRoot.Right, comparator)
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func max(a, b int) int {
|
func max(a, b int) int {
|
||||||
|
|||||||
@@ -147,16 +147,32 @@ func EndOfDay(t time.Time) time.Time {
|
|||||||
return time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), t.Location())
|
return time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), t.Location())
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeginOfWeek return beginning week, week begin from Sunday
|
// BeginOfWeek return beginning week, default week begin from Sunday
|
||||||
func BeginOfWeek(t time.Time) time.Time {
|
func BeginOfWeek(t time.Time, beginFrom ...time.Weekday) time.Time {
|
||||||
y, m, d := t.AddDate(0, 0, 0-int(BeginOfDay(t).Weekday())).Date()
|
var beginFromWeekday = time.Sunday
|
||||||
return time.Date(y, m, d, 0, 0, 0, 0, t.Location())
|
if len(beginFrom) > 0 {
|
||||||
|
beginFromWeekday = beginFrom[0]
|
||||||
|
}
|
||||||
|
y, m, d := t.AddDate(0, 0, int(beginFromWeekday-t.Weekday())).Date()
|
||||||
|
beginOfWeek := time.Date(y, m, d, 0, 0, 0, 0, t.Location())
|
||||||
|
if beginOfWeek.After(t) {
|
||||||
|
return beginOfWeek.AddDate(0, 0, -7)
|
||||||
|
}
|
||||||
|
return beginOfWeek
|
||||||
}
|
}
|
||||||
|
|
||||||
// EndOfWeek return end week time, week end with Saturday
|
// EndOfWeek return end week time, default week end with Saturday
|
||||||
func EndOfWeek(t time.Time) time.Time {
|
func EndOfWeek(t time.Time, endWith ...time.Weekday) time.Time {
|
||||||
y, m, d := BeginOfWeek(t).AddDate(0, 0, 7).Add(-time.Nanosecond).Date()
|
var endWithWeekday = time.Saturday
|
||||||
return time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), t.Location())
|
if len(endWith) > 0 {
|
||||||
|
endWithWeekday = endWith[0]
|
||||||
|
}
|
||||||
|
y, m, d := t.AddDate(0, 0, int(endWithWeekday-t.Weekday())).Date()
|
||||||
|
var endWithWeek = time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), t.Location())
|
||||||
|
if endWithWeek.Before(t) {
|
||||||
|
endWithWeek = endWithWeek.AddDate(0, 0, 7)
|
||||||
|
}
|
||||||
|
return endWithWeek
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeginOfMonth return beginning of month
|
// BeginOfMonth return beginning of month
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Package algorithm implements some basic algorithm. eg. sort, search.
|
|||||||
|
|
||||||
## Source
|
## Source
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/sorter.go](https://github.com/duke-git/lancet/blob/main/algorithm/sorter.go)
|
- [https://github.com/duke-git/lancet/blob/main/algorithm/sort.go](https://github.com/duke-git/lancet/blob/main/algorithm/sort.go)
|
||||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
|
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
|
||||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
|
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func QuickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator)
|
func QuickSort[T any](slice []T comparator lancetconstraints.Comparator)
|
||||||
```
|
```
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
@@ -278,7 +278,7 @@ func main() {
|
|||||||
|
|
||||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||||
comparator := &intComparator{}
|
comparator := &intComparator{}
|
||||||
algorithm.QuickSort(intSlice, 0, len(intSlice)-1, comparator)
|
algorithm.QuickSort(intSlice, comparator)
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ algorithm算法包实现一些基本算法,sort,search,lrucache。
|
|||||||
|
|
||||||
## 源码
|
## 源码
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/sorter.go](https://github.com/duke-git/lancet/blob/main/algorithm/sorter.go)
|
- [https://github.com/duke-git/lancet/blob/main/algorithm/sort.go](https://github.com/duke-git/lancet/blob/main/algorithm/sort.go)
|
||||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
|
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
|
||||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
|
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
|
||||||
|
|
||||||
@@ -249,7 +249,7 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func QuickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T
|
func QuickSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||||
```
|
```
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
@@ -279,7 +279,7 @@ func main() {
|
|||||||
|
|
||||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||||
comparator := &intComparator{}
|
comparator := &intComparator{}
|
||||||
algorithm.QuickSort(intSlice, 0, len(intSlice)-1, comparator)
|
algorithm.QuickSort(intSlice, comparator)
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||||
}
|
}
|
||||||
|
|||||||
264
docs/condition.md
Normal file
264
docs/condition.md
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
# Condition
|
||||||
|
Package condition contains some functions for conditional judgment. eg. And, Or, TernaryOperator... The implementation of this package refers to the implementation of carlmjohnson's truthy package, you may find more useful information in [truthy](https://github.com/carlmjohnson/truthy), thanks carlmjohnson.
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Source:
|
||||||
|
|
||||||
|
- [https://github.com/duke-git/lancet/blob/main/condition/condition.go](https://github.com/duke-git/lancet/blob/main/condition/condition.go)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Usage:
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Index
|
||||||
|
|
||||||
|
- [Bool](#Bool)
|
||||||
|
- [And](#And)
|
||||||
|
- [Or](#Or)
|
||||||
|
- [Xor](#Generate)
|
||||||
|
- [Nor](#Nor)
|
||||||
|
- [Nand](#Nand)
|
||||||
|
- [TernaryOperator](#TernaryOperator)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Bool">Bool</span>
|
||||||
|
<p>Returns the truthy value of anything.<br/>
|
||||||
|
If the value's type has a Bool() bool method, the method is called and returned.<br/>
|
||||||
|
If the type has an IsZero() bool method, the opposite value is returned.<br/>
|
||||||
|
Slices and maps are truthy if they have a length greater than zero.<br/>
|
||||||
|
All other types are truthy if they are not their zero value.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Bool[T any](value T) bool
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// bool
|
||||||
|
fmt.Println(condition.Bool(false)) // false
|
||||||
|
fmt.Println(condition.Bool(true)) // true
|
||||||
|
|
||||||
|
// integer
|
||||||
|
fmt.Println(condition.Bool(0)) // false
|
||||||
|
fmt.Println(condition.Bool(1)) // true
|
||||||
|
|
||||||
|
// float
|
||||||
|
fmt.Println(condition.Bool(0.0)) // false
|
||||||
|
fmt.Println(condition.Bool(0.1)) // true
|
||||||
|
|
||||||
|
// string
|
||||||
|
fmt.Println(condition.Bool("")) // false
|
||||||
|
fmt.Println(condition.Bool(" ")) // true
|
||||||
|
fmt.Println(condition.Bool("0")) // true
|
||||||
|
|
||||||
|
// slice
|
||||||
|
var nums [2]int
|
||||||
|
fmt.Println(condition.Bool(nums)) // false
|
||||||
|
nums = [2]int{0, 1}
|
||||||
|
fmt.Println(condition.Bool(nums)) // true
|
||||||
|
|
||||||
|
// map
|
||||||
|
fmt.Println(condition.Bool(map[string]string{})) // false
|
||||||
|
fmt.Println(condition.Bool(map[string]string{"a": "a"})) // true
|
||||||
|
|
||||||
|
// struct
|
||||||
|
fmt.Println(condition.Bool(struct{}{})) // false
|
||||||
|
fmt.Println(condition.Bool(time.Now())) // true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="And">And</span>
|
||||||
|
<p>Returns true if both a and b are truthy.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func And[T, U any](a T, b U) bool
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(condition.And(0, 1)) // false
|
||||||
|
fmt.Println(condition.And(0, "")) // false
|
||||||
|
fmt.Println(condition.And(0, "0")) // false
|
||||||
|
fmt.Println(condition.And(1, "0")) // true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Or">Or</span>
|
||||||
|
<p>Returns false iff neither a nor b is truthy.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Or[T, U any](a T, b U) bool
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(condition.Or(0, "")) // false
|
||||||
|
fmt.Println(condition.Or(0, 1)) // true
|
||||||
|
fmt.Println(condition.Or(0, "0")) // true
|
||||||
|
fmt.Println(condition.Or(1, "0")) // true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Xor">Xor</span>
|
||||||
|
<p>Returns true iff a or b but not both is truthy.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Xor[T, U any](a T, b U) bool
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(condition.Xor(0, 0)) // false
|
||||||
|
fmt.Println(condition.Xor(0, 1)) // true
|
||||||
|
fmt.Println(condition.Xor(1, 0)) // true
|
||||||
|
fmt.Println(condition.Xor(1, 1)) // false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Nor">Nor</span>
|
||||||
|
<p>Returns true iff neither a nor b is truthy.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Nor[T, U any](a T, b U) bool
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(condition.Nor(0, 0)) // true
|
||||||
|
fmt.Println(condition.Nor(0, 1)) // false
|
||||||
|
fmt.Println(condition.Nor(1, 0)) // false
|
||||||
|
fmt.Println(condition.Nor(1, 1)) // true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Nand">Nand</span>
|
||||||
|
<p>Returns false iff both a and b are truthy</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Nand[T, U any](a T, b U) bool
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(condition.Nand(0, 0)) // true
|
||||||
|
fmt.Println(condition.Nand(0, 1)) // true
|
||||||
|
fmt.Println(condition.Nand(1, 0)) // true
|
||||||
|
fmt.Println(condition.Nand(1, 1)) // false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="TernaryOperator">TernaryOperator</span>
|
||||||
|
<p>Checks the value of param `isTrue`, if true return ifValue else return elseValue</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func TernaryOperator[T, U any](isTrue T, ifValue U, elseValue U) U
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
trueValue := "1"
|
||||||
|
falseValue := "0"
|
||||||
|
|
||||||
|
fmt.Println(condition.TernaryOperator(true, trueValue, falseValue)) // "1"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
263
docs/condition_zh-CN.md
Normal file
263
docs/condition_zh-CN.md
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
# Condition
|
||||||
|
condition包含一些用于条件判断的函数。这个包的实现参考了carlmjohnson的truthy包的实现,更多有用的信息可以在[truthy](https://github.com/carlmjohnson/truthy)中找到,感谢carlmjohnson。
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 源码:
|
||||||
|
|
||||||
|
- [https://github.com/duke-git/lancet/blob/main/condition/condition.go](https://github.com/duke-git/lancet/blob/main/condition/condition.go)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 用法:
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Index
|
||||||
|
|
||||||
|
- [Bool](#Bool)
|
||||||
|
- [And](#And)
|
||||||
|
- [Or](#Or)
|
||||||
|
- [Xor](#Generate)
|
||||||
|
- [Nor](#Nor)
|
||||||
|
- [Nand](#Nand)
|
||||||
|
- [TernaryOperator](#TernaryOperator)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 目录
|
||||||
|
|
||||||
|
### <span id="Bool">Bool</span>
|
||||||
|
<p>返回传入参数的bool值.<br/>
|
||||||
|
如果出入类型参数含有Bool方法, 会调用该方法并返回<br/>
|
||||||
|
如果传入类型参数有IsZero方法, 返回IsZero方法返回值的取反<br/>
|
||||||
|
slices和map的length大于0时,返回true,否则返回false<br/>
|
||||||
|
其他类型会判断是否是零值</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Bool[T any](value T) bool
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// bool
|
||||||
|
fmt.Println(condition.Bool(false)) // false
|
||||||
|
fmt.Println(condition.Bool(true)) // true
|
||||||
|
|
||||||
|
// integer
|
||||||
|
fmt.Println(condition.Bool(0)) // false
|
||||||
|
fmt.Println(condition.Bool(1)) // true
|
||||||
|
|
||||||
|
// float
|
||||||
|
fmt.Println(condition.Bool(0.0)) // false
|
||||||
|
fmt.Println(condition.Bool(0.1)) // true
|
||||||
|
|
||||||
|
// string
|
||||||
|
fmt.Println(condition.Bool("")) // false
|
||||||
|
fmt.Println(condition.Bool(" ")) // true
|
||||||
|
fmt.Println(condition.Bool("0")) // true
|
||||||
|
|
||||||
|
// slice
|
||||||
|
var nums [2]int
|
||||||
|
fmt.Println(condition.Bool(nums)) // false
|
||||||
|
nums = [2]int{0, 1}
|
||||||
|
fmt.Println(condition.Bool(nums)) // true
|
||||||
|
|
||||||
|
// map
|
||||||
|
fmt.Println(condition.Bool(map[string]string{})) // false
|
||||||
|
fmt.Println(condition.Bool(map[string]string{"a": "a"})) // true
|
||||||
|
|
||||||
|
// struct
|
||||||
|
fmt.Println(condition.Bool(struct{}{})) // false
|
||||||
|
fmt.Println(condition.Bool(time.Now())) // true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="And">And</span>
|
||||||
|
<p>逻辑且操作,当切仅当a和b都为true时返回true</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func And[T, U any](a T, b U) bool
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(condition.And(0, 1)) // false
|
||||||
|
fmt.Println(condition.And(0, "")) // false
|
||||||
|
fmt.Println(condition.And(0, "0")) // false
|
||||||
|
fmt.Println(condition.And(1, "0")) // true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Or">Or</span>
|
||||||
|
<p>逻辑或操作,当切仅当a和b都为false时返回false</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Or[T, U any](a T, b U) bool
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(condition.Or(0, "")) // false
|
||||||
|
fmt.Println(condition.Or(0, 1)) // true
|
||||||
|
fmt.Println(condition.Or(0, "0")) // true
|
||||||
|
fmt.Println(condition.Or(1, "0")) // true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Xor">Xor</span>
|
||||||
|
<p>逻辑异或操作,a和b相同返回false,a和b不相同返回true</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Xor[T, U any](a T, b U) bool
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(condition.Xor(0, 0)) // false
|
||||||
|
fmt.Println(condition.Xor(0, 1)) // true
|
||||||
|
fmt.Println(condition.Xor(1, 0)) // true
|
||||||
|
fmt.Println(condition.Xor(1, 1)) // false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Nor">Nor</span>
|
||||||
|
<p>异或的取反操作</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Nor[T, U any](a T, b U) bool
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(condition.Nor(0, 0)) // true
|
||||||
|
fmt.Println(condition.Nor(0, 1)) // false
|
||||||
|
fmt.Println(condition.Nor(1, 0)) // false
|
||||||
|
fmt.Println(condition.Nor(1, 1)) // true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Nand">Nand</span>
|
||||||
|
<p>如果a和b都为真,返回false,否则返回true</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Nand[T, U any](a T, b U) bool
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(condition.Nand(0, 0)) // true
|
||||||
|
fmt.Println(condition.Nand(0, 1)) // true
|
||||||
|
fmt.Println(condition.Nand(1, 0)) // true
|
||||||
|
fmt.Println(condition.Nand(1, 1)) // false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="TernaryOperator">TernaryOperator</span>
|
||||||
|
<p>三元运算符</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func TernaryOperator[T, U any](isTrue T, ifValue U, elseValue U) U
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/condition"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
trueValue := "1"
|
||||||
|
falseValue := "0"
|
||||||
|
|
||||||
|
fmt.Println(condition.TernaryOperator(true, trueValue, falseValue)) // "1"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -34,6 +34,8 @@ import (
|
|||||||
- [ToString](#ToString)
|
- [ToString](#ToString)
|
||||||
- [StructToMap](#StructToMap)
|
- [StructToMap](#StructToMap)
|
||||||
- [MapToSlice](#MapToSlice)
|
- [MapToSlice](#MapToSlice)
|
||||||
|
- [EncodeByte](#EncodeByte)
|
||||||
|
- [DecodeByte](#DecodeByte)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -458,3 +460,58 @@ func main() {
|
|||||||
fmt.Println(result) //[]string{"a:1", "b:2", "c:3"}
|
fmt.Println(result) //[]string{"a:1", "b:2", "c:3"}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="EncodeByte">EncodeByte</span>
|
||||||
|
|
||||||
|
<p>Encode data to byte slice.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EncodeByte(data any) ([]byte, error)
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
byteData, _ := convertor.EncodeByte("abc")
|
||||||
|
fmt.Println(byteData) //[]byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="DecodeByte">DecodeByte</span>
|
||||||
|
|
||||||
|
<p>Decode byte data to target object. target should be a pointer instance.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DecodeByte(data []byte, target any) error
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var result string
|
||||||
|
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
convertor.DecodeByte(byteData, &result)
|
||||||
|
fmt.Println(result) //"abc"
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -36,6 +36,8 @@ import (
|
|||||||
- [ToString](#ToString)
|
- [ToString](#ToString)
|
||||||
- [StructToMap](#StructToMap)
|
- [StructToMap](#StructToMap)
|
||||||
- [MapToSlice](#MapToSlice)
|
- [MapToSlice](#MapToSlice)
|
||||||
|
- [EncodeByte](#EncodeByte)
|
||||||
|
- [DecodeByte](#DecodeByte)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -273,7 +275,7 @@ func main() {
|
|||||||
|
|
||||||
### <span id="ToInt">ToInt</span>
|
### <span id="ToInt">ToInt</span>
|
||||||
|
|
||||||
<p>将interface转成intt64类型,如果参数无法转换,会返回0和error</p>
|
<p>将interface转成int64类型,如果参数无法转换,会返回0和error</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
@@ -489,3 +491,59 @@ func main() {
|
|||||||
fmt.Println(result) //[]string{"a:1", "b:2", "c:3"}
|
fmt.Println(result) //[]string{"a:1", "b:2", "c:3"}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="EncodeByte">EncodeByte</span>
|
||||||
|
|
||||||
|
<p>将data编码成字节切片</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EncodeByte(data any) ([]byte, error)
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
byteData, _ := convertor.EncodeByte("abc")
|
||||||
|
fmt.Println(byteData) //[]byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="DecodeByte">DecodeByte</span>
|
||||||
|
|
||||||
|
<p>解码字节切片到目标对象,目标对象需要传入一个指针实例子</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DecodeByte(data []byte, target any) error
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var result string
|
||||||
|
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
convertor.DecodeByte(byteData, &result)
|
||||||
|
fmt.Println(result) //"abc"
|
||||||
|
}
|
||||||
|
```
|
||||||
314
docs/datastructure/hashmap.md
Normal file
314
docs/datastructure/hashmap.md
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
# HashMap
|
||||||
|
|
||||||
|
HashMap is a key value map data structure.
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Source
|
||||||
|
|
||||||
|
- [https://github.com/duke-git/lancet/blob/main/datastructure/hashmap/hashmap.go](https://github.com/duke-git/lancet/blob/main/datastructure/hashmap/hashmap.go)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
|
||||||
|
## Index
|
||||||
|
|
||||||
|
- [NewHashMap](#NewHashMap)
|
||||||
|
- [NewHashMapWithCapacity](#NewHashMapWithCapacity)
|
||||||
|
- [Get](#Get)
|
||||||
|
- [Put](#Put)
|
||||||
|
- [Delete](#Delete)
|
||||||
|
- [Contains](#Contains)
|
||||||
|
- [Iterate](#Iterate)
|
||||||
|
- [Keys](#Keys)
|
||||||
|
- [Values](#Values)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
### <span id="NewHashMap">NewHashMap</span>
|
||||||
|
|
||||||
|
<p>Make a HashMap instance with default capacity is 1 << 10.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewHashMap() *HashMap
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
fmt.Println(hm)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="NewHashMap">NewHashMap</span>
|
||||||
|
|
||||||
|
<p>Make a HashMap instance with given size and capacity.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewHashMapWithCapacity(size, capacity uint64) *HashMap
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMapWithCapacity(uint64(100), uint64(1000))
|
||||||
|
fmt.Println(hm)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Get">Get</span>
|
||||||
|
|
||||||
|
<p>Get the value of given key in hashmap</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Get(key any) any
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
val := hm.Get("a")
|
||||||
|
|
||||||
|
fmt.Println(val) //nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Put">Put</span>
|
||||||
|
|
||||||
|
<p>Put new key value in hashmap, then return value</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Put(key any, value any) any
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
hm.Put("a", 1)
|
||||||
|
|
||||||
|
val := hm.Get("a")
|
||||||
|
fmt.Println(val) //1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Delete">Delete</span>
|
||||||
|
|
||||||
|
<p>Delete key-value item by given key in hashmap.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Delete(key any)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
hm.Put("a", 1)
|
||||||
|
val := hm.Get("a")
|
||||||
|
fmt.Println(val) //1
|
||||||
|
|
||||||
|
hm.Delete("a")
|
||||||
|
val = hm.Get("a")
|
||||||
|
fmt.Println(val) //nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Contains">Contains</span>
|
||||||
|
|
||||||
|
<p>Checks if given key is in hashmap or not.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Contains(key any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
hm.Put("a", 1)
|
||||||
|
|
||||||
|
fmt.Println(hm.Contains("a")) //true
|
||||||
|
fmt.Println(hm.Contains("b")) //false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Iterate">Iterate</span>
|
||||||
|
|
||||||
|
<p>Executes iteratee funcation for every key and value pair of hashmap.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Iterate(iteratee func(key, value any))
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
hm.Put("a", 1)
|
||||||
|
hm.Put("b", 2)
|
||||||
|
hm.Put("c", 3)
|
||||||
|
|
||||||
|
hm.Iterate(func(key, value any) {
|
||||||
|
fmt.Println(key)
|
||||||
|
fmt.Println(value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Keys">Keys</span>
|
||||||
|
|
||||||
|
<p>Return a slice of the hashmap's keys (random order).</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Keys() []any
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
hm.Put("a", 1)
|
||||||
|
hm.Put("b", 2)
|
||||||
|
hm.Put("c", 3)
|
||||||
|
|
||||||
|
keys := hm.Keys()
|
||||||
|
fmt.Println(keys) //[]interface{"a", "b", "c"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Values">Values</span>
|
||||||
|
|
||||||
|
<p>Return a slice of the hashmap's values (random order).</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Values() []any
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
hm.Put("a", 1)
|
||||||
|
hm.Put("b", 2)
|
||||||
|
hm.Put("c", 3)
|
||||||
|
|
||||||
|
values := hm.Values()
|
||||||
|
fmt.Println(values) //[]interface{2, 1, 3}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
308
docs/datastructure/hashmap_zh-CN.md
Normal file
308
docs/datastructure/hashmap_zh-CN.md
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
# HashMap
|
||||||
|
|
||||||
|
HashMap 数据结构实现
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 源码
|
||||||
|
|
||||||
|
- [https://github.com/duke-git/lancet/blob/main/datastructure/hashmap/hashmap.go](https://github.com/duke-git/lancet/blob/main/datastructure/hashmap/hashmap.go)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 用法
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 目录
|
||||||
|
|
||||||
|
- [NewHashMap](#NewHashMap)
|
||||||
|
- [NewHashMapWithCapacity](#NewHashMapWithCapacity)
|
||||||
|
- [Get](#Get)
|
||||||
|
- [Put](#Put)
|
||||||
|
- [Delete](#Delete)
|
||||||
|
- [Contains](#Contains)
|
||||||
|
- [Iterate](#Iterate)
|
||||||
|
- [Keys](#Keys)
|
||||||
|
- [Values](#Values)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## API 文档
|
||||||
|
|
||||||
|
### <span id="NewHashMap">NewHashMap</span>
|
||||||
|
|
||||||
|
<p>新建默认容量(1 << 10)的HashMap指针实例</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewHashMap() *HashMap
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
fmt.Println(hm)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="NewHashMapWithCapacity">NewHashMapWithCapacity</span>
|
||||||
|
|
||||||
|
<p>新建指定容量和长度的HashMap指针实例.</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewHashMapWithCapacity(size, capacity uint64) *HashMap
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMapWithCapacity(uint64(100), uint64(1000))
|
||||||
|
fmt.Println(hm)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Get">Get</span>
|
||||||
|
|
||||||
|
<p>在hashmap中根据key获取值</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Get(key any) any
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
val := hm.Get("a")
|
||||||
|
|
||||||
|
fmt.Println(val) //nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Put">Put</span>
|
||||||
|
|
||||||
|
<p>将key-value放入hashmap中</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Put(key any, value any) any
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
hm.Put("a", 1)
|
||||||
|
|
||||||
|
val := hm.Get("a")
|
||||||
|
fmt.Println(val) //1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Delete">Delete</span>
|
||||||
|
|
||||||
|
<p>将指定的key从hashmap中删除</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Delete(key any)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
hm.Put("a", 1)
|
||||||
|
val := hm.Get("a")
|
||||||
|
fmt.Println(val) //1
|
||||||
|
|
||||||
|
hm.Delete("a")
|
||||||
|
val = hm.Get("a")
|
||||||
|
fmt.Println(val) //nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Contains">Contains</span>
|
||||||
|
|
||||||
|
<p>判断hashmap中是否包含指定的key</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Contains(key any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
hm.Put("a", 1)
|
||||||
|
|
||||||
|
fmt.Println(hm.Contains("a")) //true
|
||||||
|
fmt.Println(hm.Contains("b")) //false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Iterate">Iterate</span>
|
||||||
|
|
||||||
|
<p>迭代hashmap,对每个key和value执行iteratee函数</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Iterate(iteratee func(key, value any))
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
hm.Put("a", 1)
|
||||||
|
hm.Put("b", 2)
|
||||||
|
hm.Put("c", 3)
|
||||||
|
|
||||||
|
hm.Iterate(func(key, value any) {
|
||||||
|
fmt.Println(key)
|
||||||
|
fmt.Println(value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Keys">Keys</span>
|
||||||
|
|
||||||
|
<p>返回hashmap所有key的切片 (随机顺序)</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Keys() []any
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
hm.Put("a", 1)
|
||||||
|
hm.Put("b", 2)
|
||||||
|
hm.Put("c", 3)
|
||||||
|
|
||||||
|
keys := hm.Keys()
|
||||||
|
fmt.Println(keys) //[]interface{"a", "b", "c"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Values">Values</span>
|
||||||
|
|
||||||
|
<p>返回hashmap所有值的切片 (随机顺序).</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (hm *HashMap) Values() []any
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hm := heap.NewHashMap()
|
||||||
|
hm.Put("a", 1)
|
||||||
|
hm.Put("b", 2)
|
||||||
|
hm.Put("c", 3)
|
||||||
|
|
||||||
|
values := hm.Values()
|
||||||
|
fmt.Println(values) //[]interface{2, 1, 3}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -26,6 +26,9 @@ import (
|
|||||||
- [Data](#Data)
|
- [Data](#Data)
|
||||||
- [ValueOf](#ValueOf)
|
- [ValueOf](#ValueOf)
|
||||||
- [IndexOf](#IndexOf)
|
- [IndexOf](#IndexOf)
|
||||||
|
- [LastIndexOf](#LastIndexOf)
|
||||||
|
- [IndexOfFunc](#IndexOfFunc)
|
||||||
|
- [LastIndexOfFunc](#LastIndexOfFunc)
|
||||||
- [Push](#Push)
|
- [Push](#Push)
|
||||||
- [PopFirst](#PopFirst)
|
- [PopFirst](#PopFirst)
|
||||||
- [PopLast](#PopLast)
|
- [PopLast](#PopLast)
|
||||||
@@ -38,11 +41,14 @@ import (
|
|||||||
- [Clone](#Clone)
|
- [Clone](#Clone)
|
||||||
- [Merge](#Merge)
|
- [Merge](#Merge)
|
||||||
- [Size](#Size)
|
- [Size](#Size)
|
||||||
|
- [Cap](#Cap)
|
||||||
- [Swap](#Swap)
|
- [Swap](#Swap)
|
||||||
- [Reverse](#Reverse)
|
- [Reverse](#Reverse)
|
||||||
- [Unique](#Unique)
|
- [Unique](#Unique)
|
||||||
- [Union](#Union)
|
- [Union](#Union)
|
||||||
- [Intersection](#Intersection)
|
- [Intersection](#Intersection)
|
||||||
|
- [SubList](#SubList)
|
||||||
|
- [DeleteIf](#DeleteIf)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -167,7 +173,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
### <span id="IndexOf">IndexOf</span>
|
### <span id="IndexOf">IndexOf</span>
|
||||||
<p>Reture the index of value in the list. if not found return -1</p>
|
<p>Returns the index of value in the list. if not found return -1</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
@@ -192,6 +198,84 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="LastIndexOf">LastIndexOf</span>
|
||||||
|
<p> Returns the index of the last occurrence of the value in this list if not found return -1</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) LastIndexOf(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, 1})
|
||||||
|
|
||||||
|
fmt.Println(li.LastIndexOf(1)) // 3
|
||||||
|
fmt.Println(li.LastIndexOf(0)) //-1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="IndexOfFunc">IndexOfFunc</span>
|
||||||
|
<p> IndexOfFunc returns the first index satisfying f(v). if not found return -1</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) IndexOfFunc(f func(T) bool) 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.IndexOfFunc(func(a int) bool { return a == 1 })) //0
|
||||||
|
fmt.Println(li.IndexOfFunc(func(a int) bool { return a == 0 })) //-1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="LastIndexOfFunc">LastIndexOfFunc</span>
|
||||||
|
<p>LastIndexOfFunc returns the index of the last occurrence of the value in this list satisfying f(data[i]). if not found return -1</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) LastIndexOfFunc(f func(T) bool) 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, 1})
|
||||||
|
|
||||||
|
fmt.Println(li.LastIndexOfFunc(func(a int) bool { return a == 1 })) // 3
|
||||||
|
fmt.Println(li.LastIndexOfFunc(func(a int) bool { return a == 0 })) //-1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Push">Push</span>
|
### <span id="Push">Push</span>
|
||||||
@@ -568,6 +652,36 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Cap">Cap</span>
|
||||||
|
<p>Cap return cap of the inner data</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) Cap() int
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
data := make([]int, 0, 100)
|
||||||
|
|
||||||
|
li := list.NewList(data)
|
||||||
|
|
||||||
|
fmt.Println(li.Cap()) // 100
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Swap">Swap</span>
|
### <span id="Swap">Swap</span>
|
||||||
<p>Swap the value at two index in list</p>
|
<p>Swap the value at two index in list</p>
|
||||||
|
|
||||||
@@ -711,3 +825,60 @@ func main() {
|
|||||||
fmt.Println(li3.Data()) //4
|
fmt.Println(li3.Data()) //4
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="SubList">SubList</span>
|
||||||
|
<p>SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T]
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
l := list.NewList([]int{1, 2, 3, 4, 5, 6})
|
||||||
|
|
||||||
|
fmt.Println(l.SubList(2, 5)) // []int{3, 4, 5}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="DeleteIf">DeleteIf</span>
|
||||||
|
<p>DeleteIf delete all satisfying f(data[i]), returns count of removed elements</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) DeleteIf(f func(T) bool) int
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
||||||
|
|
||||||
|
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
|
||||||
|
fmt.Println(l.Data()) // []int{2, 3, 4}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -26,11 +26,15 @@ import (
|
|||||||
- [Data](#Data)
|
- [Data](#Data)
|
||||||
- [ValueOf](#ValueOf)
|
- [ValueOf](#ValueOf)
|
||||||
- [IndexOf](#IndexOf)
|
- [IndexOf](#IndexOf)
|
||||||
|
- [LastIndexOf](#LastIndexOf)
|
||||||
|
- [IndexOfFunc](#IndexOfFunc)
|
||||||
|
- [LastIndexOfFunc](#LastIndexOfFunc)
|
||||||
- [Push](#Push)
|
- [Push](#Push)
|
||||||
- [PopFirst](#PopFirst)
|
- [PopFirst](#PopFirst)
|
||||||
- [PopLast](#PopLast)
|
- [PopLast](#PopLast)
|
||||||
- [DeleteAt](#DeleteAt)
|
- [DeleteAt](#DeleteAt)
|
||||||
- [InsertAt](#InsertAt)
|
- [InsertAt](#InsertAt)
|
||||||
|
|
||||||
- [UpdateAt](#UpdateAt)
|
- [UpdateAt](#UpdateAt)
|
||||||
- [Equal](#Equal)
|
- [Equal](#Equal)
|
||||||
- [IsEmpty](#IsEmpty)
|
- [IsEmpty](#IsEmpty)
|
||||||
@@ -38,11 +42,14 @@ import (
|
|||||||
- [Clone](#Clone)
|
- [Clone](#Clone)
|
||||||
- [Merge](#Merge)
|
- [Merge](#Merge)
|
||||||
- [Size](#Size)
|
- [Size](#Size)
|
||||||
|
- [Cap](#Cap)
|
||||||
- [Swap](#Swap)
|
- [Swap](#Swap)
|
||||||
- [Reverse](#Reverse)
|
- [Reverse](#Reverse)
|
||||||
- [Unique](#Unique)
|
- [Unique](#Unique)
|
||||||
- [Union](#Union)
|
- [Union](#Union)
|
||||||
- [Intersection](#Intersection)
|
- [Intersection](#Intersection)
|
||||||
|
- [SubList](#SubList)
|
||||||
|
- [DeleteIf](#DeleteIf)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -192,6 +199,85 @@ func main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="LastIndexOf">LastIndexOf</span>
|
||||||
|
<p>返回列表中最后一次出现的值的索引。如果未找到,则返回-1</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) LastIndexOf(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, 1})
|
||||||
|
|
||||||
|
fmt.Println(li.LastIndexOf(1)) // 3
|
||||||
|
fmt.Println(li.LastIndexOf(0)) //-1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="IndexOfFunc">IndexOfFunc</span>
|
||||||
|
<p>返回第一个符合函数条件的元素的索引。如果未找到,则返回-1</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) IndexOfFunc(f func(T) bool) 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.IndexOfFunc(func(a int) bool { return a == 1 })) //0
|
||||||
|
fmt.Println(li.IndexOfFunc(func(a int) bool { return a == 0 })) //-1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="LastIndexOfFunc">LastIndexOfFunc</span>
|
||||||
|
<p>返回最后一个符合函数条件的元素的索引。如果未找到,则返回-1</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) LastIndexOfFunc(f func(T) bool) 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, 1})
|
||||||
|
|
||||||
|
fmt.Println(li.LastIndexOfFunc(func(a int) bool { return a == 1 })) // 3
|
||||||
|
fmt.Println(li.LastIndexOfFunc(func(a int) bool { return a == 0 })) //-1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Push">Push</span>
|
### <span id="Push">Push</span>
|
||||||
<p>将值附加到列表末尾</p>
|
<p>将值附加到列表末尾</p>
|
||||||
@@ -566,6 +652,34 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Cap">Cap</span>
|
||||||
|
<p>返回列表数据容量</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) Cap() int
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
data := make([]int, 0, 100)
|
||||||
|
|
||||||
|
li := list.NewList(data)
|
||||||
|
|
||||||
|
fmt.Println(li.Cap()) // 100
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Swap">Swap</span>
|
### <span id="Swap">Swap</span>
|
||||||
<p>交换列表中两个索引位置的值</p>
|
<p>交换列表中两个索引位置的值</p>
|
||||||
@@ -710,3 +824,59 @@ func main() {
|
|||||||
fmt.Println(li3.Data()) //4
|
fmt.Println(li3.Data()) //4
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="SubList">SubList</span>
|
||||||
|
<p>SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T]
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
l := list.NewList([]int{1, 2, 3, 4, 5, 6})
|
||||||
|
|
||||||
|
fmt.Println(l.SubList(2, 5)) // []int{3, 4, 5}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="DeleteIf">DeleteIf</span>
|
||||||
|
<p>删除列表中所有符合函数(调用函数返回true)的元素,返回删除元素的数量</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) DeleteIf(f func(T) bool) int
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
||||||
|
|
||||||
|
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
|
||||||
|
fmt.Println(l.Data()) // []int{2, 3, 4}
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -251,7 +251,7 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func BeginOfWeek(t time.Time) time.Time
|
func BeginOfWeek(t time.Time, beginFrom ...time.Weekday) time.Time
|
||||||
```
|
```
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
@@ -414,7 +414,7 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func EndOfWeek(t time.Time) time.Time
|
func EndOfWeek(t time.Time, endWith ...time.Weekday) time.Time
|
||||||
```
|
```
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
|
|||||||
@@ -243,12 +243,12 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
### <span id="BeginOfWeek">BeginOfWeek</span>
|
### <span id="BeginOfWeek">BeginOfWeek</span>
|
||||||
<p>返回指定时间的星期开始时间</p>
|
<p>返回指定时间的每周开始时间,默认开始时间星期日</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func BeginOfWeek(t time.Time) time.Time
|
func BeginOfWeek(t time.Time, beginFrom ...time.Weekday) time.Time
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
@@ -406,12 +406,12 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
### <span id="EndOfWeek">EndOfWeek</span>
|
### <span id="EndOfWeek">EndOfWeek</span>
|
||||||
<p>返回指定时间的星期结束时间</p>
|
<p>返回指定时间的星期结束时间,默认结束时间星期六</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func EndOfWeek(t time.Time) time.Time
|
func EndOfWeek(t time.Time, endWith ...time.Weekday) time.Time
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
- [Compose](#Compose)
|
- [Compose](#Compose)
|
||||||
- [Debounced](#Debounced)
|
- [Debounced](#Debounced)
|
||||||
- [Delay](#Delay)
|
- [Delay](#Delay)
|
||||||
|
- [Pipeline](#Pipeline)
|
||||||
- [Watcher](#Watcher)
|
- [Watcher](#Watcher)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -101,8 +102,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
assert := internal.NewAssert(t, "TestBefore")
|
|
||||||
|
|
||||||
arr := []string{"a", "b", "c", "d", "e"}
|
arr := []string{"a", "b", "c", "d", "e"}
|
||||||
f := function.Before(3, func(i int) int {
|
f := function.Before(3, func(i int) int {
|
||||||
return i
|
return i
|
||||||
@@ -120,7 +119,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expected := []int64{0, 1, 2, 2, 2}
|
expected := []int64{0, 1, 2, 2, 2}
|
||||||
assert.Equal(expected, res)
|
fmt.Println(res) // 0, 1, 2, 2, 2
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -302,6 +301,43 @@ func main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Pipeline">Pipeline</span>
|
||||||
|
|
||||||
|
<p>Pipeline takes a list of functions and returns a function whose param will be passed into
|
||||||
|
the functions one by one.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Pipeline[T any](funcs ...func(T) T) func(T) T
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/function"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
addOne := func(x int) int {
|
||||||
|
return x + 1
|
||||||
|
}
|
||||||
|
double := func(x int) int {
|
||||||
|
return 2 * x
|
||||||
|
}
|
||||||
|
square := func(x int) int {
|
||||||
|
return x * x
|
||||||
|
}
|
||||||
|
|
||||||
|
f := Pipeline(addOne, double, square)
|
||||||
|
|
||||||
|
fmt.Println(f(2)) //36
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="Watcher">Watcher</span>
|
### <span id="Watcher">Watcher</span>
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
- [Compose](#Compose)
|
- [Compose](#Compose)
|
||||||
- [Debounced](#Debounced)
|
- [Debounced](#Debounced)
|
||||||
- [Delay](#Delay)
|
- [Delay](#Delay)
|
||||||
|
- [Pipeline](#Pipeline)
|
||||||
- [Watcher](#Watcher)
|
- [Watcher](#Watcher)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -101,8 +102,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
assert := internal.NewAssert(t, "TestBefore")
|
|
||||||
|
|
||||||
arr := []string{"a", "b", "c", "d", "e"}
|
arr := []string{"a", "b", "c", "d", "e"}
|
||||||
f := function.Before(3, func(i int) int {
|
f := function.Before(3, func(i int) int {
|
||||||
return i
|
return i
|
||||||
@@ -119,8 +118,7 @@ func main() {
|
|||||||
appendStr(i, arr[i], f)
|
appendStr(i, arr[i], f)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := []int64{0, 1, 2, 2, 2}
|
fmt.Println(res) // 0, 1, 2, 2, 2
|
||||||
assert.Equal(expected, res)
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -303,6 +301,44 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Pipeline">Pipeline</span>
|
||||||
|
|
||||||
|
<p>执行函数pipeline.</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Pipeline[T any](funcs ...func(T) T) func(T) T
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/function"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
addOne := func(x int) int {
|
||||||
|
return x + 1
|
||||||
|
}
|
||||||
|
double := func(x int) int {
|
||||||
|
return 2 * x
|
||||||
|
}
|
||||||
|
square := func(x int) int {
|
||||||
|
return x * x
|
||||||
|
}
|
||||||
|
|
||||||
|
f := Pipeline(addOne, double, square)
|
||||||
|
|
||||||
|
fmt.Println(f(2)) //36
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Watcher">Watcher</span>
|
### <span id="Watcher">Watcher</span>
|
||||||
|
|
||||||
<p>Watcher 用于记录代码执行时间。可以启动/停止/重置手表定时器。获取函数执行的时间。 </p>
|
<p>Watcher 用于记录代码执行时间。可以启动/停止/重置手表定时器。获取函数执行的时间。 </p>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Package maputil includes some functions to manipulate map.
|
|||||||
|
|
||||||
## Source:
|
## Source:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/maputil/maputil.go](https://github.com/duke-git/lancet/blob/main/maputil/maputil.go)
|
- [https://github.com/duke-git/lancet/blob/main/maputil/map.go](https://github.com/duke-git/lancet/blob/main/maputil/map.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
- [Merge](#Merge)
|
- [Merge](#Merge)
|
||||||
- [Minus](#Minus)
|
- [Minus](#Minus)
|
||||||
- [Values](#Values)
|
- [Values](#Values)
|
||||||
|
- [IsDisjoint](#IsDisjoint)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -302,3 +303,50 @@ func main() {
|
|||||||
fmt.Println(values) // []string{"a", "a", "b", "c", "d"}
|
fmt.Println(values) // []string{"a", "a", "b", "c", "d"}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="IsDisjoint">IsDisjoint</span>
|
||||||
|
<p>Checks two maps are disjoint if they have no keys in common</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsDisjoint[K comparable, V any](mapA, mapB map[K]V) bool
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/maputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
m1 := map[int]string{
|
||||||
|
1: "a",
|
||||||
|
2: "a",
|
||||||
|
3: "b",
|
||||||
|
4: "c",
|
||||||
|
5: "d",
|
||||||
|
}
|
||||||
|
|
||||||
|
m2 := map[int]string{
|
||||||
|
1: "a",
|
||||||
|
2: "a",
|
||||||
|
3: "b",
|
||||||
|
4: "c",
|
||||||
|
5: "d",
|
||||||
|
}
|
||||||
|
|
||||||
|
m3 := map[int]string{
|
||||||
|
6: "a",
|
||||||
|
}
|
||||||
|
|
||||||
|
ok := maputil.IsDisjoint(m2, m1)
|
||||||
|
fmt.Println(ok) // false
|
||||||
|
|
||||||
|
ok = maputil.IsDisjoint(m2, m3)
|
||||||
|
fmt.Println(ok) // true
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -5,7 +5,7 @@ maputil包包括一些操作map的函数。
|
|||||||
|
|
||||||
## 源码:
|
## 源码:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/maputil/maputil.go](https://github.com/duke-git/lancet/blob/main/maputil/maputil.go)
|
- [https://github.com/duke-git/lancet/blob/main/maputil/map.go](https://github.com/duke-git/lancet/blob/main/maputil/map.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
- [Merge](#Merge)
|
- [Merge](#Merge)
|
||||||
- [Minus](#Minus)
|
- [Minus](#Minus)
|
||||||
- [Values](#Values)
|
- [Values](#Values)
|
||||||
|
- [IsDisjoint](#IsDisjoint)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -231,7 +232,6 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Minus">Minus</span>
|
### <span id="Minus">Minus</span>
|
||||||
<p>返回一个map,其中的key存在于mapA,不存在于mapB.</p>
|
<p>返回一个map,其中的key存在于mapA,不存在于mapB.</p>
|
||||||
|
|
||||||
@@ -302,3 +302,51 @@ func main() {
|
|||||||
fmt.Println(values) // []string{"a", "a", "b", "c", "d"}
|
fmt.Println(values) // []string{"a", "a", "b", "c", "d"}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="IsDisjoint">IsDisjoint</span>
|
||||||
|
<p>验证两个map是否具有不同的key</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsDisjoint[K comparable, V any](mapA, mapB map[K]V) bool
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/maputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
m1 := map[int]string{
|
||||||
|
1: "a",
|
||||||
|
2: "a",
|
||||||
|
3: "b",
|
||||||
|
4: "c",
|
||||||
|
5: "d",
|
||||||
|
}
|
||||||
|
|
||||||
|
m2 := map[int]string{
|
||||||
|
1: "a",
|
||||||
|
2: "a",
|
||||||
|
3: "b",
|
||||||
|
4: "c",
|
||||||
|
5: "d",
|
||||||
|
}
|
||||||
|
|
||||||
|
m3 := map[int]string{
|
||||||
|
6: "a",
|
||||||
|
}
|
||||||
|
|
||||||
|
ok := maputil.IsDisjoint(m2, m1)
|
||||||
|
fmt.Println(ok) // false
|
||||||
|
|
||||||
|
ok = maputil.IsDisjoint(m2, m3)
|
||||||
|
fmt.Println(ok) // true
|
||||||
|
}
|
||||||
|
```
|
||||||
283
docs/netutil.md
283
docs/netutil.md
@@ -7,6 +7,8 @@ Package netutil contains functions to get net information and send http request.
|
|||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go)
|
- [https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go)
|
||||||
|
|
||||||
|
- [https://github.com/duke-git/lancet/blob/main/netutil/http_client.go](https://github.com/duke-git/lancet/blob/main/netutil/http_client.go)
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go)
|
- [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -22,6 +24,8 @@ import (
|
|||||||
|
|
||||||
## Index
|
## Index
|
||||||
- [ConvertMapToQueryString](#ConvertMapToQueryString)
|
- [ConvertMapToQueryString](#ConvertMapToQueryString)
|
||||||
|
- [EncodeUrl](#EncodeUrl)
|
||||||
|
|
||||||
- [GetInternalIp](#GetInternalIp)
|
- [GetInternalIp](#GetInternalIp)
|
||||||
- [GetIps](#GetIps)
|
- [GetIps](#GetIps)
|
||||||
- [GetMacAddrs](#GetMacAddrs)
|
- [GetMacAddrs](#GetMacAddrs)
|
||||||
@@ -29,12 +33,17 @@ import (
|
|||||||
- [GetRequestPublicIp](#GetRequestPublicIp)
|
- [GetRequestPublicIp](#GetRequestPublicIp)
|
||||||
- [IsPublicIP](#IsPublicIP)
|
- [IsPublicIP](#IsPublicIP)
|
||||||
- [IsInternalIP](#IsInternalIP)
|
- [IsInternalIP](#IsInternalIP)
|
||||||
- [HttpGet](#HttpGet)
|
- [HttpRequest](#HttpRequest)
|
||||||
- [HttpDelete](#HttpDelete)
|
- [HttpClient](#HttpClient)
|
||||||
- [HttpPost](#HttpPost)
|
- [SendRequest](#SendRequest)
|
||||||
- [HttpPut](#HttpPut)
|
- [DecodeResponse](#DecodeResponse)
|
||||||
|
- [StructToUrlValues](#StructToUrlValues)
|
||||||
|
|
||||||
- [HttpPatch](#HttpPatch)
|
- [HttpGet<sup>Deprecated</sup>](#HttpGet)
|
||||||
|
- [HttpDelete<sup>Deprecated</sup>](#HttpDelete)
|
||||||
|
- [HttpPost<sup>Deprecated</sup>](#HttpPost)
|
||||||
|
- [HttpPut<sup>Deprecated</sup>](#HttpPut)
|
||||||
|
- [HttpPatch<sup>Deprecated</sup>](#HttpPatch)
|
||||||
- [ParseHttpResponse](#ParseHttpResponse)
|
- [ParseHttpResponse](#ParseHttpResponse)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -74,6 +83,36 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="EncodeUrl">EncodeUrl</span>
|
||||||
|
<p>Encode url query string values.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EncodeUrl(urlStr string) (string, error)
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
urlAddr := "http://www.lancet.com?a=1&b=[2]"
|
||||||
|
encodedUrl, err := netutil.EncodeUrl(urlAddr)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
fmt.Println(encodedUrl) //http://www.lancet.com?a=1&b=%5B2%5D
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="GetInternalIp">GetInternalIp</span>
|
### <span id="GetInternalIp">GetInternalIp</span>
|
||||||
<p>Get internal ip information.</p>
|
<p>Get internal ip information.</p>
|
||||||
|
|
||||||
@@ -304,8 +343,232 @@ func main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="HttpRequest">HttpRequest</span>
|
||||||
|
<p>HttpRequest is a struct used to abstract HTTP request entity.</p>
|
||||||
|
|
||||||
### <span id="HttpGet">HttpGet</span>
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
type HttpRequest struct {
|
||||||
|
RawURL string
|
||||||
|
Method string
|
||||||
|
Headers http.Header
|
||||||
|
QueryParams url.Values
|
||||||
|
FormData url.Values
|
||||||
|
Body []byte
|
||||||
|
}
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"github.com/duke-git/lancet/v2/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
header := http.Header{}
|
||||||
|
header.Add("Content-Type", "multipart/form-data")
|
||||||
|
|
||||||
|
postData := url.Values{}
|
||||||
|
postData.Add("userId", "1")
|
||||||
|
postData.Add("title", "testItem")
|
||||||
|
|
||||||
|
request := &netutil.HttpRequest{
|
||||||
|
RawURL: "https://jsonplaceholder.typicode.com/todos",
|
||||||
|
Method: "POST",
|
||||||
|
Headers: header,
|
||||||
|
FormData: postData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="HttpClient">HttpClient</span>
|
||||||
|
<p>HttpClient is a struct used to send HTTP request. It can be instanced with some configurations or none config.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
type HttpClient struct {
|
||||||
|
*http.Client
|
||||||
|
TLS *tls.Config
|
||||||
|
Request *http.Request
|
||||||
|
Config HttpClientConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type HttpClientConfig struct {
|
||||||
|
SSLEnabled bool
|
||||||
|
TLSConfig *tls.Config
|
||||||
|
Compressed bool
|
||||||
|
HandshakeTimeout time.Duration
|
||||||
|
ResponseTimeout time.Duration
|
||||||
|
Verbose bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHttpClient() *HttpClient
|
||||||
|
|
||||||
|
func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
httpClientCfg := netutil.HttpClientConfig{
|
||||||
|
SSLEnabled: true,
|
||||||
|
HandshakeTimeout:10 * time.Second
|
||||||
|
}
|
||||||
|
httpClient := netutil.NewHttpClientWithConfig(&httpClientCfg)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="SendRequest">SendRequest</span>
|
||||||
|
<p>Use HttpClient to send HTTP request.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error)
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
request := &netutil.HttpRequest{
|
||||||
|
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||||
|
Method: "GET",
|
||||||
|
}
|
||||||
|
|
||||||
|
httpClient := netutil.NewHttpClient()
|
||||||
|
resp, err := httpClient.SendRequest(request)
|
||||||
|
if err != nil || resp.StatusCode != 200 {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Todo struct {
|
||||||
|
UserId int `json:"userId"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Completed bool `json:"completed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var todo Todo
|
||||||
|
httpClient.DecodeResponse(resp, &todo)
|
||||||
|
|
||||||
|
fmt.Println(todo.Id) //1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="DecodeResponse">DecodeResponse</span>
|
||||||
|
<p>Decode http response into target object.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
request := &netutil.HttpRequest{
|
||||||
|
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||||
|
Method: "GET",
|
||||||
|
}
|
||||||
|
|
||||||
|
httpClient := netutil.NewHttpClient()
|
||||||
|
resp, err := httpClient.SendRequest(request)
|
||||||
|
if err != nil || resp.StatusCode != 200 {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Todo struct {
|
||||||
|
UserId int `json:"userId"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Completed bool `json:"completed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var todo Todo
|
||||||
|
httpClient.DecodeResponse(resp, &todo)
|
||||||
|
|
||||||
|
fmt.Println(todo.Id) //1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="StructToUrlValues">StructToUrlValues</span>
|
||||||
|
<p>Convert struct to url values, only convert the field which is exported and has `json` tag.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func StructToUrlValues(targetStruct any) url.Values
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
type TodoQuery struct {
|
||||||
|
Id int `json:"id"`
|
||||||
|
UserId int `json:"userId"`
|
||||||
|
}
|
||||||
|
todoQuery := TodoQuery{
|
||||||
|
Id: 1,
|
||||||
|
UserId: 2,
|
||||||
|
}
|
||||||
|
todoValues := netutil.StructToUrlValues(todoQuery)
|
||||||
|
|
||||||
|
fmt.Println(todoValues.Get("id")) //1
|
||||||
|
fmt.Println(todoValues.Get("userId")) //2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="HttpGet">HttpGet (Deprecated: use SendRequest for replacement)</span>
|
||||||
<p>Send http get request.</p>
|
<p>Send http get request.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -347,7 +610,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HttpPost">HttpPost</span>
|
### <span id="HttpPost">HttpPost (Deprecated: use SendRequest for replacement)</span>
|
||||||
<p>Send http post request.</p>
|
<p>Send http post request.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -396,7 +659,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HttpPut">HttpPut</span>
|
### <span id="HttpPut">HttpPut (Deprecated: use SendRequest for replacement)</span>
|
||||||
<p>Send http put request.</p>
|
<p>Send http put request.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -446,7 +709,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HttpDelete">HttpDelete</span>
|
### <span id="HttpDelete">HttpDelete (Deprecated: use SendRequest for replacement)</span>
|
||||||
<p>Send http delete request.</p>
|
<p>Send http delete request.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -485,7 +748,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HttpPatch">HttpPatch</span>
|
### <span id="HttpPatch">HttpPatch (Deprecated: use SendRequest for replacement)</span>
|
||||||
<p>Send http patch request.</p>
|
<p>Send http patch request.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ netutil网络包支持获取ip地址,发送http请求。
|
|||||||
## 源码:
|
## 源码:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go)
|
- [https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go)
|
||||||
|
|
||||||
|
- [https://github.com/duke-git/lancet/blob/main/netutil/http_client.go](https://github.com/duke-git/lancet/blob/main/netutil/http_client.go)
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go)
|
- [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -21,6 +24,7 @@ import (
|
|||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
- [ConvertMapToQueryString](#ConvertMapToQueryString)
|
- [ConvertMapToQueryString](#ConvertMapToQueryString)
|
||||||
|
- [EncodeUrl](#EncodeUrl)
|
||||||
- [GetInternalIp](#GetInternalIp)
|
- [GetInternalIp](#GetInternalIp)
|
||||||
- [GetIps](#GetIps)
|
- [GetIps](#GetIps)
|
||||||
- [GetMacAddrs](#GetMacAddrs)
|
- [GetMacAddrs](#GetMacAddrs)
|
||||||
@@ -29,11 +33,18 @@ import (
|
|||||||
|
|
||||||
- [IsPublicIP](#IsPublicIP)
|
- [IsPublicIP](#IsPublicIP)
|
||||||
- [IsInternalIP](#IsInternalIP)
|
- [IsInternalIP](#IsInternalIP)
|
||||||
- [HttpGet](#HttpGet)
|
- [HttpRequest](#HttpRequest)
|
||||||
- [HttpDelete](#HttpDelete)
|
- [HttpClient](#HttpClient)
|
||||||
- [HttpPost](#HttpPost)
|
- [SendRequest](#SendRequest)
|
||||||
- [HttpPut](#HttpPut)
|
- [DecodeResponse](#DecodeResponse)
|
||||||
- [HttpPatch](#HttpPatch)
|
- [StructToUrlValues](#StructToUrlValues)
|
||||||
|
|
||||||
|
- [HttpGet<sup>Deprecated</sup>](#HttpGet)
|
||||||
|
- [HttpDelete<sup>Deprecated</sup>](#HttpDelete)
|
||||||
|
- [HttpPost<sup>Deprecated</sup>](#HttpPost)
|
||||||
|
- [HttpPut<sup>Deprecated</sup>](#HttpPut)
|
||||||
|
- [HttpPatch<sup>Deprecated</sup>](#HttpPatch)
|
||||||
|
|
||||||
- [ParseHttpResponse](#ParseHttpResponse)
|
- [ParseHttpResponse](#ParseHttpResponse)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -73,6 +84,37 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="EncodeUrl">EncodeUrl</span>
|
||||||
|
<p>编码url query string的值</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EncodeUrl(urlStr string) (string, error)
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
urlAddr := "http://www.lancet.com?a=1&b=[2]"
|
||||||
|
encodedUrl, err := netutil.EncodeUrl(urlAddr)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
fmt.Println(encodedUrl) //http://www.lancet.com?a=1&b=%5B2%5D
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="GetInternalIp">GetInternalIp</span>
|
### <span id="GetInternalIp">GetInternalIp</span>
|
||||||
<p>获取内部ip</p>
|
<p>获取内部ip</p>
|
||||||
|
|
||||||
@@ -302,8 +344,232 @@ func main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="HttpRequest">HttpRequest</span>
|
||||||
|
<p>HttpRequest用于抽象HTTP请求实体的结构</p>
|
||||||
|
|
||||||
### <span id="HttpGet">HttpGet</span>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
type HttpRequest struct {
|
||||||
|
RawURL string
|
||||||
|
Method string
|
||||||
|
Headers http.Header
|
||||||
|
QueryParams url.Values
|
||||||
|
FormData url.Values
|
||||||
|
Body []byte
|
||||||
|
}
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"github.com/duke-git/lancet/v2/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
header := http.Header{}
|
||||||
|
header.Add("Content-Type", "multipart/form-data")
|
||||||
|
|
||||||
|
postData := url.Values{}
|
||||||
|
postData.Add("userId", "1")
|
||||||
|
postData.Add("title", "testItem")
|
||||||
|
|
||||||
|
request := &netutil.HttpRequest{
|
||||||
|
RawURL: "https://jsonplaceholder.typicode.com/todos",
|
||||||
|
Method: "POST",
|
||||||
|
Headers: header,
|
||||||
|
FormData: postData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="HttpClient">HttpClient</span>
|
||||||
|
<p>HttpClient是用于发送HTTP请求的结构体。它可以用一些配置参数或无配置实例化.</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
type HttpClient struct {
|
||||||
|
*http.Client
|
||||||
|
TLS *tls.Config
|
||||||
|
Request *http.Request
|
||||||
|
Config HttpClientConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type HttpClientConfig struct {
|
||||||
|
SSLEnabled bool
|
||||||
|
TLSConfig *tls.Config
|
||||||
|
Compressed bool
|
||||||
|
HandshakeTimeout time.Duration
|
||||||
|
ResponseTimeout time.Duration
|
||||||
|
Verbose bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHttpClient() *HttpClient
|
||||||
|
|
||||||
|
func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
httpClientCfg := netutil.HttpClientConfig{
|
||||||
|
SSLEnabled: true,
|
||||||
|
HandshakeTimeout:10 * time.Second
|
||||||
|
}
|
||||||
|
httpClient := netutil.NewHttpClientWithConfig(&httpClientCfg)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="SendRequest">SendRequest</span>
|
||||||
|
<p>HttpClient发送http请求</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error)
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
request := &netutil.HttpRequest{
|
||||||
|
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||||
|
Method: "GET",
|
||||||
|
}
|
||||||
|
|
||||||
|
httpClient := netutil.NewHttpClient()
|
||||||
|
resp, err := httpClient.SendRequest(request)
|
||||||
|
if err != nil || resp.StatusCode != 200 {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Todo struct {
|
||||||
|
UserId int `json:"userId"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Completed bool `json:"completed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var todo Todo
|
||||||
|
httpClient.DecodeResponse(resp, &todo)
|
||||||
|
|
||||||
|
fmt.Println(todo.Id) //1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="DecodeResponse">DecodeResponse</span>
|
||||||
|
<p>解析http响应体到目标结构体</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
request := &netutil.HttpRequest{
|
||||||
|
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||||
|
Method: "GET",
|
||||||
|
}
|
||||||
|
|
||||||
|
httpClient := netutil.NewHttpClient()
|
||||||
|
resp, err := httpClient.SendRequest(request)
|
||||||
|
if err != nil || resp.StatusCode != 200 {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Todo struct {
|
||||||
|
UserId int `json:"userId"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Completed bool `json:"completed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var todo Todo
|
||||||
|
httpClient.DecodeResponse(resp, &todo)
|
||||||
|
|
||||||
|
fmt.Println(todo.Id) //1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="StructToUrlValues">StructToUrlValues</span>
|
||||||
|
<p>将结构体转为url values, 仅转化结构体导出字段并且包含`json` tag.</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func StructToUrlValues(targetStruct any) url.Values
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
type TodoQuery struct {
|
||||||
|
Id int `json:"id"`
|
||||||
|
UserId int `json:"userId"`
|
||||||
|
}
|
||||||
|
todoQuery := TodoQuery{
|
||||||
|
Id: 1,
|
||||||
|
UserId: 2,
|
||||||
|
}
|
||||||
|
todoValues := netutil.StructToUrlValues(todoQuery)
|
||||||
|
|
||||||
|
fmt.Println(todoValues.Get("id")) //1
|
||||||
|
fmt.Println(todoValues.Get("userId")) //2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="HttpGet">HttpGet (Deprecated: use SendRequest for replacement)</span>
|
||||||
<p>发送http get请求</p>
|
<p>发送http get请求</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -345,7 +611,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HttpPost">HttpPost</span>
|
### <span id="HttpPost">HttpPost (Deprecated: use SendRequest for replacement)</span>
|
||||||
<p>发送http post请求</p>
|
<p>发送http post请求</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -394,7 +660,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HttpPut">HttpPut</span>
|
### <span id="HttpPut">HttpPut (Deprecated: use SendRequest for replacement)</span>
|
||||||
<p>发送http put请求</p>
|
<p>发送http put请求</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -406,7 +672,7 @@ func main() {
|
|||||||
// params[3] http client,类型必须是http.Client
|
// params[3] http client,类型必须是http.Client
|
||||||
func HttpPut(url string, params ...any) (*http.Response, error)
|
func HttpPut(url string, params ...any) (*http.Response, error)
|
||||||
```
|
```
|
||||||
<b>Example:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -444,7 +710,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HttpDelete">HttpDelete</span>
|
### <span id="HttpDelete">HttpDelete (Deprecated: use SendRequest for replacement)</span>
|
||||||
<p>发送http delete请求</p>
|
<p>发送http delete请求</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -483,7 +749,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HttpPatch">HttpPatch</span>
|
### <span id="HttpPatch">HttpPatch (Deprecated: use SendRequest for replacement)</span>
|
||||||
<p>发送http patch请求</p>
|
<p>发送http patch请求</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|||||||
128
docs/random.md
128
docs/random.md
@@ -1,4 +1,5 @@
|
|||||||
# Random
|
# Random
|
||||||
|
|
||||||
Package random implements some basic functions to generate random int and string.
|
Package random implements some basic functions to generate random int and string.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -7,10 +8,10 @@ Package random implements some basic functions to generate random int and string
|
|||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go)
|
- [https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Usage:
|
## Usage:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/random"
|
"github.com/duke-git/lancet/v2/random"
|
||||||
@@ -20,17 +21,23 @@ import (
|
|||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
|
|
||||||
- [RandBytes](#RandBytes)
|
- [RandBytes](#RandBytes)
|
||||||
- [RandInt](#RandInt)
|
- [RandInt](#RandInt)
|
||||||
- [RandString](#RandString)
|
- [RandString](#RandString)
|
||||||
|
- [RandUpper](#RandUpper)
|
||||||
|
|
||||||
|
- [RandLower](#RandLower)
|
||||||
|
- [RandNumeral](#RandNumeral)
|
||||||
|
- [RandNumeralOrLetter](#RandNumeralOrLetter)
|
||||||
- [UUIdV4](#UUIdV4)
|
- [UUIdV4](#UUIdV4)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|
||||||
### <span id="RandBytes">RandBytes</span>
|
### <span id="RandBytes">RandBytes</span>
|
||||||
|
|
||||||
<p>Generate random byte slice.</p>
|
<p>Generate random byte slice.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -38,6 +45,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func RandBytes(length int) []byte
|
func RandBytes(length int) []byte
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -54,8 +62,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="RandInt">RandInt</span>
|
### <span id="RandInt">RandInt</span>
|
||||||
|
|
||||||
<p>Generate random int between min and max, may contain min, not max.</p>
|
<p>Generate random int between min and max, may contain min, not max.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -63,6 +71,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RandInt(min, max int) int
|
func RandInt(min, max int) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -79,16 +88,16 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="RandString">RandString</span>
|
||||||
|
|
||||||
|
<p>Generate random given length string. only contains letter (a-zA-Z)</p>
|
||||||
### <span id="RandString">RandInt</span>
|
|
||||||
<p>Generate random given length string.</p>
|
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func RandString(length int) string
|
func RandString(length int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -101,14 +110,116 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
randStr := random.RandString(6)
|
randStr := random.RandString(6)
|
||||||
fmt.Println(randStr)
|
fmt.Println(randStr) //pGWsze
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="RandUpper">RandUpper</span>
|
||||||
|
|
||||||
|
<p>Generate a random upper case string</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandUpper(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandString(6)
|
||||||
|
fmt.Println(randStr) //PACWGF
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandLower">RandLower</span>
|
||||||
|
|
||||||
|
<p>Generate a random lower case string</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandLower(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandLower(6)
|
||||||
|
fmt.Println(randStr) //siqbew
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandNumeral">RandNumeral</span>
|
||||||
|
|
||||||
|
<p>Generate a random numeral string</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandNumeral(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandNumeral(6)
|
||||||
|
fmt.Println(randStr) //035172
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandNumeralOrLetter">RandNumeralOrLetter</span>
|
||||||
|
|
||||||
|
<p>generate a random numeral or letter string</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandNumeralOrLetter(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandNumeralOrLetter(6)
|
||||||
|
fmt.Println(randStr) //0aW7cQ
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="UUIdV4">UUIdV4</span>
|
### <span id="UUIdV4">UUIdV4</span>
|
||||||
|
|
||||||
<p>Generate a random UUID of version 4 according to RFC 4122.</p>
|
<p>Generate a random UUID of version 4 according to RFC 4122.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -116,6 +227,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func UUIdV4() (string, error)
|
func UUIdV4() (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -134,5 +246,3 @@ func main() {
|
|||||||
fmt.Println(uuid)
|
fmt.Println(uuid)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# Random
|
# Random
|
||||||
|
|
||||||
random 随机数生成器包,可以生成随机[]bytes, int, string。
|
random 随机数生成器包,可以生成随机[]bytes, int, string。
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -7,10 +8,10 @@ random随机数生成器包,可以生成随机[]bytes, int, string。
|
|||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go)
|
- [https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 用法:
|
## 用法:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/random"
|
"github.com/duke-git/lancet/v2/random"
|
||||||
@@ -20,18 +21,23 @@ import (
|
|||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
|
|
||||||
- [RandBytes](#RandBytes)
|
- [RandBytes](#RandBytes)
|
||||||
- [RandInt](#RandInt)
|
- [RandInt](#RandInt)
|
||||||
- [RandString](#RandString)
|
- [RandString](#RandString)
|
||||||
- [UUIdV4](#UUIdV4)
|
- [RandUpper](#RandUpper)
|
||||||
|
|
||||||
|
- [RandLower](#RandLower)
|
||||||
|
- [RandNumeral](#RandNumeral)
|
||||||
|
- [RandNumeralOrLetter](#RandNumeralOrLetter)
|
||||||
|
- [UUIdV4](#UUIdV4)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
|
|
||||||
### <span id="RandBytes">RandBytes</span>
|
### <span id="RandBytes">RandBytes</span>
|
||||||
|
|
||||||
<p>生成随机字节切片</p>
|
<p>生成随机字节切片</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -39,6 +45,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func RandBytes(length int) []byte
|
func RandBytes(length int) []byte
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -55,8 +62,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="RandInt">RandInt</span>
|
### <span id="RandInt">RandInt</span>
|
||||||
|
|
||||||
<p>生成随机int, 范围[min, max)</p>
|
<p>生成随机int, 范围[min, max)</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -64,6 +71,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RandInt(min, max int) int
|
func RandInt(min, max int) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -80,16 +88,16 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="RandString">RandString</span>
|
||||||
|
|
||||||
|
<p>生成给定长度的随机字符串,只包含字母(a-zA-Z)</p>
|
||||||
### <span id="RandString">RandInt</span>
|
|
||||||
<p>生成随机给定长度的随机字符串</p>
|
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func RandString(length int) string
|
func RandString(length int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -102,13 +110,116 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
randStr := random.RandString(6)
|
randStr := random.RandString(6)
|
||||||
fmt.Println(randStr)
|
fmt.Println(randStr) //pGWsze
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="RandUpper">RandUpper</span>
|
||||||
|
|
||||||
|
<p>生成给定长度的随机大写字母字符串</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandUpper(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandString(6)
|
||||||
|
fmt.Println(randStr) //PACWGF
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandLower">RandLower</span>
|
||||||
|
|
||||||
|
<p>生成给定长度的随机小写字母字符串</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandLower(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandLower(6)
|
||||||
|
fmt.Println(randStr) //siqbew
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandNumeral">RandNumeral</span>
|
||||||
|
|
||||||
|
<p>生成给定长度的随机数字字符串</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandNumeral(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandNumeral(6)
|
||||||
|
fmt.Println(randStr) //035172
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandNumeralOrLetter">RandNumeralOrLetter</span>
|
||||||
|
|
||||||
|
<p>生成给定长度的随机字符串(数字+字母)</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandNumeralOrLetter(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandNumeralOrLetter(6)
|
||||||
|
fmt.Println(randStr) //0aW7cQ
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="UUIdV4">UUIdV4</span>
|
### <span id="UUIdV4">UUIdV4</span>
|
||||||
|
|
||||||
<p>生成UUID v4字符串</p>
|
<p>生成UUID v4字符串</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -116,6 +227,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func UUIdV4() (string, error)
|
func UUIdV4() (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -134,5 +246,3 @@ func main() {
|
|||||||
fmt.Println(uuid)
|
fmt.Println(uuid)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -97,8 +97,8 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var number int
|
var number int
|
||||||
var increaseNumber retry.RetryFunc
|
|
||||||
increaseNumber = func() error {
|
increaseNumber := func() error {
|
||||||
number++
|
number++
|
||||||
if number == 3 {
|
if number == 3 {
|
||||||
return nil
|
return nil
|
||||||
@@ -139,6 +139,7 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var number int
|
var number int
|
||||||
|
|
||||||
increaseNumber := func() error {
|
increaseNumber := func() error {
|
||||||
number++
|
number++
|
||||||
if number == 3 {
|
if number == 3 {
|
||||||
|
|||||||
@@ -99,8 +99,7 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var number int
|
var number int
|
||||||
var increaseNumber retry.RetryFunc
|
increaseNumber := func() error {
|
||||||
increaseNumber = func() error {
|
|
||||||
number++
|
number++
|
||||||
if number == 3 {
|
if number == 3 {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
337
docs/slice.md
337
docs/slice.md
@@ -1,4 +1,5 @@
|
|||||||
# Slice
|
# Slice
|
||||||
|
|
||||||
Package slice implements some functions to manipulate slice.
|
Package slice implements some functions to manipulate slice.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -7,10 +8,10 @@ Package slice implements some functions to manipulate slice.
|
|||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go)
|
- [https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Usage:
|
## Usage:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/slice"
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
@@ -20,6 +21,8 @@ import (
|
|||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
|
|
||||||
|
- [AppendIfAbsent](#AppendIfAbsent)
|
||||||
- [Contain](#Contain)
|
- [Contain](#Contain)
|
||||||
- [ContainSubSlice](#ContainSubSlice)
|
- [ContainSubSlice](#ContainSubSlice)
|
||||||
- [Chunk](#Chunk)
|
- [Chunk](#Chunk)
|
||||||
@@ -37,6 +40,7 @@ import (
|
|||||||
- [Filter](#Filter)
|
- [Filter](#Filter)
|
||||||
- [Find](#Find)
|
- [Find](#Find)
|
||||||
- [FindLast](#FindLast)
|
- [FindLast](#FindLast)
|
||||||
|
- [Flatten](#Flatten)
|
||||||
- [FlattenDeep](#FlattenDeep)
|
- [FlattenDeep](#FlattenDeep)
|
||||||
- [ForEach](#ForEach)
|
- [ForEach](#ForEach)
|
||||||
|
|
||||||
@@ -51,22 +55,57 @@ import (
|
|||||||
- [Map](#Map)
|
- [Map](#Map)
|
||||||
- [Reverse](#Reverse)
|
- [Reverse](#Reverse)
|
||||||
- [Reduce](#Reduce)
|
- [Reduce](#Reduce)
|
||||||
|
- [Replace](#Replace)
|
||||||
|
- [ReplaceAll](#ReplaceAll)
|
||||||
- [Shuffle](#Shuffle)
|
- [Shuffle](#Shuffle)
|
||||||
- [SortByField](#SortByField)
|
- [SortByField](#SortByField)
|
||||||
- [Some](#Some)
|
- [Some](#Some)
|
||||||
- [StringSlice](#StringSlice)
|
- [StringSlice](#StringSlice)
|
||||||
- [SymmetricDifference](#SymmetricDifference)
|
- [SymmetricDifference](#SymmetricDifference)
|
||||||
|
- [ToSlice](#ToSlice)
|
||||||
|
- [ToSlicePointer](#ToSlicePointer)
|
||||||
- [Unique](#Unique)
|
- [Unique](#Unique)
|
||||||
- [UniqueBy](#UniqueBy)
|
- [UniqueBy](#UniqueBy)
|
||||||
- [Union](#Union)
|
- [Union](#Union)
|
||||||
|
- [UnionBy](#UnionBy)
|
||||||
- [UpdateAt](#UpdateAt)
|
- [UpdateAt](#UpdateAt)
|
||||||
- [Without](#Without)
|
- [Without](#Without)
|
||||||
|
- [KeyBy](#KeyBy)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
### <span id="AppendIfAbsent">AppendIfAbsent</span>
|
||||||
|
|
||||||
|
<p>If slice doesn't contain the value, append it to the slice.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AppendIfAbsent[T comparable](slice []T, value T) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
strs := []string{"a", "b"}
|
||||||
|
res1 := slice.AppendIfAbsent(strs, "a")
|
||||||
|
fmt.Println(res1) //[]string{"a", "b"}
|
||||||
|
|
||||||
|
res2 := slice.AppendIfAbsent(strs, "cannot")
|
||||||
|
fmt.Println(res2"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Contain">Contain</span>
|
### <span id="Contain">Contain</span>
|
||||||
|
|
||||||
<p>Check if the value is in the slice or not.</p>
|
<p>Check if the value is in the slice or not.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -74,6 +113,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func Contain[T comparable](slice []T, value T) bool
|
func Contain[T comparable](slice []T, value T) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -88,8 +128,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="ContainSubSlice">ContainSubSlice</span>
|
### <span id="ContainSubSlice">ContainSubSlice</span>
|
||||||
|
|
||||||
<p>Check if the slice contain subslice or not.</p>
|
<p>Check if the slice contain subslice or not.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -97,6 +137,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ContainSubSlice[T comparable](slice, subslice []T) bool
|
func ContainSubSlice[T comparable](slice, subslice []T) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -111,10 +152,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Chunk">Chunk</span>
|
### <span id="Chunk">Chunk</span>
|
||||||
|
|
||||||
<p>Creates an slice of elements split into groups the length of `size`.</p>
|
<p>Creates an slice of elements split into groups the length of `size`.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -122,6 +161,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Chunk[T any](slice []T, size int) [][]T
|
func Chunk[T any](slice []T, size int) [][]T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -137,9 +177,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Compact">Compact</span>
|
### <span id="Compact">Compact</span>
|
||||||
|
|
||||||
<p>Creates an slice with all falsey values removed. The values false, nil, 0, and "" are falsey.</p>
|
<p>Creates an slice with all falsey values removed. The values false, nil, 0, and "" are falsey.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -147,6 +186,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Compact[T any](slice []T) []T
|
func Compact[T any](slice []T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -161,8 +201,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="Concat">Concat</span>
|
### <span id="Concat">Concat</span>
|
||||||
|
|
||||||
<p>Creates a new slice concatenating slice with any additional slices and/or values.</p>
|
<p>Creates a new slice concatenating slice with any additional slices and/or values.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -170,6 +210,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Concat[T any](slice []T, values ...[]T) []T
|
func Concat[T any](slice []T, values ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -187,9 +228,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Count">Count</span>
|
### <span id="Count">Count</span>
|
||||||
|
|
||||||
<p>Count iterates over elements of slice, returns a count of all matched elements.</p>
|
<p>Count iterates over elements of slice, returns a count of all matched elements.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -197,6 +237,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Count[T any](slice []T, predicate func(index int, t T) bool) int
|
func Count[T any](slice []T, predicate func(index int, t T) bool) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -216,10 +257,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Difference">Difference</span>
|
### <span id="Difference">Difference</span>
|
||||||
|
|
||||||
<p>Creates an slice of whose element not included in the other given slice.</p>
|
<p>Creates an slice of whose element not included in the other given slice.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -227,6 +266,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Difference[T comparable](slice, comparedSlice []T) []T
|
func Difference[T comparable](slice, comparedSlice []T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -244,10 +284,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DifferenceBy">DifferenceBy</span>
|
### <span id="DifferenceBy">DifferenceBy</span>
|
||||||
|
|
||||||
<p>DifferenceBy accepts iteratee func which is invoked for each element of slice and values to generate the criterion by which they're compared.</p>
|
<p>DifferenceBy accepts iteratee func which is invoked for each element of slice and values to generate the criterion by which they're compared.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -255,6 +293,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T
|
func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -275,8 +314,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="DifferenceWith">DifferenceWith</span>
|
### <span id="DifferenceWith">DifferenceWith</span>
|
||||||
|
|
||||||
<p>DifferenceWith accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice.</p>
|
<p>DifferenceWith accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -284,6 +323,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T
|
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -305,6 +345,7 @@ func main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### <span id="DeleteAt">DeleteAt</span>
|
### <span id="DeleteAt">DeleteAt</span>
|
||||||
|
|
||||||
<p>Delete the element of slice from start index to end index - 1.</p>
|
<p>Delete the element of slice from start index to end index - 1.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -312,6 +353,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func DeleteAt[T any](slice []T, start int, end ...int)
|
func DeleteAt[T any](slice []T, start int, end ...int)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -330,10 +372,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Drop">Drop</span>
|
### <span id="Drop">Drop</span>
|
||||||
|
|
||||||
<p>Creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0.</p>
|
<p>Creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -341,6 +381,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Drop[T any](slice []T, n int) []T
|
func Drop[T any](slice []T, n int) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -361,9 +402,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Equal">Equal</span>
|
### <span id="Equal">Equal</span>
|
||||||
|
|
||||||
<p>Check if two slices are equal: the same length and all elements' order and value are equal.</p>
|
<p>Check if two slices are equal: the same length and all elements' order and value are equal.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -371,6 +411,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Equal[T comparable](slice1, slice2 []T) bool
|
func Equal[T comparable](slice1, slice2 []T) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -392,9 +433,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="EqualWith">EqualWith</span>
|
### <span id="EqualWith">EqualWith</span>
|
||||||
|
|
||||||
<p>Check if two slices are equal with comparator func.</p>
|
<p>Check if two slices are equal with comparator func.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -402,6 +442,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool
|
func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -424,9 +465,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Every">Every</span>
|
### <span id="Every">Every</span>
|
||||||
|
|
||||||
<p>Return true if all of the values in the slice pass the predicate function.</p>
|
<p>Return true if all of the values in the slice pass the predicate function.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -434,6 +474,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Every[T any](slice []T, predicate func(index int, item T) bool) bool
|
func Every[T any](slice []T, predicate func(index int, item T) bool) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -453,10 +494,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Filter">Filter</span>
|
### <span id="Filter">Filter</span>
|
||||||
|
|
||||||
<p>Return all elements which match the function.</p>
|
<p>Return all elements which match the function.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -464,6 +503,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T
|
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -483,9 +523,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Find">Find</span>
|
### <span id="Find">Find</span>
|
||||||
|
|
||||||
<p>Iterates over elements of slice, returning the first one that passes a truth test on function.</p>
|
<p>Iterates over elements of slice, returning the first one that passes a truth test on function.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -493,6 +532,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
|
func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -513,10 +553,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="FindLast">FindLast</span>
|
### <span id="FindLast">FindLast</span>
|
||||||
|
|
||||||
<p>iterates over elements of slice from end to begin, returning the last one that passes a truth test on function.</p>
|
<p>iterates over elements of slice from end to begin, returning the last one that passes a truth test on function.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -524,6 +562,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
|
func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -544,9 +583,33 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="Flatten">Flatten</span>
|
||||||
|
|
||||||
|
<p>Flatten slice with one level.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Flatten(slice any) any
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
arr := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
|
||||||
|
res := slice.Flatten(arr)
|
||||||
|
fmt.Println(res) //{{"a", "b"}, {"c", "d"}}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="FlattenDeep">FlattenDeep</span>
|
### <span id="FlattenDeep">FlattenDeep</span>
|
||||||
|
|
||||||
<p>flattens slice recursive.</p>
|
<p>flattens slice recursive.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -554,6 +617,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func FlattenDeep(slice any) any
|
func FlattenDeep(slice any) any
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -565,15 +629,12 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
arr := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
|
arr := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
|
||||||
res := slice.FlattenDeep(arr)
|
res := slice.FlattenDeep(arr)
|
||||||
fmt.Println(res) //[]string{"a", "b", "c", "d"}
|
fmt.Println(res) //{"a", "b", "c", "d"}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ForEach">ForEach</span>
|
### <span id="ForEach">ForEach</span>
|
||||||
|
|
||||||
<p>Iterates over elements of slice and invokes function for each element.</p>
|
<p>Iterates over elements of slice and invokes function for each element.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -581,6 +642,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ForEach[T any](slice []T, iteratee func(index int, item T))
|
func ForEach[T any](slice []T, iteratee func(index int, item T))
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -599,10 +661,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="GroupBy">GroupBy</span>
|
### <span id="GroupBy">GroupBy</span>
|
||||||
|
|
||||||
<p>Iterates over elements of the slice, each element will be group by criteria, returns two slices.</p>
|
<p>Iterates over elements of the slice, each element will be group by criteria, returns two slices.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -610,6 +670,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T)
|
func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -630,10 +691,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="GroupWith">GroupWith</span>
|
### <span id="GroupWith">GroupWith</span>
|
||||||
|
|
||||||
<p>Return a map composed of keys generated from the results of running each element of slice thru iteratee.</p>
|
<p>Return a map composed of keys generated from the results of running each element of slice thru iteratee.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -641,6 +700,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T
|
func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -659,9 +719,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IntSlice">IntSlice</span>
|
### <span id="IntSlice">IntSlice</span>
|
||||||
|
|
||||||
<p>Convert interface slice to int slice.</p>
|
<p>Convert interface slice to int slice.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -669,6 +728,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func IntSlice(slice any) []int
|
func IntSlice(slice any) []int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -684,10 +744,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="InterfaceSlice">InterfaceSlice</span>
|
### <span id="InterfaceSlice">InterfaceSlice</span>
|
||||||
|
|
||||||
<p>Convert value to interface slice.</p>
|
<p>Convert value to interface slice.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -695,6 +753,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func InterfaceSlice(slice any) []any
|
func InterfaceSlice(slice any) []any
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -710,10 +769,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Intersection">Intersection</span>
|
### <span id="Intersection">Intersection</span>
|
||||||
|
|
||||||
<p>Creates a slice of unique values that included by all slices.</p>
|
<p>Creates a slice of unique values that included by all slices.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -721,6 +778,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Intersection[T comparable](slices ...[]T) []T
|
func Intersection[T comparable](slices ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -738,10 +796,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="InsertAt">InsertAt</span>
|
### <span id="InsertAt">InsertAt</span>
|
||||||
|
|
||||||
<p>insert the element into slice at index.</p>
|
<p>insert the element into slice at index.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -749,6 +805,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func InsertAt[T any](slice []T, index int, value any) []T
|
func InsertAt[T any](slice []T, index int, value any) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -768,10 +825,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IndexOf">IndexOf</span>
|
### <span id="IndexOf">IndexOf</span>
|
||||||
|
|
||||||
<p>Returns the index at which the first occurrence of a value is found in a slice or return -1 if the value cannot be found.</p>
|
<p>Returns the index at which the first occurrence of a value is found in a slice or return -1 if the value cannot be found.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -779,6 +834,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func IndexOf[T comparable](slice []T, value T) int
|
func IndexOf[T comparable](slice []T, value T) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -797,9 +853,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="LastIndexOf">LastIndexOf</span>
|
### <span id="LastIndexOf">LastIndexOf</span>
|
||||||
|
|
||||||
<p>Returns the index at which the last occurrence of a value is found in a slice or return -1 if the value cannot be found.</p>
|
<p>Returns the index at which the last occurrence of a value is found in a slice or return -1 if the value cannot be found.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -807,6 +862,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func LastIndexOf[T comparable](slice []T, value T) int
|
func LastIndexOf[T comparable](slice []T, value T) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -825,10 +881,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Map">Map</span>
|
### <span id="Map">Map</span>
|
||||||
|
|
||||||
<p>Creates an slice of values by running each element in slice thru function.</p>
|
<p>Creates an slice of values by running each element in slice thru function.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -836,6 +890,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U
|
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -854,10 +909,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Reverse">Reverse</span>
|
### <span id="Reverse">Reverse</span>
|
||||||
|
|
||||||
<p>Reverse the elements order in slice.</p>
|
<p>Reverse the elements order in slice.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -865,6 +918,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Reverse[T any](slice []T)
|
func Reverse[T any](slice []T)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -880,9 +934,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Reduce">Reduce</span>
|
### <span id="Reduce">Reduce</span>
|
||||||
|
|
||||||
<p>Reduce slice.</p>
|
<p>Reduce slice.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -890,6 +943,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Reduce[T any](slice []T, iteratee func(index int, item1, item2 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>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -908,10 +962,64 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="Replace">Replace</span>
|
||||||
|
|
||||||
|
<p>Returns a copy of the slice with the first n non-overlapping instances of old replaced by new.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Replace[T comparable](slice []T, old T, new T, n int) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
strs := []string{"a", "b", "a", "c", "d", "a"}
|
||||||
|
|
||||||
|
fmt.Println(slice.Replace(strs, "a", "x", 0)) //{"a", "b", "a", "c", "d", "a"}
|
||||||
|
|
||||||
|
fmt.Println(slice.Replace(strs, "a", "x", 1)) //{"x", "b", "a", "c", "d", "a"}
|
||||||
|
|
||||||
|
fmt.Println(slice.Replace(strs, "a", "x", -1)) //{"x", "b", "x", "c", "d", "x"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ReplaceAll">ReplaceAll</span>
|
||||||
|
|
||||||
|
<p>Returns a copy of the slice with the first n non-overlapping instances of old replaced by new.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReplaceAll[T comparable](slice []T, old T, new T) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
strs := []string{"a", "b", "a", "c", "d", "a"}
|
||||||
|
|
||||||
|
fmt.Println(slice.ReplaceAll(strs, "a", "x")) //{"x", "b", "x", "c", "d", "x"}
|
||||||
|
|
||||||
|
fmt.Println(slice.Replace(strs, "e", "x")) //{"a", "b", "a", "c", "d", "a"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Shuffle">Shuffle</span>
|
### <span id="Shuffle">Shuffle</span>
|
||||||
|
|
||||||
<p>Creates an slice of shuffled values.</p>
|
<p>Creates an slice of shuffled values.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -919,6 +1027,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Shuffle[T any](slice []T) []T
|
func Shuffle[T any](slice []T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -934,9 +1043,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="SortByField">SortByField</span>
|
### <span id="SortByField">SortByField</span>
|
||||||
|
|
||||||
<p>Sort struct slice by field. Slice element should be struct, field type should be int, uint, string, or bool. Default sort type is ascending (asc), if descending order, set sortType to desc</p>
|
<p>Sort struct slice by field. Slice element should be struct, field type should be int, uint, string, or bool. Default sort type is ascending (asc), if descending order, set sortType to desc</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -944,6 +1052,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func SortByField(slice any, field string, sortType ...string) error
|
func SortByField(slice any, field string, sortType ...string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -977,9 +1086,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Some">Some</span>
|
### <span id="Some">Some</span>
|
||||||
|
|
||||||
<p>Return true if any of the values in the list pass the predicate function.</p>
|
<p>Return true if any of the values in the list pass the predicate function.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -987,6 +1095,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Some[T any](slice []T, predicate func(index int, item T) bool) bool
|
func Some[T any](slice []T, predicate func(index int, item T) bool) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1006,9 +1115,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="StringSlice">StringSlice</span>
|
### <span id="StringSlice">StringSlice</span>
|
||||||
|
|
||||||
<p>Convert interface slice to string slice.</p>
|
<p>Convert interface slice to string slice.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -1016,6 +1124,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func StringSlice(slice any) []string
|
func StringSlice(slice any) []string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1031,10 +1140,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="SymmetricDifference">SymmetricDifference</span>
|
### <span id="SymmetricDifference">SymmetricDifference</span>
|
||||||
|
|
||||||
<p>Create a slice whose element is in given slices, but not in both slices.</p>
|
<p>Create a slice whose element is in given slices, but not in both slices.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -1042,6 +1149,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func SymmetricDifference[T comparable](slices ...[]T) []T
|
func SymmetricDifference[T comparable](slices ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1061,9 +1169,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToSlice">ToSlice</span>
|
### <span id="ToSlice">ToSlice</span>
|
||||||
|
|
||||||
<p>Returns a slices of a variable parameter transformation</p>
|
<p>Returns a slices of a variable parameter transformation</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -1071,6 +1178,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToSlice[T any](value ...T) []T
|
func ToSlice[T any](value ...T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1085,9 +1193,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ToSlicePointer">ToSlicePointer</span>
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToSlicePointer">ToSlice</span>
|
|
||||||
<p>Returns a pointer to the slices of a variable parameter transformation</p>
|
<p>Returns a pointer to the slices of a variable parameter transformation</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -1095,6 +1202,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToSlicePointer[T any](value ...T) []*T
|
func ToSlicePointer[T any](value ...T) []*T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1111,8 +1219,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="Unique">Unique</span>
|
### <span id="Unique">Unique</span>
|
||||||
|
|
||||||
<p>Remove duplicate elements in slice.</p>
|
<p>Remove duplicate elements in slice.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -1120,6 +1228,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Unique[T comparable](slice []T) []T
|
func Unique[T comparable](slice []T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1134,9 +1243,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="UniqueBy">UniqueBy</span>
|
### <span id="UniqueBy">UniqueBy</span>
|
||||||
|
|
||||||
<p>Call iteratee func with every item of slice, then remove duplicated.</p>
|
<p>Call iteratee func with every item of slice, then remove duplicated.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -1144,6 +1252,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T
|
func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1160,9 +1269,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Union">Union</span>
|
### <span id="Union">Union</span>
|
||||||
|
|
||||||
<p>Creates a slice of unique values, in order, from all given slices. using == for equality comparisons.</p>
|
<p>Creates a slice of unique values, in order, from all given slices. using == for equality comparisons.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -1170,6 +1278,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Union[T comparable](slices ...[]T) []T
|
func Union[T comparable](slices ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1187,9 +1296,35 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="UnionBy">UnionBy</span>
|
||||||
|
|
||||||
|
<p>UnionBy is like Union, what's more it accepts iteratee which is invoked for each element of each slice.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
testFunc := func(i int) int {
|
||||||
|
return i / 2
|
||||||
|
}
|
||||||
|
result := slice.UnionBy(testFunc, []int{0, 1, 2, 3, 4, 5}, []int{0, 2, 10})
|
||||||
|
fmt.Println(result) //[]int{0, 2, 4, 10}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="UpdateAt">UpdateAt</span>
|
### <span id="UpdateAt">UpdateAt</span>
|
||||||
|
|
||||||
<p>Update the slice element at index. if param index < 0 or index >= len(slice), will return error. </p>
|
<p>Update the slice element at index. if param index < 0 or index >= len(slice), will return error. </p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -1197,6 +1332,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func UpdateAt[T any](slice []T, index int, value T) []T
|
func UpdateAt[T any](slice []T, index int, value T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1213,10 +1349,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Without">Without</span>
|
### <span id="Without">Without</span>
|
||||||
|
|
||||||
<p>Creates a slice excluding all given values. </p>
|
<p>Creates a slice excluding all given values. </p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -1224,6 +1358,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Without[T comparable](slice []T, values ...T) []T
|
func Without[T comparable](slice []T, values ...T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1238,13 +1373,29 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="KeyBy">KeyBy</span>
|
||||||
|
|
||||||
|
<p>Converts a slice to a map based on a callback function.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
res := slice.KeyBy([]string{"a", "ab", "abc"}, func(str string) int {
|
||||||
|
return len(str)
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(res) //map[int]string{1: "a", 2: "ab", 3: "abc"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# Slice
|
# Slice
|
||||||
|
|
||||||
slice 包包含操作切片的方法集合。
|
slice 包包含操作切片的方法集合。
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -7,10 +8,10 @@ slice包包含操作切片的方法集合。
|
|||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go)
|
- [https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 用法:
|
## 用法:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/slice"
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
@@ -20,6 +21,8 @@ import (
|
|||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
|
|
||||||
|
- [AppendIfAbsent](#AppendIfAbsent)
|
||||||
- [Contain](#Contain)
|
- [Contain](#Contain)
|
||||||
- [ContainSubSlice](#ContainSubSlice)
|
- [ContainSubSlice](#ContainSubSlice)
|
||||||
- [Chunk](#Chunk)
|
- [Chunk](#Chunk)
|
||||||
@@ -37,12 +40,13 @@ import (
|
|||||||
- [Filter](#Filter)
|
- [Filter](#Filter)
|
||||||
- [Find](#Find)
|
- [Find](#Find)
|
||||||
- [FindLast](#FindLast)
|
- [FindLast](#FindLast)
|
||||||
|
- [Flatten](#Flatten)
|
||||||
- [FlattenDeep](#FlattenDeep)
|
- [FlattenDeep](#FlattenDeep)
|
||||||
- [ForEach](#ForEach)
|
- [ForEach](#ForEach)
|
||||||
|
|
||||||
- [GroupBy](#GroupBy)
|
- [GroupBy](#GroupBy)
|
||||||
- [GroupWith](#GroupWith)
|
- [GroupWith](#GroupWith)
|
||||||
- [IntSlice](#IntSlice)
|
- [IntSlice](#IntSlice)
|
||||||
|
|
||||||
- [InterfaceSlice](#InterfaceSlice)
|
- [InterfaceSlice](#InterfaceSlice)
|
||||||
- [Intersection](#Intersection)
|
- [Intersection](#Intersection)
|
||||||
- [InsertAt](#InsertAt)
|
- [InsertAt](#InsertAt)
|
||||||
@@ -51,6 +55,8 @@ import (
|
|||||||
- [Map](#Map)
|
- [Map](#Map)
|
||||||
- [Reverse](#Reverse)
|
- [Reverse](#Reverse)
|
||||||
- [Reduce](#Reduce)
|
- [Reduce](#Reduce)
|
||||||
|
- [Replace](#Replace)
|
||||||
|
- [ReplaceAll](#ReplaceAll)
|
||||||
- [Shuffle](#Shuffle)
|
- [Shuffle](#Shuffle)
|
||||||
- [SortByField](#SortByField)
|
- [SortByField](#SortByField)
|
||||||
- [Some](#Some)
|
- [Some](#Some)
|
||||||
@@ -61,14 +67,45 @@ import (
|
|||||||
- [Unique](#Unique)
|
- [Unique](#Unique)
|
||||||
- [UniqueBy](#UniqueBy)
|
- [UniqueBy](#UniqueBy)
|
||||||
- [Union](#Union)
|
- [Union](#Union)
|
||||||
|
- [UnionBy](#UnionBy)
|
||||||
- [UpdateAt](#UpdateAt)
|
- [UpdateAt](#UpdateAt)
|
||||||
- [Without](#Without)
|
- [Without](#Without)
|
||||||
|
- [KeyBy](#KeyBy)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
|
### <span id="AppendIfAbsent">AppendIfAbsent</span>
|
||||||
|
|
||||||
|
<p>当前切片中不包含值时,将该值追加到切片中</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AppendIfAbsent[T comparable](slice []T, value T) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
strs := []string{"a", "b"}
|
||||||
|
res1 := slice.AppendIfAbsent(strs, "a")
|
||||||
|
fmt.Println(res1) //[]string{"a", "b"}
|
||||||
|
|
||||||
|
res2 := slice.AppendIfAbsent(strs, "cannot")
|
||||||
|
fmt.Println(res2"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Contain">Contain</span>
|
### <span id="Contain">Contain</span>
|
||||||
|
|
||||||
<p>判断slice是否包含value</p>
|
<p>判断slice是否包含value</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -76,6 +113,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func Contain[T comparable](slice []T, value T) bool
|
func Contain[T comparable](slice []T, value T) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -90,8 +128,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="ContainSubSlice">ContainSubSlice</span>
|
### <span id="ContainSubSlice">ContainSubSlice</span>
|
||||||
|
|
||||||
<p>判断slice是否包含subslice</p>
|
<p>判断slice是否包含subslice</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -99,6 +137,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ContainSubSlice[T comparable](slice, subslice []T) bool
|
func ContainSubSlice[T comparable](slice, subslice []T) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -113,10 +152,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Chunk">Chunk</span>
|
### <span id="Chunk">Chunk</span>
|
||||||
|
|
||||||
<p>按照size参数均分slice</p>
|
<p>按照size参数均分slice</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -124,6 +161,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Chunk[T any](slice []T, size int) [][]T
|
func Chunk[T any](slice []T, size int) [][]T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -139,9 +177,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Compact">Compact</span>
|
### <span id="Compact">Compact</span>
|
||||||
|
|
||||||
<p>去除slice中的假值(false values are false, nil, 0, "")</p>
|
<p>去除slice中的假值(false values are false, nil, 0, "")</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -149,6 +186,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Compact[T any](slice []T) []T
|
func Compact[T any](slice []T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -163,8 +201,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="Concat">Concat</span>
|
### <span id="Concat">Concat</span>
|
||||||
|
|
||||||
<p>连接values到slice中,values类型可以是切片或多个值</p>
|
<p>连接values到slice中,values类型可以是切片或多个值</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -172,6 +210,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Concat[T any](slice []T, values ...[]T) []T
|
func Concat[T any](slice []T, values ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -189,9 +228,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Count">Count</span>
|
### <span id="Count">Count</span>
|
||||||
|
|
||||||
<p>遍历切片,对每个元素执行函数function. 返回符合函数返回值为true的元素的个数</p>
|
<p>遍历切片,对每个元素执行函数function. 返回符合函数返回值为true的元素的个数</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -199,6 +237,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Count[T any](slice []T, predicate func(index int, t T) bool) int
|
func Count[T any](slice []T, predicate func(index int, t T) bool) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -218,10 +257,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Difference">Difference</span>
|
### <span id="Difference">Difference</span>
|
||||||
|
|
||||||
<p>创建一个切片,其元素不包含在另一个给定切片中</p>
|
<p>创建一个切片,其元素不包含在另一个给定切片中</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -229,6 +266,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Difference[T comparable](slice, comparedSlice []T) []T
|
func Difference[T comparable](slice, comparedSlice []T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -246,10 +284,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DifferenceBy">DifferenceBy</span>
|
### <span id="DifferenceBy">DifferenceBy</span>
|
||||||
|
|
||||||
<p>在slice和comparedSlice中的每个元素调用iteratee函数,并比较它们的返回值,如果不想等返回在slice中对应的值</p>
|
<p>在slice和comparedSlice中的每个元素调用iteratee函数,并比较它们的返回值,如果不想等返回在slice中对应的值</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -257,6 +293,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T
|
func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -277,9 +314,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DifferenceWith">DifferenceWith</span>
|
### <span id="DifferenceWith">DifferenceWith</span>
|
||||||
|
|
||||||
<p>DifferenceWith 接受比较器,该比较器被调用以将切片的元素与值进行比较。 结果值的顺序和引用由第一个切片确定</p>
|
<p>DifferenceWith 接受比较器,该比较器被调用以将切片的元素与值进行比较。 结果值的顺序和引用由第一个切片确定</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -287,6 +323,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T
|
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -307,8 +344,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="DeleteAt">DeleteAt</span>
|
### <span id="DeleteAt">DeleteAt</span>
|
||||||
|
|
||||||
<p>删除切片中从开始索引到结束索引-1的元素</p>
|
<p>删除切片中从开始索引到结束索引-1的元素</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -316,6 +353,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func DeleteAt[T any](slice []T, start int, end ...int)
|
func DeleteAt[T any](slice []T, start int, end ...int)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -334,10 +372,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Drop">Drop</span>
|
### <span id="Drop">Drop</span>
|
||||||
|
|
||||||
<p>创建一个切片,当 n > 0 时从开头删除 n 个元素,或者当 n < 0 时从结尾删除 n 个元素</p>
|
<p>创建一个切片,当 n > 0 时从开头删除 n 个元素,或者当 n < 0 时从结尾删除 n 个元素</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -345,6 +381,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Drop[T any](slice []T, n int) []T
|
func Drop[T any](slice []T, n int) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -365,10 +402,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Every">Every</span>
|
### <span id="Every">Every</span>
|
||||||
|
|
||||||
<p>如果切片中的所有值都通过谓词函数,则返回true。 函数签名应该是func(index int, value any) bool</p>
|
<p>如果切片中的所有值都通过谓词函数,则返回true。 函数签名应该是func(index int, value any) bool</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -376,6 +411,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Every[T any](slice []T, predicate func(index int, item T) bool) bool
|
func Every[T any](slice []T, predicate func(index int, item T) bool) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -395,10 +431,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Equal">Equal</span>
|
### <span id="Equal">Equal</span>
|
||||||
|
|
||||||
<p>检查两个切片是否相等,相等条件:切片长度相同,元素顺序和值都相同</p>
|
<p>检查两个切片是否相等,相等条件:切片长度相同,元素顺序和值都相同</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -406,6 +440,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Equal[T comparable](slice1, slice2 []T) bool
|
func Equal[T comparable](slice1, slice2 []T) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -427,9 +462,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="EqualWith">EqualWith</span>
|
### <span id="EqualWith">EqualWith</span>
|
||||||
|
|
||||||
<p>检查两个切片是否相等,相等条件:对两个切片的元素调用比较函数comparator,返回true</p>
|
<p>检查两个切片是否相等,相等条件:对两个切片的元素调用比较函数comparator,返回true</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -437,6 +471,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool
|
func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -459,9 +494,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Filter">Filter</span>
|
### <span id="Filter">Filter</span>
|
||||||
|
|
||||||
<p>返回切片中通过predicate函数真值测试的所有元素</p>
|
<p>返回切片中通过predicate函数真值测试的所有元素</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -469,6 +503,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T
|
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -488,9 +523,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Find">Find</span>
|
### <span id="Find">Find</span>
|
||||||
|
|
||||||
<p>遍历切片的元素,返回第一个通过predicate函数真值测试的元素</p>
|
<p>遍历切片的元素,返回第一个通过predicate函数真值测试的元素</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -498,6 +532,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
|
func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -518,10 +553,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="FindLast">FindLast</span>
|
### <span id="FindLast">FindLast</span>
|
||||||
|
|
||||||
<p>从头到尾遍历slice的元素,返回最后一个通过predicate函数真值测试的元素。</p>
|
<p>从头到尾遍历slice的元素,返回最后一个通过predicate函数真值测试的元素。</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -529,6 +562,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
|
func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -549,9 +583,33 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="Flatten">Flatten</span>
|
||||||
|
|
||||||
|
<p>将切片压平一层</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Flatten(slice any) any
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
arr := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
|
||||||
|
res := slice.Flatten(arr)
|
||||||
|
fmt.Println(res) //{{"a", "b"}, {"c", "d"}}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="FlattenDeep">FlattenDeep</span>
|
### <span id="FlattenDeep">FlattenDeep</span>
|
||||||
|
|
||||||
<p>flattens slice recursive.</p>
|
<p>flattens slice recursive.</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -559,6 +617,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func FlattenDeep(slice any) any
|
func FlattenDeep(slice any) any
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -574,11 +633,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ForEach">ForEach</span>
|
### <span id="ForEach">ForEach</span>
|
||||||
|
|
||||||
<p>遍历切片的元素并为每个元素调用iteratee函数</p>
|
<p>遍历切片的元素并为每个元素调用iteratee函数</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -586,6 +642,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ForEach[T any](slice []T, iteratee func(index int, item T))
|
func ForEach[T any](slice []T, iteratee func(index int, item T))
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -604,10 +661,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="GroupBy">GroupBy</span>
|
### <span id="GroupBy">GroupBy</span>
|
||||||
|
|
||||||
<p>迭代切片的元素,每个元素将按条件分组,返回两个切片</p>
|
<p>迭代切片的元素,每个元素将按条件分组,返回两个切片</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -615,6 +670,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T)
|
func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -635,9 +691,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="GroupWith">GroupWith</span>
|
### <span id="GroupWith">GroupWith</span>
|
||||||
|
|
||||||
<p>创建一个map,key是iteratee遍历slice中的每个元素返回的结果。 分组值的顺序是由他们出现在slice中的顺序确定的。每个键对应的值负责生成key的元素组成的数组。iteratee调用1个参数: (value)</p>
|
<p>创建一个map,key是iteratee遍历slice中的每个元素返回的结果。 分组值的顺序是由他们出现在slice中的顺序确定的。每个键对应的值负责生成key的元素组成的数组。iteratee调用1个参数: (value)</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -645,6 +700,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T
|
func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -663,8 +719,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="IntSlice">IntSlice</span>
|
### <span id="IntSlice">IntSlice</span>
|
||||||
|
|
||||||
<p>将接口切片转换为int切片</p>
|
<p>将接口切片转换为int切片</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -672,6 +728,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func IntSlice(slice any) []int
|
func IntSlice(slice any) []int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -687,10 +744,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="InterfaceSlice">InterfaceSlice</span>
|
### <span id="InterfaceSlice">InterfaceSlice</span>
|
||||||
|
|
||||||
<p>将值转换为接口切片</p>
|
<p>将值转换为接口切片</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -698,6 +753,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func InterfaceSlice(slice any) []any
|
func InterfaceSlice(slice any) []any
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -713,10 +769,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Intersection">Intersection</span>
|
### <span id="Intersection">Intersection</span>
|
||||||
|
|
||||||
<p>多个切片的交集</p>
|
<p>多个切片的交集</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -724,6 +778,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Intersection[T comparable](slices ...[]T) []T
|
func Intersection[T comparable](slices ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -741,10 +796,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="InsertAt">InsertAt</span>
|
### <span id="InsertAt">InsertAt</span>
|
||||||
|
|
||||||
<p>将元素插入到索引处的切片中</p>
|
<p>将元素插入到索引处的切片中</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -752,6 +805,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func InsertAt[T any](slice []T, index int, value any) []T
|
func InsertAt[T any](slice []T, index int, value any) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -771,10 +825,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IndexOf">IndexOf</span>
|
### <span id="IndexOf">IndexOf</span>
|
||||||
|
|
||||||
<p>返回在切片中找到值的第一个匹配项的索引,如果找不到值,则返回-1</p>
|
<p>返回在切片中找到值的第一个匹配项的索引,如果找不到值,则返回-1</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -782,6 +834,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func IndexOf[T comparable](slice []T, value T) int
|
func IndexOf[T comparable](slice []T, value T) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -800,9 +853,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="LastIndexOf">LastIndexOf</span>
|
### <span id="LastIndexOf">LastIndexOf</span>
|
||||||
|
|
||||||
<p>返回在切片中找到最后一个值的索引,如果找不到该值,则返回-1</p>
|
<p>返回在切片中找到最后一个值的索引,如果找不到该值,则返回-1</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -810,6 +862,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func LastIndexOf[T comparable](slice []T, value T) int
|
func LastIndexOf[T comparable](slice []T, value T) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -828,9 +881,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Map">Map</span>
|
### <span id="Map">Map</span>
|
||||||
|
|
||||||
<p>通过运行函数slice中的每个元素来创建一个新切片</p>
|
<p>通过运行函数slice中的每个元素来创建一个新切片</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -838,6 +890,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U
|
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -856,10 +909,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Reverse">Reverse</span>
|
### <span id="Reverse">Reverse</span>
|
||||||
|
|
||||||
<p>反转切片中的元素顺序</p>
|
<p>反转切片中的元素顺序</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -867,6 +918,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Reverse[T any](slice []T)
|
func Reverse[T any](slice []T)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -882,9 +934,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Reduce">Reduce</span>
|
### <span id="Reduce">Reduce</span>
|
||||||
|
|
||||||
<p>将切片中的元素依次运行iteratee函数,返回运行结果</p>
|
<p>将切片中的元素依次运行iteratee函数,返回运行结果</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -892,6 +943,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T
|
func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -910,10 +962,64 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="Replace">Replace</span>
|
||||||
|
|
||||||
|
<p>返回切片的副本,其中前n个不重叠的old替换为new</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Replace[T comparable](slice []T, old T, new T, n int) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
strs := []string{"a", "b", "a", "c", "d", "a"}
|
||||||
|
|
||||||
|
fmt.Println(slice.Replace(strs, "a", "x", 0)) //{"a", "b", "a", "c", "d", "a"}
|
||||||
|
|
||||||
|
fmt.Println(slice.Replace(strs, "a", "x", 1)) //{"x", "b", "a", "c", "d", "a"}
|
||||||
|
|
||||||
|
fmt.Println(slice.Replace(strs, "a", "x", -1)) //{"x", "b", "x", "c", "d", "x"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ReplaceAll">ReplaceAll</span>
|
||||||
|
|
||||||
|
<p>返回切片的副本,将其中old全部替换为new</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReplaceAll[T comparable](slice []T, old T, new T) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
strs := []string{"a", "b", "a", "c", "d", "a"}
|
||||||
|
|
||||||
|
fmt.Println(slice.ReplaceAll(strs, "a", "x")) //{"x", "b", "x", "c", "d", "x"}
|
||||||
|
|
||||||
|
fmt.Println(slice.Replace(strs, "e", "x")) //{"a", "b", "a", "c", "d", "a"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Shuffle">Shuffle</span>
|
### <span id="Shuffle">Shuffle</span>
|
||||||
|
|
||||||
<p>随机打乱切片中的元素顺序</p>
|
<p>随机打乱切片中的元素顺序</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -921,6 +1027,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Shuffle[T any](slice []T) []T
|
func Shuffle[T any](slice []T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -936,9 +1043,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="SortByField">SortByField</span>
|
### <span id="SortByField">SortByField</span>
|
||||||
|
|
||||||
<p>按字段对结构切片进行排序。slice元素应为struct,字段类型应为int、uint、string或bool。 默认排序类型是升序(asc),如果是降序,设置 sortType 为 desc</p>
|
<p>按字段对结构切片进行排序。slice元素应为struct,字段类型应为int、uint、string或bool。 默认排序类型是升序(asc),如果是降序,设置 sortType 为 desc</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -946,6 +1052,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func SortByField(slice any, field string, sortType ...string) error
|
func SortByField(slice any, field string, sortType ...string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -979,9 +1086,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Some">Some</span>
|
### <span id="Some">Some</span>
|
||||||
|
|
||||||
<p>如果列表中的任何值通过谓词函数,则返回true</p>
|
<p>如果列表中的任何值通过谓词函数,则返回true</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -989,6 +1095,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Some[T any](slice []T, predicate func(index int, item T) bool) bool
|
func Some[T any](slice []T, predicate func(index int, item T) bool) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1008,9 +1115,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="StringSlice">StringSlice</span>
|
### <span id="StringSlice">StringSlice</span>
|
||||||
|
|
||||||
<p>将接口切片转换为字符串切片</p>
|
<p>将接口切片转换为字符串切片</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -1018,6 +1124,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func StringSlice(slice any) []string
|
func StringSlice(slice any) []string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1033,10 +1140,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="SymmetricDifference">SymmetricDifference</span>
|
### <span id="SymmetricDifference">SymmetricDifference</span>
|
||||||
|
|
||||||
<p>返回一个切片,其中的元素存在于参数切片中,但不同时存储在于参数切片中(交集取反)</p>
|
<p>返回一个切片,其中的元素存在于参数切片中,但不同时存储在于参数切片中(交集取反)</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -1044,6 +1149,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func SymmetricDifference[T comparable](slices ...[]T) []T
|
func SymmetricDifference[T comparable](slices ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1063,8 +1169,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToSlice">ToSlice</span>
|
### <span id="ToSlice">ToSlice</span>
|
||||||
|
|
||||||
<p>将可变参数转为切片</p>
|
<p>将可变参数转为切片</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -1072,6 +1178,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToSlice[T any](value ...T) []T
|
func ToSlice[T any](value ...T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1086,9 +1193,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ToSlicePointer">ToSlicePointer</span>
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToSlicePointer">ToSlice</span>
|
|
||||||
<p>将可变参数转为指针切片</p>
|
<p>将可变参数转为指针切片</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -1096,6 +1202,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToSlicePointer[T any](value ...T) []*T
|
func ToSlicePointer[T any](value ...T) []*T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1112,9 +1219,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Unique">Unique</span>
|
### <span id="Unique">Unique</span>
|
||||||
|
|
||||||
<p>删除切片中的重复元素</p>
|
<p>删除切片中的重复元素</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -1122,6 +1228,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Unique[T comparable](slice []T) []T
|
func Unique[T comparable](slice []T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1136,9 +1243,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="UniqueBy">UniqueBy</span>
|
### <span id="UniqueBy">UniqueBy</span>
|
||||||
|
|
||||||
<p>对切片的每个元素调用iteratee函数,然后删除重复元素</p>
|
<p>对切片的每个元素调用iteratee函数,然后删除重复元素</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -1146,6 +1252,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T
|
func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1162,16 +1269,16 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Union">Union</span>
|
### <span id="Union">Union</span>
|
||||||
<p>从所有给定的切片按顺序创建一个唯一值切片,使用==进行相等比较</p>
|
|
||||||
|
<p>合并多个切片.</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Union[T comparable](slices ...[]T) []T
|
func Union[T comparable](slices ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1189,9 +1296,35 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="UnionBy">UnionBy</span>
|
||||||
|
|
||||||
|
<p>对切片的每个元素调用函数后,合并多个切片</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
testFunc := func(i int) int {
|
||||||
|
return i / 2
|
||||||
|
}
|
||||||
|
result := slice.UnionBy(testFunc, []int{0, 1, 2, 3, 4, 5}, []int{0, 2, 10})
|
||||||
|
fmt.Println(result) //[]int{0, 2, 4, 10}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="UpdateAt">UpdateAt</span>
|
### <span id="UpdateAt">UpdateAt</span>
|
||||||
|
|
||||||
<p>更新索引处的切片元素。 如果index < 0或 index >= len(slice),将返回错误</p>
|
<p>更新索引处的切片元素。 如果index < 0或 index >= len(slice),将返回错误</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -1199,6 +1332,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func UpdateAt[T any](slice []T, index int, value T) []T
|
func UpdateAt[T any](slice []T, index int, value T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1215,10 +1349,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Without">Without</span>
|
### <span id="Without">Without</span>
|
||||||
|
|
||||||
<p>创建一个不包括所有给定值的切片</p>
|
<p>创建一个不包括所有给定值的切片</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -1226,6 +1358,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Without[T comparable](slice []T, values ...T) []T
|
func Without[T comparable](slice []T, values ...T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1241,12 +1374,29 @@ func main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="KeyBy">KeyBy</span>
|
||||||
|
|
||||||
|
<p>将切片每个元素调用函数后转为map</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
res := slice.KeyBy([]string{"a", "ab", "abc"}, func(str string) int {
|
||||||
|
return len(str)
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(res) //map[int]string{1: "a", 2: "ab", 3: "abc"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import (
|
|||||||
- [UpperFirst](#UpperFirst)
|
- [UpperFirst](#UpperFirst)
|
||||||
- [PadEnd](#PadEnd)
|
- [PadEnd](#PadEnd)
|
||||||
- [PadStart](#PadStart)
|
- [PadStart](#PadStart)
|
||||||
- [ReverseStr](#ReverseStr)
|
- [Reverse](#Reverse)
|
||||||
- [SnakeCase](#SnakeCase)
|
- [SnakeCase](#SnakeCase)
|
||||||
- [SplitEx](#SplitEx)
|
- [SplitEx](#SplitEx)
|
||||||
- [Wrap](#Wrap)
|
- [Wrap](#Wrap)
|
||||||
@@ -430,13 +430,13 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ReverseStr">ReverseStr</span>
|
### <span id="Reverse">Reverse</span>
|
||||||
<p>Return string whose char order is reversed to the given string.</p>
|
<p>Return string whose char order is reversed to the given string.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ReverseStr(s string) string
|
func Reverse(s string) string
|
||||||
```
|
```
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import (
|
|||||||
- [UpperFirst](#UpperFirst)
|
- [UpperFirst](#UpperFirst)
|
||||||
- [PadEnd](#PadEnd)
|
- [PadEnd](#PadEnd)
|
||||||
- [PadStart](#PadStart)
|
- [PadStart](#PadStart)
|
||||||
- [ReverseStr](#ReverseStr)
|
- [Reverse](#Reverse)
|
||||||
- [SnakeCase](#SnakeCase)
|
- [SnakeCase](#SnakeCase)
|
||||||
- [SplitEx](#SplitEx)
|
- [SplitEx](#SplitEx)
|
||||||
- [Wrap](#Wrap)
|
- [Wrap](#Wrap)
|
||||||
@@ -431,13 +431,13 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ReverseStr">ReverseStr</span>
|
### <span id="Reverse">Reverse</span>
|
||||||
<p>返回字符顺序与给定字符串相反的字符串</p>
|
<p>返回字符顺序与给定字符串相反的字符串</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ReverseStr(s string) string
|
func Reverse(s string) string
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import (
|
|||||||
- [RemoveOsEnv](#RemoveOsEnv)
|
- [RemoveOsEnv](#RemoveOsEnv)
|
||||||
- [CompareOsEnv](#CompareOsEnv)
|
- [CompareOsEnv](#CompareOsEnv)
|
||||||
- [ExecCommand](#ExecCommand)
|
- [ExecCommand](#ExecCommand)
|
||||||
|
- [GetOsBits](#GetOsBits)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -210,7 +211,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
### <span id="ExecCommand">CompareOsEnv</span>
|
### <span id="ExecCommand">CompareOsEnv</span>
|
||||||
<p>use shell /bin/bash -c(linux) or cmd (windows) to execute command.</p>
|
<p>Use shell /bin/bash -c(linux) or cmd (windows) to execute command.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
@@ -236,7 +237,27 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="GetOsBits">GetOsBits</span>
|
||||||
|
<p>Get current os bits, 32bit or 64bit. return 32 or 64</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GetOsBits() int
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/system"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
osBit := system.GetOsBits()
|
||||||
|
fmt.Println(osBit)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ import (
|
|||||||
- [GetOsEnv](#GetOsEnv)
|
- [GetOsEnv](#GetOsEnv)
|
||||||
- [SetOsEnv](#SetOsEnv)
|
- [SetOsEnv](#SetOsEnv)
|
||||||
- [RemoveOsEnv](#RemoveOsEnv)
|
- [RemoveOsEnv](#RemoveOsEnv)
|
||||||
|
|
||||||
- [CompareOsEnv](#CompareOsEnv)
|
- [CompareOsEnv](#CompareOsEnv)
|
||||||
- [ExecCommand](#ExecCommand)
|
- [ExecCommand](#ExecCommand)
|
||||||
|
- [GetOsBits](#GetOsBits)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -236,6 +238,30 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="GetOsBits">GetOsBits</span>
|
||||||
|
<p>获取当前操作系统位数,返回32或64</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GetOsBits() int
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/system"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
osBit := system.GetOsBits()
|
||||||
|
fmt.Println(osBit)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import (
|
|||||||
- [IsStrongPassword](#IsStrongPassword)
|
- [IsStrongPassword](#IsStrongPassword)
|
||||||
- [IsUrl](#IsUrl)
|
- [IsUrl](#IsUrl)
|
||||||
- [IsWeakPassword](#IsWeakPassword)
|
- [IsWeakPassword](#IsWeakPassword)
|
||||||
|
- [IsZeroValue](#IsZeroValue)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -765,7 +766,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
### <span id="IsWeakPassword">IsWeakPassword</span>
|
### <span id="IsWeakPassword">IsWeakPassword</span>
|
||||||
<p>Check if the string is weak password(only letter or only number or letter + number)
|
<p>Checks if the string is weak password(only letter or only number or letter + number)
|
||||||
.</p>
|
.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -792,6 +793,36 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="IsZeroValue">IsZeroValue</span>
|
||||||
|
<p>Checks if passed value is a zero value.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsZeroValue(value any) bool
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(validator.IsZeroValue(nil)) //true
|
||||||
|
fmt.Println(validator.IsZeroValue(0)) //true
|
||||||
|
fmt.Println(validator.IsZeroValue("")) //true
|
||||||
|
fmt.Println(validator.IsZeroValue([]int)) //true
|
||||||
|
fmt.Println(validator.IsZeroValue(interface{})) //true
|
||||||
|
|
||||||
|
fmt.Println(validator.IsZeroValue("0")) //false
|
||||||
|
fmt.Println(validator.IsZeroValue("nil")) //false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import (
|
|||||||
- [IsStrongPassword](#IsStrongPassword)
|
- [IsStrongPassword](#IsStrongPassword)
|
||||||
- [IsUrl](#IsUrl)
|
- [IsUrl](#IsUrl)
|
||||||
- [IsWeakPassword](#IsWeakPassword)
|
- [IsWeakPassword](#IsWeakPassword)
|
||||||
|
- [IsZeroValue](#IsZeroValue)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -792,8 +793,31 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="IsZeroValue">IsZeroValue</span>
|
||||||
|
<p>判断传入的参数值是否为零值</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsZeroValue(value any) bool
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(validator.IsZeroValue(nil)) //true
|
||||||
|
fmt.Println(validator.IsZeroValue(0)) //true
|
||||||
|
fmt.Println(validator.IsZeroValue("")) //true
|
||||||
|
fmt.Println(validator.IsZeroValue([]int)) //true
|
||||||
|
fmt.Println(validator.IsZeroValue(interface{})) //true
|
||||||
|
|
||||||
|
fmt.Println(validator.IsZeroValue("0")) //false
|
||||||
|
fmt.Println(validator.IsZeroValue("nil")) //false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ func ReadFileByLine(path string) ([]string, error) {
|
|||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
res := make([]string, 0)
|
result := make([]string, 0)
|
||||||
buf := bufio.NewReader(f)
|
buf := bufio.NewReader(f)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@@ -128,10 +128,10 @@ func ReadFileByLine(path string) ([]string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
res = append(res, l)
|
result = append(result, l)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListFileNames return all file names in the path
|
// ListFileNames return all file names in the path
|
||||||
@@ -150,14 +150,14 @@ func ListFileNames(path string) ([]string, error) {
|
|||||||
return []string{}, nil
|
return []string{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
res := []string{}
|
result := []string{}
|
||||||
for i := 0; i < sz; i++ {
|
for i := 0; i < sz; i++ {
|
||||||
if !fs[i].IsDir() {
|
if !fs[i].IsDir() {
|
||||||
res = append(res, fs[i].Name())
|
result = append(result, fs[i].Name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zip create zip file, fpath could be a single file or a directory
|
// Zip create zip file, fpath could be a single file or a directory
|
||||||
|
|||||||
@@ -27,16 +27,16 @@ func After(n int, fn any) func(args ...any) []reflect.Value {
|
|||||||
func Before(n int, fn any) func(args ...any) []reflect.Value {
|
func Before(n int, fn any) func(args ...any) []reflect.Value {
|
||||||
// Catch programming error while constructing the closure
|
// Catch programming error while constructing the closure
|
||||||
mustBeFunction(fn)
|
mustBeFunction(fn)
|
||||||
var res []reflect.Value
|
var result []reflect.Value
|
||||||
return func(args ...any) []reflect.Value {
|
return func(args ...any) []reflect.Value {
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
res = unsafeInvokeFunc(fn, args...)
|
result = unsafeInvokeFunc(fn, args...)
|
||||||
}
|
}
|
||||||
if n <= 0 {
|
if n <= 0 {
|
||||||
fn = nil
|
fn = nil
|
||||||
}
|
}
|
||||||
n--
|
n--
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,3 +113,15 @@ func Schedule(d time.Duration, fn any, args ...any) chan bool {
|
|||||||
|
|
||||||
return quit
|
return quit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pipeline takes a list of functions and returns a function whose param will be passed into
|
||||||
|
// the functions one by one.
|
||||||
|
func Pipeline[T any](funcs ...func(T) T) func(T) T {
|
||||||
|
return func(arg T) (result T) {
|
||||||
|
result = arg
|
||||||
|
for _, fn := range funcs {
|
||||||
|
result = fn(result)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ func TestDebounced(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSchedule(t *testing.T) {
|
func TestSchedule(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestSchedule")
|
// assert := internal.NewAssert(t, "TestSchedule")
|
||||||
|
|
||||||
var res []string
|
var res []string
|
||||||
appendStr := func(s string) {
|
appendStr := func(s string) {
|
||||||
@@ -127,6 +127,28 @@ func TestSchedule(t *testing.T) {
|
|||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
close(stop)
|
close(stop)
|
||||||
|
|
||||||
expected := []string{"*", "*", "*", "*", "*"}
|
t.Log(res)
|
||||||
assert.Equal(expected, res)
|
|
||||||
|
// todo: in github action, for now, this test is not working sometimes
|
||||||
|
// res maybe [* * * * *] or [* * * * * *]
|
||||||
|
// expected := []string{"*", "*", "*", "*", "*"}
|
||||||
|
// assert.Equal(expected, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPipeline(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestPipeline")
|
||||||
|
|
||||||
|
addOne := func(x int) int {
|
||||||
|
return x + 1
|
||||||
|
}
|
||||||
|
double := func(x int) int {
|
||||||
|
return 2 * x
|
||||||
|
}
|
||||||
|
square := func(x int) int {
|
||||||
|
return x * x
|
||||||
|
}
|
||||||
|
|
||||||
|
f := Pipeline(addOne, double, square)
|
||||||
|
|
||||||
|
assert.Equal(36, f(2))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,10 @@ func TestWatcher(t *testing.T) {
|
|||||||
assert.Equal(int64(0), w.stopTime)
|
assert.Equal(int64(0), w.stopTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
func longRunningTask() {
|
func longRunningTask() []int64 {
|
||||||
var slice []int64
|
var data []int64
|
||||||
for i := 0; i < 10000000; i++ {
|
for i := 0; i < 10000000; i++ {
|
||||||
slice = append(slice, int64(i))
|
data = append(data, int64(i))
|
||||||
}
|
}
|
||||||
|
return data
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,5 +14,5 @@ type Comparator interface {
|
|||||||
|
|
||||||
// Number contains all types of number and uintptr, used for generics constraint
|
// Number contains all types of number and uintptr, used for generics constraint
|
||||||
type Number interface {
|
type Number interface {
|
||||||
int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | uintptr | float32 | float64
|
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,12 @@ import "reflect"
|
|||||||
|
|
||||||
// Keys returns a slice of the map's keys
|
// Keys returns a slice of the map's keys
|
||||||
func Keys[K comparable, V any](m map[K]V) []K {
|
func Keys[K comparable, V any](m map[K]V) []K {
|
||||||
keys := make([]K, 0, len(m))
|
keys := make([]K, len(m))
|
||||||
|
|
||||||
|
var i int
|
||||||
for k := range m {
|
for k := range m {
|
||||||
keys = append(keys, k)
|
keys[i] = k
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
return keys
|
return keys
|
||||||
@@ -19,10 +21,12 @@ func Keys[K comparable, V any](m map[K]V) []K {
|
|||||||
|
|
||||||
// Values returns a slice of the map's values
|
// Values returns a slice of the map's values
|
||||||
func Values[K comparable, V any](m map[K]V) []V {
|
func Values[K comparable, V any](m map[K]V) []V {
|
||||||
values := make([]V, 0, len(m))
|
values := make([]V, len(m))
|
||||||
|
|
||||||
|
var i int
|
||||||
for _, v := range m {
|
for _, v := range m {
|
||||||
values = append(values, v)
|
values[i] = v
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
return values
|
return values
|
||||||
@@ -30,15 +34,15 @@ func Values[K comparable, V any](m map[K]V) []V {
|
|||||||
|
|
||||||
// Merge maps, next key will overwrite previous key
|
// Merge maps, next key will overwrite previous key
|
||||||
func Merge[K comparable, V any](maps ...map[K]V) map[K]V {
|
func Merge[K comparable, V any](maps ...map[K]V) map[K]V {
|
||||||
res := make(map[K]V, 0)
|
result := make(map[K]V, 0)
|
||||||
|
|
||||||
for _, m := range maps {
|
for _, m := range maps {
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
res[k] = v
|
result[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEach executes iteratee funcation for every key and value pair in map
|
// ForEach executes iteratee funcation for every key and value pair in map
|
||||||
@@ -50,14 +54,14 @@ func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V)) {
|
|||||||
|
|
||||||
// Filter iterates over map, return a new map contains all key and value pairs pass the predicate function
|
// Filter iterates over map, return a new map contains all key and value pairs pass the predicate function
|
||||||
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V {
|
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V {
|
||||||
res := make(map[K]V)
|
result := make(map[K]V)
|
||||||
|
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
if predicate(k, v) {
|
if predicate(k, v) {
|
||||||
res[k] = v
|
result[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intersect iterates over maps, return a new map of key and value pairs in all given maps
|
// Intersect iterates over maps, return a new map of key and value pairs in all given maps
|
||||||
@@ -69,7 +73,7 @@ func Intersect[K comparable, V any](maps ...map[K]V) map[K]V {
|
|||||||
return maps[0]
|
return maps[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
var res map[K]V
|
var result map[K]V
|
||||||
|
|
||||||
reducer := func(m1, m2 map[K]V) map[K]V {
|
reducer := func(m1, m2 map[K]V) map[K]V {
|
||||||
m := make(map[K]V)
|
m := make(map[K]V)
|
||||||
@@ -82,25 +86,35 @@ func Intersect[K comparable, V any](maps ...map[K]V) map[K]V {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reduceMaps := make([]map[K]V, 2, 2)
|
reduceMaps := make([]map[K]V, 2, 2)
|
||||||
res = reducer(maps[0], maps[1])
|
result = reducer(maps[0], maps[1])
|
||||||
|
|
||||||
for i := 2; i < len(maps); i++ {
|
for i := 2; i < len(maps); i++ {
|
||||||
reduceMaps[0] = res
|
reduceMaps[0] = result
|
||||||
reduceMaps[1] = maps[i]
|
reduceMaps[1] = maps[i]
|
||||||
res = reducer(reduceMaps[0], reduceMaps[1])
|
result = reducer(reduceMaps[0], reduceMaps[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Minus creates an map of whose key in mapA but not in mapB
|
// Minus creates an map of whose key in mapA but not in mapB
|
||||||
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V {
|
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V {
|
||||||
res := make(map[K]V)
|
result := make(map[K]V)
|
||||||
|
|
||||||
for k, v := range mapA {
|
for k, v := range mapA {
|
||||||
if _, ok := mapB[k]; !ok {
|
if _, ok := mapB[k]; !ok {
|
||||||
res[k] = v
|
result[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDisjoint two map are disjoint if they have no keys in common
|
||||||
|
func IsDisjoint[K comparable, V any](mapA, mapB map[K]V) bool {
|
||||||
|
for k := range mapA {
|
||||||
|
if _, ok := mapB[k]; ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,3 +148,25 @@ func TestMinus(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(map[string]int{"c": 3}, Minus(m1, m2))
|
assert.Equal(map[string]int{"c": 3}, Minus(m1, m2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsDisjoint(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestMinus")
|
||||||
|
|
||||||
|
m1 := map[string]int{
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
"c": 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
m2 := map[string]int{
|
||||||
|
"d": 22,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(true, IsDisjoint(m1, m2))
|
||||||
|
|
||||||
|
m3 := map[string]int{
|
||||||
|
"a": 22,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(false, IsDisjoint(m1, m3))
|
||||||
|
}
|
||||||
|
|||||||
@@ -57,9 +57,9 @@ func Percent(val, total float64, n int) float64 {
|
|||||||
return float64(0)
|
return float64(0)
|
||||||
}
|
}
|
||||||
tmp := val / total * 100
|
tmp := val / total * 100
|
||||||
res := RoundToFloat(tmp, n)
|
result := RoundToFloat(tmp, n)
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// RoundToString round up to n decimal places
|
// RoundToString round up to n decimal places
|
||||||
@@ -67,8 +67,8 @@ func RoundToString(x float64, n int) string {
|
|||||||
tmp := math.Pow(10.0, float64(n))
|
tmp := math.Pow(10.0, float64(n))
|
||||||
x *= tmp
|
x *= tmp
|
||||||
x = math.Round(x)
|
x = math.Round(x)
|
||||||
res := strconv.FormatFloat(x/tmp, 'f', n, 64)
|
result := strconv.FormatFloat(x/tmp, 'f', n, 64)
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// RoundToFloat round up to n decimal places
|
// RoundToFloat round up to n decimal places
|
||||||
@@ -89,8 +89,8 @@ func TruncRound(x float64, n int) float64 {
|
|||||||
} else {
|
} else {
|
||||||
newFloat = temp[0] + "." + temp[1][:n]
|
newFloat = temp[0] + "." + temp[1][:n]
|
||||||
}
|
}
|
||||||
res, _ := strconv.ParseFloat(newFloat, 64)
|
result, _ := strconv.ParseFloat(newFloat, 64)
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Max return max value of params
|
// Max return max value of params
|
||||||
|
|||||||
@@ -87,6 +87,9 @@ func TestMax(t *testing.T) {
|
|||||||
assert.Equal(Max(0, 0), 0)
|
assert.Equal(Max(0, 0), 0)
|
||||||
assert.Equal(Max(1, 2, 3), 3)
|
assert.Equal(Max(1, 2, 3), 3)
|
||||||
assert.Equal(Max(1.2, 1.4, 1.1, 1.4), 1.4)
|
assert.Equal(Max(1.2, 1.4, 1.1, 1.4), 1.4)
|
||||||
|
|
||||||
|
type Integer int
|
||||||
|
assert.Equal(Max(Integer(1), Integer(0)), Integer(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMaxBy(t *testing.T) {
|
func TestMaxBy(t *testing.T) {
|
||||||
|
|||||||
228
netutil/http_client.go
Normal file
228
netutil/http_client.go
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
package netutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HttpRequest struct is a composed http request
|
||||||
|
type HttpRequest struct {
|
||||||
|
RawURL string
|
||||||
|
Method string
|
||||||
|
Headers http.Header
|
||||||
|
QueryParams url.Values
|
||||||
|
FormData url.Values
|
||||||
|
Body []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// HttpClientConfig contains some configurations for http client
|
||||||
|
type HttpClientConfig struct {
|
||||||
|
SSLEnabled bool
|
||||||
|
TLSConfig *tls.Config
|
||||||
|
Compressed bool
|
||||||
|
HandshakeTimeout time.Duration
|
||||||
|
ResponseTimeout time.Duration
|
||||||
|
Verbose bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaultHttpClientConfig defalut client config
|
||||||
|
var defaultHttpClientConfig = &HttpClientConfig{
|
||||||
|
Compressed: false,
|
||||||
|
HandshakeTimeout: 20 * time.Second,
|
||||||
|
ResponseTimeout: 40 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
// HttpClient is used for sending http request
|
||||||
|
type HttpClient struct {
|
||||||
|
*http.Client
|
||||||
|
TLS *tls.Config
|
||||||
|
Request *http.Request
|
||||||
|
Config HttpClientConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHttpClient make a HttpClient instance
|
||||||
|
func NewHttpClient() *HttpClient {
|
||||||
|
client := &HttpClient{
|
||||||
|
Client: &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
TLSHandshakeTimeout: defaultHttpClientConfig.HandshakeTimeout,
|
||||||
|
ResponseHeaderTimeout: defaultHttpClientConfig.ResponseTimeout,
|
||||||
|
DisableCompression: !defaultHttpClientConfig.Compressed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Config: *defaultHttpClientConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHttpClientWithConfig make a HttpClient instance with pass config
|
||||||
|
func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient {
|
||||||
|
if config == nil {
|
||||||
|
config = defaultHttpClientConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &HttpClient{
|
||||||
|
Client: &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
TLSHandshakeTimeout: config.HandshakeTimeout,
|
||||||
|
ResponseHeaderTimeout: config.ResponseTimeout,
|
||||||
|
DisableCompression: !config.Compressed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Config: *config,
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.SSLEnabled {
|
||||||
|
client.TLS = config.TLSConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendRequest send http request
|
||||||
|
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error) {
|
||||||
|
err := validateRequest(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rawUrl := request.RawURL
|
||||||
|
|
||||||
|
req, err := http.NewRequest(request.Method, rawUrl, bytes.NewBuffer(request.Body))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
client.setTLS(rawUrl)
|
||||||
|
client.setHeader(req, request.Headers)
|
||||||
|
client.setQueryParam(req, rawUrl, request.QueryParams)
|
||||||
|
|
||||||
|
if request.FormData != nil {
|
||||||
|
client.setFormData(req, request.FormData)
|
||||||
|
}
|
||||||
|
|
||||||
|
client.Request = req
|
||||||
|
|
||||||
|
resp, err := client.Client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeResponse decode response into target object
|
||||||
|
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error {
|
||||||
|
if resp == nil {
|
||||||
|
return errors.New("invalid target param")
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
return json.NewDecoder(resp.Body).Decode(target)
|
||||||
|
}
|
||||||
|
|
||||||
|
// setTLS set http client transport TLSClientConfig
|
||||||
|
func (client *HttpClient) setTLS(rawUrl string) {
|
||||||
|
if strings.HasPrefix(rawUrl, "https") {
|
||||||
|
if transport, ok := client.Client.Transport.(*http.Transport); ok {
|
||||||
|
transport.TLSClientConfig = client.TLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setHeader set http rquest header
|
||||||
|
func (client *HttpClient) setHeader(req *http.Request, headers http.Header) {
|
||||||
|
if headers == nil {
|
||||||
|
headers = make(http.Header)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := headers["Accept"]; !ok {
|
||||||
|
headers["Accept"] = []string{"*/*"}
|
||||||
|
}
|
||||||
|
if _, ok := headers["Accept-Encoding"]; !ok && client.Config.Compressed {
|
||||||
|
headers["Accept-Encoding"] = []string{"deflate, gzip"}
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header = headers
|
||||||
|
}
|
||||||
|
|
||||||
|
// setQueryParam set http request query string param
|
||||||
|
func (client *HttpClient) setQueryParam(req *http.Request, reqUrl string, queryParam url.Values) error {
|
||||||
|
if queryParam != nil {
|
||||||
|
if !strings.Contains(reqUrl, "?") {
|
||||||
|
reqUrl = reqUrl + "?" + queryParam.Encode()
|
||||||
|
} else {
|
||||||
|
reqUrl = reqUrl + "&" + queryParam.Encode()
|
||||||
|
}
|
||||||
|
u, err := url.Parse(reqUrl)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.URL = u
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *HttpClient) setFormData(req *http.Request, values url.Values) {
|
||||||
|
formData := []byte(values.Encode())
|
||||||
|
req.Body = ioutil.NopCloser(bytes.NewReader(formData))
|
||||||
|
req.ContentLength = int64(len(formData))
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateRequest check if a request has url, and valid method.
|
||||||
|
func validateRequest(req *HttpRequest) error {
|
||||||
|
if req.RawURL == "" {
|
||||||
|
return errors.New("invalid request url")
|
||||||
|
}
|
||||||
|
|
||||||
|
// common HTTP methods
|
||||||
|
methods := []string{"GET", "POST", "PUT", "DELETE", "PATCH",
|
||||||
|
"HEAD", "CONNECT", "OPTIONS", "TRACE"}
|
||||||
|
|
||||||
|
if !slice.Contain(methods, strings.ToUpper(req.Method)) {
|
||||||
|
return errors.New("invalid request method")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StructToUrlValues convert struct to url valuse,
|
||||||
|
// only convert the field which is exported and has `json` tag
|
||||||
|
func StructToUrlValues(targetStruct any) url.Values {
|
||||||
|
rv := reflect.ValueOf(targetStruct)
|
||||||
|
rt := reflect.TypeOf(targetStruct)
|
||||||
|
|
||||||
|
if rt.Kind() == reflect.Ptr {
|
||||||
|
rt = rt.Elem()
|
||||||
|
}
|
||||||
|
if rt.Kind() != reflect.Struct {
|
||||||
|
panic(fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", targetStruct))
|
||||||
|
}
|
||||||
|
|
||||||
|
result := url.Values{}
|
||||||
|
|
||||||
|
fieldNum := rt.NumField()
|
||||||
|
pattern := `^[A-Z]`
|
||||||
|
regex := regexp.MustCompile(pattern)
|
||||||
|
for i := 0; i < fieldNum; i++ {
|
||||||
|
name := rt.Field(i).Name
|
||||||
|
tag := rt.Field(i).Tag.Get("json")
|
||||||
|
if regex.MatchString(name) && tag != "" {
|
||||||
|
result.Add(tag, fmt.Sprintf("%v", rv.Field(i).Interface()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
95
netutil/http_client_test.go
Normal file
95
netutil/http_client_test.go
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
package netutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHttpClient_Get(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestHttpClient_Get")
|
||||||
|
|
||||||
|
request := &HttpRequest{
|
||||||
|
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||||
|
Method: "GET",
|
||||||
|
}
|
||||||
|
|
||||||
|
httpClient := NewHttpClient()
|
||||||
|
resp, err := httpClient.SendRequest(request)
|
||||||
|
if err != nil || resp.StatusCode != 200 {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Todo struct {
|
||||||
|
UserId int `json:"userId"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Completed bool `json:"completed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var todo Todo
|
||||||
|
httpClient.DecodeResponse(resp, &todo)
|
||||||
|
|
||||||
|
assert.Equal(1, todo.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHttpClent_Post(t *testing.T) {
|
||||||
|
header := http.Header{}
|
||||||
|
header.Add("Content-Type", "multipart/form-data")
|
||||||
|
|
||||||
|
postData := url.Values{}
|
||||||
|
postData.Add("userId", "1")
|
||||||
|
postData.Add("title", "testItem")
|
||||||
|
|
||||||
|
request := &HttpRequest{
|
||||||
|
RawURL: "https://jsonplaceholder.typicode.com/todos",
|
||||||
|
Method: "POST",
|
||||||
|
Headers: header,
|
||||||
|
FormData: postData,
|
||||||
|
}
|
||||||
|
|
||||||
|
httpClient := NewHttpClient()
|
||||||
|
resp, err := httpClient.SendRequest(request)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
t.Log("response: ", resp.StatusCode, string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStructToUrlValues(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStructToUrlValues")
|
||||||
|
|
||||||
|
type TodoQuery struct {
|
||||||
|
Id int `json:"id"`
|
||||||
|
UserId int `json:"userId"`
|
||||||
|
}
|
||||||
|
todoQuery := TodoQuery{
|
||||||
|
Id: 1,
|
||||||
|
UserId: 1,
|
||||||
|
}
|
||||||
|
todoValues := StructToUrlValues(todoQuery)
|
||||||
|
|
||||||
|
assert.Equal("1", todoValues.Get("id"))
|
||||||
|
assert.Equal("1", todoValues.Get("userId"))
|
||||||
|
|
||||||
|
request := &HttpRequest{
|
||||||
|
RawURL: "https://jsonplaceholder.typicode.com/todos",
|
||||||
|
Method: "GET",
|
||||||
|
QueryParams: todoValues,
|
||||||
|
}
|
||||||
|
|
||||||
|
httpClient := NewHttpClient()
|
||||||
|
resp, err := httpClient.SendRequest(request)
|
||||||
|
if err != nil || resp.StatusCode != 200 {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
t.Log("response: ", string(body))
|
||||||
|
}
|
||||||
@@ -18,7 +18,6 @@ func TestHttpGet(t *testing.T) {
|
|||||||
resp, err := HttpGet(url, header)
|
resp, err := HttpGet(url, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
t.FailNow()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body, _ := ioutil.ReadAll(resp.Body)
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
@@ -40,7 +39,6 @@ func TestHttpPost(t *testing.T) {
|
|||||||
resp, err := HttpPost(url, header, nil, bodyParams)
|
resp, err := HttpPost(url, header, nil, bodyParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
t.FailNow()
|
|
||||||
}
|
}
|
||||||
body, _ := ioutil.ReadAll(resp.Body)
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
t.Log("response: ", resp.StatusCode, string(body))
|
t.Log("response: ", resp.StatusCode, string(body))
|
||||||
@@ -67,7 +65,6 @@ func TestHttpPostFormData(t *testing.T) {
|
|||||||
resp, err := HttpPost(apiUrl, header, postData, nil)
|
resp, err := HttpPost(apiUrl, header, postData, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
t.FailNow()
|
|
||||||
}
|
}
|
||||||
body, _ := ioutil.ReadAll(resp.Body)
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
t.Log("response: ", resp.StatusCode, string(body))
|
t.Log("response: ", resp.StatusCode, string(body))
|
||||||
@@ -89,7 +86,6 @@ func TestHttpPut(t *testing.T) {
|
|||||||
resp, err := HttpPut(url, header, nil, bodyParams)
|
resp, err := HttpPut(url, header, nil, bodyParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
t.FailNow()
|
|
||||||
}
|
}
|
||||||
body, _ := ioutil.ReadAll(resp.Body)
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
t.Log("response: ", resp.StatusCode, string(body))
|
t.Log("response: ", resp.StatusCode, string(body))
|
||||||
@@ -111,7 +107,6 @@ func TestHttpPatch(t *testing.T) {
|
|||||||
resp, err := HttpPatch(url, header, nil, bodyParams)
|
resp, err := HttpPatch(url, header, nil, bodyParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
t.FailNow()
|
|
||||||
}
|
}
|
||||||
body, _ := ioutil.ReadAll(resp.Body)
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
t.Log("response: ", resp.StatusCode, string(body))
|
t.Log("response: ", resp.StatusCode, string(body))
|
||||||
@@ -122,7 +117,6 @@ func TestHttpDelete(t *testing.T) {
|
|||||||
resp, err := HttpDelete(url)
|
resp, err := HttpDelete(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
t.FailNow()
|
|
||||||
}
|
}
|
||||||
body, _ := ioutil.ReadAll(resp.Body)
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
t.Log("response: ", resp.StatusCode, string(body))
|
t.Log("response: ", resp.StatusCode, string(body))
|
||||||
@@ -148,7 +142,6 @@ func TestParseResponse(t *testing.T) {
|
|||||||
resp, err := HttpGet(url, header)
|
resp, err := HttpGet(url, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
t.FailNow()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Todo struct {
|
type Todo struct {
|
||||||
@@ -162,7 +155,6 @@ func TestParseResponse(t *testing.T) {
|
|||||||
err = ParseHttpResponse(resp, toDoResp)
|
err = ParseHttpResponse(resp, toDoResp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
t.FailNow()
|
|
||||||
}
|
}
|
||||||
t.Log("response: ", toDoResp)
|
t.Log("response: ", toDoResp)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -157,3 +158,15 @@ func IsInternalIP(IP net.IP) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EncodeUrl encode url
|
||||||
|
func EncodeUrl(urlStr string) (string, error) {
|
||||||
|
URL, err := url.Parse(urlStr)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
URL.RawQuery = URL.Query().Encode()
|
||||||
|
|
||||||
|
return URL.String(), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -96,3 +96,16 @@ func TestGetMacAddrs(t *testing.T) {
|
|||||||
macAddrs := GetMacAddrs()
|
macAddrs := GetMacAddrs()
|
||||||
t.Log(macAddrs)
|
t.Log(macAddrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEncodeUrl(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIsInternalIP")
|
||||||
|
|
||||||
|
urlAddr := "http://www.lancet.com?a=1&b=[2]"
|
||||||
|
encodedUrl, err := EncodeUrl(urlAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := "http://www.lancet.com?a=1&b=%5B2%5D"
|
||||||
|
assert.Equal(expected, encodedUrl)
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,18 +12,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RandString generate random string
|
const (
|
||||||
// see https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go
|
NUMERAL = "0123456789"
|
||||||
func RandString(length int) string {
|
LOWER_LETTERS = "abcdefghijklmnopqrstuvwxyz"
|
||||||
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
UPPER_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
b := make([]byte, length)
|
)
|
||||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
||||||
for i := range b {
|
|
||||||
b[i] = letters[r.Int63()%int64(len(letters))]
|
|
||||||
}
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RandInt generate random int between min and max, maybe min, not be max
|
// RandInt generate random int between min and max, maybe min, not be max
|
||||||
func RandInt(min, max int) int {
|
func RandInt(min, max int) int {
|
||||||
@@ -50,6 +44,41 @@ func RandBytes(length int) []byte {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RandString generate random string
|
||||||
|
func RandString(length int) string {
|
||||||
|
return random(LETTERS, length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RandUpper generate a random upper case string
|
||||||
|
func RandUpper(length int) string {
|
||||||
|
return random(UPPER_LETTERS, length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RandLower generate a random lower case string
|
||||||
|
func RandLower(length int) string {
|
||||||
|
return random(LOWER_LETTERS, length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RandNumeral generate a random numeral string
|
||||||
|
func RandNumeral(length int) string {
|
||||||
|
return random(NUMERAL, length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RandNumeralOrLetter generate a random numeral or letter string
|
||||||
|
func RandNumeralOrLetter(length int) string {
|
||||||
|
return random(NUMERAL+LETTERS, length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// random generate a random string based on given string range
|
||||||
|
func random(s string, length int) string {
|
||||||
|
b := make([]byte, length)
|
||||||
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
for i := range b {
|
||||||
|
b[i] = s[r.Int63()%int64(len(s))]
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
// UUIdV4 generate a random UUID of version 4 according to RFC 4122
|
// UUIdV4 generate a random UUID of version 4 according to RFC 4122
|
||||||
func UUIdV4() (string, error) {
|
func UUIdV4() (string, error) {
|
||||||
uuid := make([]byte, 16)
|
uuid := make([]byte, 16)
|
||||||
|
|||||||
@@ -19,6 +19,51 @@ func TestRandString(t *testing.T) {
|
|||||||
assert.Equal(true, reg.MatchString(randStr))
|
assert.Equal(true, reg.MatchString(randStr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRandUpper(t *testing.T) {
|
||||||
|
pattern := `^[A-Z]+$`
|
||||||
|
reg := regexp.MustCompile(pattern)
|
||||||
|
|
||||||
|
randStr := RandUpper(6)
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestRandUpper")
|
||||||
|
assert.Equal(6, len(randStr))
|
||||||
|
assert.Equal(true, reg.MatchString(randStr))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRandLower(t *testing.T) {
|
||||||
|
pattern := `^[a-z]+$`
|
||||||
|
reg := regexp.MustCompile(pattern)
|
||||||
|
|
||||||
|
randStr := RandLower(6)
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestRandLower")
|
||||||
|
assert.Equal(6, len(randStr))
|
||||||
|
assert.Equal(true, reg.MatchString(randStr))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRandNumeral(t *testing.T) {
|
||||||
|
pattern := `^[0-9]+$`
|
||||||
|
reg := regexp.MustCompile(pattern)
|
||||||
|
|
||||||
|
randStr := RandNumeral(12)
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestRandNumeral")
|
||||||
|
assert.Equal(12, len(randStr))
|
||||||
|
assert.Equal(true, reg.MatchString(randStr))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRandNumeralOrLetter(t *testing.T) {
|
||||||
|
pattern := `^[0-9a-zA-Z]+$`
|
||||||
|
reg := regexp.MustCompile(pattern)
|
||||||
|
|
||||||
|
randStr := RandNumeralOrLetter(10)
|
||||||
|
t.Log(randStr)
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestRandNumeralOrLetter")
|
||||||
|
assert.Equal(10, len(randStr))
|
||||||
|
assert.Equal(true, reg.MatchString(randStr))
|
||||||
|
}
|
||||||
|
|
||||||
func TestRandInt(t *testing.T) {
|
func TestRandInt(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestRandInt")
|
assert := internal.NewAssert(t, "TestRandInt")
|
||||||
|
|
||||||
|
|||||||
349
slice/slice.go
349
slice/slice.go
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
// Copyright 2021 dudaodong@gmail.com. All rights resulterved.
|
||||||
// Use of this source code is governed by MIT license
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
// Package slice implements some functions to manipulate slice.
|
// Package slice implements some functions to manipulate slice.
|
||||||
@@ -14,13 +14,13 @@ import (
|
|||||||
|
|
||||||
// Contain check if the value is in the slice or not
|
// Contain check if the value is in the slice or not
|
||||||
func Contain[T comparable](slice []T, value T) bool {
|
func Contain[T comparable](slice []T, value T) bool {
|
||||||
|
set := make(map[T]struct{}, len(slice))
|
||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
if v == value {
|
set[v] = struct{}{}
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
_, ok := set[value]
|
||||||
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainSubSlice check if the slice contain subslice or not
|
// ContainSubSlice check if the slice contain subslice or not
|
||||||
@@ -36,10 +36,10 @@ func ContainSubSlice[T comparable](slice, subslice []T) bool {
|
|||||||
|
|
||||||
// Chunk creates an slice of elements split into groups the length of size.
|
// Chunk creates an slice of elements split into groups the length of size.
|
||||||
func Chunk[T any](slice []T, size int) [][]T {
|
func Chunk[T any](slice []T, size int) [][]T {
|
||||||
var res [][]T
|
result := [][]T{}
|
||||||
|
|
||||||
if len(slice) == 0 || size <= 0 {
|
if len(slice) == 0 || size <= 0 {
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
length := len(slice)
|
length := len(slice)
|
||||||
@@ -47,9 +47,9 @@ func Chunk[T any](slice []T, size int) [][]T {
|
|||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
var tmp []T
|
var tmp []T
|
||||||
tmp = append(tmp, v)
|
tmp = append(tmp, v)
|
||||||
res = append(res, tmp)
|
result = append(result, tmp)
|
||||||
}
|
}
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// divide slice equally
|
// divide slice equally
|
||||||
@@ -57,52 +57,53 @@ func Chunk[T any](slice []T, size int) [][]T {
|
|||||||
for i := 0; i < divideNum; i++ {
|
for i := 0; i < divideNum; i++ {
|
||||||
if i == divideNum-1 {
|
if i == divideNum-1 {
|
||||||
if len(slice[i*size:]) > 0 {
|
if len(slice[i*size:]) > 0 {
|
||||||
res = append(res, slice[i*size:])
|
result = append(result, slice[i*size:])
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res = append(res, slice[i*size:(i+1)*size])
|
result = append(result, slice[i*size:(i+1)*size])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compact creates an slice with all falsey values removed. The values false, nil, 0, and "" are falsey
|
// Compact creates an slice with all falsey values removed. The values false, nil, 0, and "" are falsey
|
||||||
func Compact[T any](slice []T) []T {
|
func Compact[T any](slice []T) []T {
|
||||||
res := make([]T, 0, 0)
|
result := make([]T, 0)
|
||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
if !reflect.DeepEqual(v, nil) &&
|
if !reflect.DeepEqual(v, nil) &&
|
||||||
!reflect.DeepEqual(v, false) &&
|
!reflect.DeepEqual(v, false) &&
|
||||||
!reflect.DeepEqual(v, "") &&
|
!reflect.DeepEqual(v, "") &&
|
||||||
!reflect.DeepEqual(v, 0) {
|
!reflect.DeepEqual(v, 0) {
|
||||||
res = append(res, v)
|
result = append(result, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concat creates a new slice concatenating slice with any additional slices and/or values.
|
// Concat creates a new slice concatenating slice with any additional slices and/or values.
|
||||||
func Concat[T any](slice []T, values ...[]T) []T {
|
func Concat[T any](slice []T, values ...[]T) []T {
|
||||||
res := append([]T{}, slice...)
|
result := append([]T{}, slice...)
|
||||||
|
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
res = append(res, v...)
|
result = append(result, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Difference creates an slice of whose element in slice but not in comparedSlice
|
// Difference creates an slice of whose element in slice but not in comparedSlice
|
||||||
func Difference[T comparable](slice, comparedSlice []T) []T {
|
func Difference[T comparable](slice, comparedSlice []T) []T {
|
||||||
var res []T
|
result := []T{}
|
||||||
|
|
||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
if !Contain(comparedSlice, v) {
|
if !Contain(comparedSlice, v) {
|
||||||
res = append(res, v)
|
result = append(result, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// DifferenceBy it accepts iteratee which is invoked for each element of slice
|
// DifferenceBy it accepts iteratee which is invoked for each element of slice
|
||||||
@@ -112,19 +113,19 @@ func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(inde
|
|||||||
orginSliceAfterMap := Map(slice, iteratee)
|
orginSliceAfterMap := Map(slice, iteratee)
|
||||||
comparedSliceAfterMap := Map(comparedSlice, iteratee)
|
comparedSliceAfterMap := Map(comparedSlice, iteratee)
|
||||||
|
|
||||||
res := make([]T, 0, 0)
|
result := make([]T, 0)
|
||||||
for i, v := range orginSliceAfterMap {
|
for i, v := range orginSliceAfterMap {
|
||||||
if !Contain(comparedSliceAfterMap, v) {
|
if !Contain(comparedSliceAfterMap, v) {
|
||||||
res = append(res, slice[i])
|
result = append(result, slice[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
//DifferenceWith accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice. The comparator is invoked with two arguments: (arrVal, othVal).
|
//DifferenceWith accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice. The comparator is invoked with two arguments: (arrVal, othVal).
|
||||||
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T {
|
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value1, value2 T) bool) []T {
|
||||||
res := make([]T, 0, 0)
|
result := make([]T, 0)
|
||||||
|
|
||||||
getIndex := func(arr []T, item T, comparison func(v1, v2 T) bool) int {
|
getIndex := func(arr []T, item T, comparison func(v1, v2 T) bool) int {
|
||||||
index := -1
|
index := -1
|
||||||
@@ -140,11 +141,11 @@ func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value,
|
|||||||
for i, v := range slice {
|
for i, v := range slice {
|
||||||
index := getIndex(comparedSlice, v, comparator)
|
index := getIndex(comparedSlice, v, comparator)
|
||||||
if index == -1 {
|
if index == -1 {
|
||||||
res = append(res, slice[i])
|
result = append(result, slice[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equal checks if two slices are equal: the same length and all elements' order and value are equal
|
// Equal checks if two slices are equal: the same length and all elements' order and value are equal
|
||||||
@@ -180,11 +181,8 @@ func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) boo
|
|||||||
|
|
||||||
// Every return true if all of the values in the slice pass the predicate function.
|
// 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, item 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")
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentLength int
|
var currentLength int
|
||||||
|
|
||||||
for i, v := range slice {
|
for i, v := range slice {
|
||||||
if predicate(i, v) {
|
if predicate(i, v) {
|
||||||
currentLength++
|
currentLength++
|
||||||
@@ -196,9 +194,6 @@ func Every[T any](slice []T, predicate func(index int, item T) bool) bool {
|
|||||||
|
|
||||||
// None return true if all the values in the slice mismatch the criteria
|
// None return true if all the values in the slice mismatch the criteria
|
||||||
func None[T any](slice []T, predicate func(index int, item 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")
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentLength int
|
var currentLength int
|
||||||
for i, v := range slice {
|
for i, v := range slice {
|
||||||
@@ -212,39 +207,30 @@ func None[T any](slice []T, predicate func(index int, item T) bool) bool {
|
|||||||
|
|
||||||
// Some return true if any of the values in the list pass the predicate function.
|
// 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, item 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")
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range slice {
|
for i, v := range slice {
|
||||||
if predicate(i, v) {
|
if predicate(i, v) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter iterates over elements of slice, returning an slice of all elements pass the predicate function
|
// 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, item T) bool) []T {
|
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T {
|
||||||
if predicate == nil {
|
result := make([]T, 0)
|
||||||
panic("predicate func is missing")
|
|
||||||
}
|
|
||||||
|
|
||||||
res := make([]T, 0, 0)
|
|
||||||
for i, v := range slice {
|
for i, v := range slice {
|
||||||
if predicate(i, v) {
|
if predicate(i, v) {
|
||||||
res = append(res, v)
|
result = append(result, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count iterates over elements of slice, returns a count of all matched elements
|
// Count iterates over elements of slice, returns a count of all matched elements
|
||||||
func Count[T any](slice []T, predicate func(index int, item 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")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(slice) == 0 {
|
if len(slice) == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -261,10 +247,6 @@ func Count[T any](slice []T, predicate func(index int, item T) bool) int {
|
|||||||
|
|
||||||
// GroupBy iterate over elements of the slice, each element will be group by criteria, returns two slices
|
// 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, item 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")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(slice) == 0 {
|
if len(slice) == 0 {
|
||||||
return make([]T, 0), make([]T, 0)
|
return make([]T, 0), make([]T, 0)
|
||||||
}
|
}
|
||||||
@@ -284,32 +266,24 @@ func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T)
|
|||||||
return groupA, groupB
|
return groupA, groupB
|
||||||
}
|
}
|
||||||
|
|
||||||
// GroupWith return a map composed of keys generated from the results of running each element of slice thru iteratee.
|
// GroupWith return a map composed of keys generated from the resultults of running each element of slice thru iteratee.
|
||||||
func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T {
|
func GroupWith[T any, U comparable](slice []T, iteratee func(item T) U) map[U][]T {
|
||||||
if iteratee == nil {
|
result := make(map[U][]T)
|
||||||
panic("iteratee func is missing")
|
|
||||||
}
|
|
||||||
|
|
||||||
res := make(map[U][]T)
|
|
||||||
|
|
||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
key := iteratee(v)
|
key := iteratee(v)
|
||||||
if _, ok := res[key]; !ok {
|
if _, ok := result[key]; !ok {
|
||||||
res[key] = []T{}
|
result[key] = []T{}
|
||||||
}
|
}
|
||||||
res[key] = append(res[key], v)
|
result[key] = append(result[key], v)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find iterates over elements of slice, returning the first one that passes a truth test on predicate function.
|
// 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
|
// If return T is nil then no items matched the predicate func
|
||||||
func Find[T any](slice []T, predicate func(index int, item 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")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(slice) == 0 {
|
if len(slice) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
@@ -332,10 +306,6 @@ func Find[T any](slice []T, predicate func(index int, item 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.
|
// 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
|
// If return T is nil then no items matched the predicate func
|
||||||
func FindLast[T any](slice []T, predicate func(index int, item 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")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(slice) == 0 {
|
if len(slice) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
@@ -355,13 +325,40 @@ func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, boo
|
|||||||
return &slice[index], true
|
return &slice[index], true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flatten flattens slice with one level
|
||||||
|
func Flatten(slice any) any {
|
||||||
|
sv := sliceValue(slice)
|
||||||
|
|
||||||
|
var result reflect.Value
|
||||||
|
if sv.Type().Elem().Kind() == reflect.Interface {
|
||||||
|
result = reflect.MakeSlice(reflect.TypeOf([]interface{}{}), 0, sv.Len())
|
||||||
|
} else if sv.Type().Elem().Kind() == reflect.Slice {
|
||||||
|
result = reflect.MakeSlice(sv.Type().Elem(), 0, sv.Len())
|
||||||
|
} else {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < sv.Len(); i++ {
|
||||||
|
item := reflect.ValueOf(sv.Index(i).Interface())
|
||||||
|
if item.Kind() == reflect.Slice {
|
||||||
|
for j := 0; j < item.Len(); j++ {
|
||||||
|
result = reflect.Append(result, item.Index(j))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = reflect.Append(result, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
// FlattenDeep flattens slice recursive
|
// FlattenDeep flattens slice recursive
|
||||||
func FlattenDeep(slice any) any {
|
func FlattenDeep(slice any) any {
|
||||||
sv := sliceValue(slice)
|
sv := sliceValue(slice)
|
||||||
st := sliceElemType(sv.Type())
|
st := sliceElemType(sv.Type())
|
||||||
tmp := reflect.MakeSlice(reflect.SliceOf(st), 0, 0)
|
tmp := reflect.MakeSlice(reflect.SliceOf(st), 0, 0)
|
||||||
res := flattenRecursive(sv, tmp)
|
result := flattenRecursive(sv, tmp)
|
||||||
return res.Interface()
|
return result.Interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
func flattenRecursive(value reflect.Value, result reflect.Value) reflect.Value {
|
func flattenRecursive(value reflect.Value, result reflect.Value) reflect.Value {
|
||||||
@@ -381,10 +378,6 @@ func flattenRecursive(value reflect.Value, result reflect.Value) reflect.Value {
|
|||||||
|
|
||||||
// ForEach iterates over elements of slice and invokes function for each element
|
// ForEach iterates over elements of slice and invokes function for each element
|
||||||
func ForEach[T any](slice []T, iteratee func(index int, item T)) {
|
func ForEach[T any](slice []T, iteratee func(index int, item T)) {
|
||||||
if iteratee == nil {
|
|
||||||
panic("iteratee func is missing")
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range slice {
|
for i, v := range slice {
|
||||||
iteratee(i, v)
|
iteratee(i, v)
|
||||||
}
|
}
|
||||||
@@ -392,38 +385,51 @@ func ForEach[T any](slice []T, iteratee func(index int, item T)) {
|
|||||||
|
|
||||||
// Map creates an slice of values by running each element of slice thru iteratee function.
|
// 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, item T) U) []U {
|
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U {
|
||||||
if iteratee == nil {
|
result := make([]U, len(slice), cap(slice))
|
||||||
panic("iteratee func is missing")
|
|
||||||
}
|
|
||||||
|
|
||||||
res := make([]U, len(slice), cap(slice))
|
|
||||||
for i, v := range slice {
|
for i, v := range slice {
|
||||||
res[i] = iteratee(i, v)
|
result[i] = iteratee(i, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reduce creates an slice of values by running each element of slice thru iteratee function.
|
// 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, item1, item2 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")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(slice) == 0 {
|
if len(slice) == 0 {
|
||||||
return initial
|
return initial
|
||||||
}
|
}
|
||||||
|
|
||||||
res := iteratee(0, initial, slice[0])
|
result := iteratee(0, initial, slice[0])
|
||||||
|
|
||||||
tmp := make([]T, 2, 2)
|
tmp := make([]T, 2)
|
||||||
for i := 1; i < len(slice); i++ {
|
for i := 1; i < len(slice); i++ {
|
||||||
tmp[0] = res
|
tmp[0] = result
|
||||||
tmp[1] = slice[i]
|
tmp[1] = slice[i]
|
||||||
res = iteratee(i, tmp[0], tmp[1])
|
result = iteratee(i, tmp[0], tmp[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace returns a copy of the slice with the first n non-overlapping instances of old replaced by new
|
||||||
|
func Replace[T comparable](slice []T, old T, new T, n int) []T {
|
||||||
|
result := make([]T, len(slice))
|
||||||
|
copy(result, slice)
|
||||||
|
|
||||||
|
for i := range result {
|
||||||
|
if result[i] == old && n != 0 {
|
||||||
|
result[i] = new
|
||||||
|
n--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceAll returns a copy of the slice with all non-overlapping instances of old replaced by new.
|
||||||
|
func ReplaceAll[T comparable](slice []T, old T, new T) []T {
|
||||||
|
return Replace(slice, old, new, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InterfaceSlice convert param to slice of interface.
|
// InterfaceSlice convert param to slice of interface.
|
||||||
@@ -433,12 +439,12 @@ func InterfaceSlice(slice any) []any {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
res := make([]any, sv.Len())
|
result := make([]any, sv.Len())
|
||||||
for i := 0; i < sv.Len(); i++ {
|
for i := 0; i < sv.Len(); i++ {
|
||||||
res[i] = sv.Index(i).Interface()
|
result[i] = sv.Index(i).Interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// StringSlice convert param to slice of string.
|
// StringSlice convert param to slice of string.
|
||||||
@@ -495,7 +501,7 @@ func DeleteAt[T any](slice []T, start int, end ...int) []T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if start == size-1 {
|
if start == size-1 {
|
||||||
slice = append(slice[:start])
|
slice = slice[:start]
|
||||||
} else {
|
} else {
|
||||||
slice = append(slice[:start], slice[start+1:]...)
|
slice = append(slice[:start], slice[start+1:]...)
|
||||||
}
|
}
|
||||||
@@ -530,13 +536,11 @@ func InsertAt[T any](slice []T, index int, value any) []T {
|
|||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
// value is T
|
|
||||||
if v, ok := value.(T); ok {
|
if v, ok := value.(T); ok {
|
||||||
slice = append(slice[:index], append([]T{v}, slice[index:]...)...)
|
slice = append(slice[:index], append([]T{v}, slice[index:]...)...)
|
||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
// value is []T
|
|
||||||
if v, ok := value.([]T); ok {
|
if v, ok := value.([]T); ok {
|
||||||
slice = append(slice[:index], append(v, slice[index:]...)...)
|
slice = append(slice[:index], append(v, slice[index:]...)...)
|
||||||
return slice
|
return slice
|
||||||
@@ -559,60 +563,70 @@ func UpdateAt[T any](slice []T, index int, value T) []T {
|
|||||||
|
|
||||||
// Unique remove duplicate elements in slice.
|
// Unique remove duplicate elements in slice.
|
||||||
func Unique[T comparable](slice []T) []T {
|
func Unique[T comparable](slice []T) []T {
|
||||||
if len(slice) == 0 {
|
result := []T{}
|
||||||
return []T{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// here no use map filter. if use it, the result slice element order is random, not same as origin slice
|
|
||||||
var res []T
|
|
||||||
for i := 0; i < len(slice); i++ {
|
for i := 0; i < len(slice); i++ {
|
||||||
v := slice[i]
|
v := slice[i]
|
||||||
skip := true
|
skip := true
|
||||||
for j := range res {
|
for j := range result {
|
||||||
if v == res[j] {
|
if v == result[j] {
|
||||||
skip = false
|
skip = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if skip {
|
if skip {
|
||||||
res = append(res, v)
|
result = append(result, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// UniqueBy call iteratee func with every item of slice, then remove duplicated.
|
// UniqueBy call iteratee func with every item of slice, then remove duplicated.
|
||||||
func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T {
|
func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T {
|
||||||
if len(slice) == 0 {
|
result := []T{}
|
||||||
return []T{}
|
|
||||||
}
|
|
||||||
|
|
||||||
var res []T
|
|
||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
val := iteratee(v)
|
val := iteratee(v)
|
||||||
res = append(res, val)
|
result = append(result, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Unique(res)
|
return Unique(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Union creates a slice of unique values, in order, from all given slices. using == for equality comparisons.
|
// Union creates a slice of unique values, in order, from all given slices.
|
||||||
func Union[T comparable](slices ...[]T) []T {
|
func Union[T comparable](slices ...[]T) []T {
|
||||||
if len(slices) == 0 {
|
result := []T{}
|
||||||
return []T{}
|
contain := map[T]struct{}{}
|
||||||
}
|
|
||||||
|
|
||||||
// append all slices, then unique it
|
|
||||||
var allElements []T
|
|
||||||
|
|
||||||
for _, slice := range slices {
|
for _, slice := range slices {
|
||||||
for _, v := range slice {
|
for _, item := range slice {
|
||||||
allElements = append(allElements, v)
|
if _, ok := contain[item]; !ok {
|
||||||
|
contain[item] = struct{}{}
|
||||||
|
result = append(result, item)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Unique(allElements)
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnionBy is like Union, what's more it accepts iteratee which is invoked for each element of each slice
|
||||||
|
func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T {
|
||||||
|
result := []T{}
|
||||||
|
contain := map[V]struct{}{}
|
||||||
|
|
||||||
|
for _, slice := range slices {
|
||||||
|
for _, item := range slice {
|
||||||
|
val := predicate(item)
|
||||||
|
if _, ok := contain[val]; !ok {
|
||||||
|
contain[val] = struct{}{}
|
||||||
|
result = append(result, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intersection creates a slice of unique values that included by all slices.
|
// Intersection creates a slice of unique values that included by all slices.
|
||||||
@@ -624,28 +638,32 @@ func Intersection[T comparable](slices ...[]T) []T {
|
|||||||
return Unique(slices[0])
|
return Unique(slices[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
var res []T
|
reducer := func(sliceA, sliceB []T) []T {
|
||||||
|
hashMap := make(map[T]int)
|
||||||
reducer := func(s1, s2 []T) []T {
|
for _, val := range sliceA {
|
||||||
s := make([]T, 0, 0)
|
hashMap[val] = 1
|
||||||
for _, v := range s1 {
|
|
||||||
if Contain(s2, v) {
|
|
||||||
s = append(s, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res = reducer(slices[0], slices[1])
|
out := make([]T, 0)
|
||||||
|
for _, val := range sliceB {
|
||||||
|
if v, ok := hashMap[val]; v == 1 && ok {
|
||||||
|
out = append(out, val)
|
||||||
|
hashMap[val]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
reduceSlice := make([][]T, 2, 2)
|
result := reducer(slices[0], slices[1])
|
||||||
|
|
||||||
|
reduceSlice := make([][]T, 2)
|
||||||
for i := 2; i < len(slices); i++ {
|
for i := 2; i < len(slices); i++ {
|
||||||
reduceSlice[0] = res
|
reduceSlice[0] = result
|
||||||
reduceSlice[1] = slices[i]
|
reduceSlice[1] = slices[i]
|
||||||
res = reducer(reduceSlice[0], reduceSlice[1])
|
result = reducer(reduceSlice[0], reduceSlice[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
return Unique(res)
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// SymmetricDifference oppoiste operation of intersection function
|
// SymmetricDifference oppoiste operation of intersection function
|
||||||
@@ -657,7 +675,7 @@ func SymmetricDifference[T comparable](slices ...[]T) []T {
|
|||||||
return Unique(slices[0])
|
return Unique(slices[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
res := make([]T, 0)
|
result := make([]T, 0)
|
||||||
|
|
||||||
intersectSlice := Intersection(slices...)
|
intersectSlice := Intersection(slices...)
|
||||||
|
|
||||||
@@ -665,13 +683,13 @@ func SymmetricDifference[T comparable](slices ...[]T) []T {
|
|||||||
slice := slices[i]
|
slice := slices[i]
|
||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
if !Contain(intersectSlice, v) {
|
if !Contain(intersectSlice, v) {
|
||||||
res = append(res, v)
|
result = append(result, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Unique(res)
|
return Unique(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverse return slice of element order is reversed to the given slice
|
// Reverse return slice of element order is reversed to the given slice
|
||||||
@@ -683,13 +701,12 @@ func Reverse[T any](slice []T) {
|
|||||||
|
|
||||||
// Shuffle creates an slice of shuffled values
|
// Shuffle creates an slice of shuffled values
|
||||||
func Shuffle[T any](slice []T) []T {
|
func Shuffle[T any](slice []T) []T {
|
||||||
|
result := make([]T, len(slice))
|
||||||
res := make([]T, len(slice))
|
|
||||||
for i, v := range rand.Perm(len(slice)) {
|
for i, v := range rand.Perm(len(slice)) {
|
||||||
res[i] = slice[v]
|
result[i] = slice[v]
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// SortByField return sorted slice by field
|
// SortByField return sorted slice by field
|
||||||
@@ -770,14 +787,14 @@ func Without[T comparable](slice []T, values ...T) []T {
|
|||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
out := make([]T, 0, len(slice))
|
result := make([]T, 0, len(slice))
|
||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
if !Contain(values, v) {
|
if !Contain(values, v) {
|
||||||
out = append(out, v)
|
result = append(result, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return out
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexOf returns the index at which the first occurrence of a value is found in a slice or return -1
|
// IndexOf returns the index at which the first occurrence of a value is found in a slice or return -1
|
||||||
@@ -806,18 +823,38 @@ func LastIndexOf[T comparable](slice []T, value T) int {
|
|||||||
|
|
||||||
// ToSlicePointer returns a pointer to the slices of a variable parameter transformation
|
// ToSlicePointer returns a pointer to the slices of a variable parameter transformation
|
||||||
func ToSlicePointer[T any](value ...T) []*T {
|
func ToSlicePointer[T any](value ...T) []*T {
|
||||||
out := make([]*T, len(value))
|
result := make([]*T, len(value))
|
||||||
for i := range value {
|
for i := range value {
|
||||||
out[i] = &value[i]
|
result[i] = &value[i]
|
||||||
}
|
}
|
||||||
return out
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToSlice returns a slices of a variable parameter transformation
|
// ToSlice returns a slices of a variable parameter transformation
|
||||||
func ToSlice[T any](value ...T) []T {
|
func ToSlice[T any](value ...T) []T {
|
||||||
out := make([]T, len(value))
|
result := make([]T, len(value))
|
||||||
for i := range value {
|
copy(result, value)
|
||||||
out[i] = value[i]
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
return out
|
|
||||||
|
// AppendIfAbsent only absent append the value
|
||||||
|
func AppendIfAbsent[T comparable](slice []T, value T) []T {
|
||||||
|
if !Contain(slice, value) {
|
||||||
|
slice = append(slice, value)
|
||||||
|
}
|
||||||
|
return slice
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyBy converts a slice to a map based on a callback function
|
||||||
|
func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T {
|
||||||
|
result := make(map[U]T, len(slice))
|
||||||
|
|
||||||
|
for _, v := range slice {
|
||||||
|
k := iteratee(v)
|
||||||
|
result[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,45 +14,6 @@ func sliceValue(slice any) reflect.Value {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// functionValue return the reflect value of a function
|
|
||||||
func functionValue(function any) reflect.Value {
|
|
||||||
v := reflect.ValueOf(function)
|
|
||||||
if v.Kind() != reflect.Func {
|
|
||||||
panic(fmt.Sprintf("Invalid function type, value of type %T", function))
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkSliceCallbackFuncSignature Check func sign : s :[]type1{} -> func(i int, data type1) type2
|
|
||||||
// see https://coolshell.cn/articles/21164.html#%E6%B3%9B%E5%9E%8BMap-Reduce
|
|
||||||
func checkSliceCallbackFuncSignature(fn reflect.Value, types ...reflect.Type) bool {
|
|
||||||
//Check it is a function
|
|
||||||
if fn.Kind() != reflect.Func {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// NumIn() - returns a function type's input parameter count.
|
|
||||||
// NumOut() - returns a function type's output parameter count.
|
|
||||||
if (fn.Type().NumIn() != len(types)-1) || (fn.Type().NumOut() != 1) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// In() - returns the type of a function type's i'th input parameter.
|
|
||||||
// first input param type should be int
|
|
||||||
if fn.Type().In(0) != reflect.TypeOf(1) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i := 0; i < len(types)-1; i++ {
|
|
||||||
if fn.Type().In(i) != types[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Out() - returns the type of a function type's i'th output parameter.
|
|
||||||
outType := types[len(types)-1]
|
|
||||||
if outType != nil && fn.Type().Out(0) != outType {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// sliceElemType get slice element type
|
// sliceElemType get slice element type
|
||||||
func sliceElemType(reflectType reflect.Type) reflect.Type {
|
func sliceElemType(reflectType reflect.Type) reflect.Type {
|
||||||
for {
|
for {
|
||||||
|
|||||||
@@ -236,6 +236,14 @@ func TestFindFoundNothing(t *testing.T) {
|
|||||||
assert.Equal(false, ok)
|
assert.Equal(false, ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFlatten(t *testing.T) {
|
||||||
|
input := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
|
||||||
|
expected := [][]string{{"a", "b"}, {"c", "d"}}
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestFlattenDeep")
|
||||||
|
assert.Equal(expected, Flatten(input))
|
||||||
|
}
|
||||||
|
|
||||||
func TestFlattenDeep(t *testing.T) {
|
func TestFlattenDeep(t *testing.T) {
|
||||||
input := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
|
input := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
|
||||||
expected := []string{"a", "b", "c", "d"}
|
expected := []string{"a", "b", "c", "d"}
|
||||||
@@ -420,6 +428,17 @@ func TestUnion(t *testing.T) {
|
|||||||
assert.Equal([]int{1, 3, 4, 6}, Union(s1))
|
assert.Equal([]int{1, 3, 4, 6}, Union(s1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnionBy(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestUnionBy")
|
||||||
|
|
||||||
|
testFunc := func(i int) int {
|
||||||
|
return i / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
result := UnionBy(testFunc, []int{0, 1, 2, 3, 4, 5}, []int{0, 2, 10})
|
||||||
|
assert.Equal(result, []int{0, 2, 4, 10})
|
||||||
|
}
|
||||||
|
|
||||||
func TestIntersection(t *testing.T) {
|
func TestIntersection(t *testing.T) {
|
||||||
s1 := []int{1, 2, 2, 3}
|
s1 := []int{1, 2, 2, 3}
|
||||||
s2 := []int{1, 2, 3, 4}
|
s2 := []int{1, 2, 3, 4}
|
||||||
@@ -601,3 +620,48 @@ func TestToSlicePointer(t *testing.T) {
|
|||||||
assert.Equal([]*string{&str1}, ToSlicePointer(str1))
|
assert.Equal([]*string{&str1}, ToSlicePointer(str1))
|
||||||
assert.Equal([]*string{&str1, &str2}, ToSlicePointer(str1, str2))
|
assert.Equal([]*string{&str1, &str2}, ToSlicePointer(str1, str2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAppendIfAbsent(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestAppendIfAbsent")
|
||||||
|
|
||||||
|
str1 := []string{"a", "b"}
|
||||||
|
assert.Equal([]string{"a", "b"}, AppendIfAbsent(str1, "a"))
|
||||||
|
assert.Equal([]string{"a", "b", "c"}, AppendIfAbsent(str1, "c"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReplace(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestReplace")
|
||||||
|
|
||||||
|
strs := []string{"a", "b", "a", "c", "d", "a"}
|
||||||
|
|
||||||
|
assert.Equal([]string{"a", "b", "a", "c", "d", "a"}, Replace(strs, "a", "x", 0))
|
||||||
|
assert.Equal([]string{"x", "b", "a", "c", "d", "a"}, Replace(strs, "a", "x", 1))
|
||||||
|
assert.Equal([]string{"x", "b", "x", "c", "d", "a"}, Replace(strs, "a", "x", 2))
|
||||||
|
assert.Equal([]string{"x", "b", "x", "c", "d", "x"}, Replace(strs, "a", "x", 3))
|
||||||
|
assert.Equal([]string{"x", "b", "x", "c", "d", "x"}, Replace(strs, "a", "x", 4))
|
||||||
|
|
||||||
|
assert.Equal([]string{"x", "b", "x", "c", "d", "x"}, Replace(strs, "a", "x", -1))
|
||||||
|
assert.Equal([]string{"x", "b", "x", "c", "d", "x"}, Replace(strs, "a", "x", -2))
|
||||||
|
|
||||||
|
assert.Equal([]string{"a", "b", "a", "c", "d", "a"}, Replace(strs, "x", "y", 1))
|
||||||
|
assert.Equal([]string{"a", "b", "a", "c", "d", "a"}, Replace(strs, "x", "y", -1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReplaceAll(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestReplaceAll")
|
||||||
|
|
||||||
|
strs := []string{"a", "b", "a", "c", "d", "a"}
|
||||||
|
|
||||||
|
assert.Equal([]string{"x", "b", "x", "c", "d", "x"}, ReplaceAll(strs, "a", "x"))
|
||||||
|
assert.Equal([]string{"a", "b", "a", "c", "d", "a"}, ReplaceAll(strs, "e", "x"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKeyBy(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestKeyBy")
|
||||||
|
|
||||||
|
result := KeyBy([]string{"a", "ab", "abc"}, func(str string) int {
|
||||||
|
return len(str)
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(result, map[int]string{1: "a", 2: "ab", 3: "abc"})
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func CamelCase(s string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
res := ""
|
result := ""
|
||||||
blankSpace := " "
|
blankSpace := " "
|
||||||
regex, _ := regexp.Compile("[-_&]+")
|
regex, _ := regexp.Compile("[-_&]+")
|
||||||
ss := regex.ReplaceAllString(s, blankSpace)
|
ss := regex.ReplaceAllString(s, blankSpace)
|
||||||
@@ -26,13 +26,13 @@ func CamelCase(s string) string {
|
|||||||
if vv[i] >= 65 && vv[i] <= 96 {
|
if vv[i] >= 65 && vv[i] <= 96 {
|
||||||
vv[0] += 32
|
vv[0] += 32
|
||||||
}
|
}
|
||||||
res += string(vv)
|
result += string(vv)
|
||||||
} else {
|
} else {
|
||||||
res += Capitalize(v)
|
result += Capitalize(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Capitalize converts the first character of a string to upper case and the remaining to lower case.
|
// Capitalize converts the first character of a string to upper case and the remaining to lower case.
|
||||||
@@ -126,15 +126,15 @@ func KebabCase(s string) string {
|
|||||||
match := regex.ReplaceAllString(s, blankSpace)
|
match := regex.ReplaceAllString(s, blankSpace)
|
||||||
rs := strings.Split(match, blankSpace)
|
rs := strings.Split(match, blankSpace)
|
||||||
|
|
||||||
var res []string
|
var result []string
|
||||||
for _, v := range rs {
|
for _, v := range rs {
|
||||||
splitWords := splitWordsToLower(v)
|
splitWords := splitWordsToLower(v)
|
||||||
if len(splitWords) > 0 {
|
if len(splitWords) > 0 {
|
||||||
res = append(res, splitWords...)
|
result = append(result, splitWords...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Join(res, "-")
|
return strings.Join(result, "-")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SnakeCase covert string to snake_case
|
// SnakeCase covert string to snake_case
|
||||||
@@ -148,15 +148,15 @@ func SnakeCase(s string) string {
|
|||||||
match := regex.ReplaceAllString(s, blankSpace)
|
match := regex.ReplaceAllString(s, blankSpace)
|
||||||
rs := strings.Split(match, blankSpace)
|
rs := strings.Split(match, blankSpace)
|
||||||
|
|
||||||
var res []string
|
var result []string
|
||||||
for _, v := range rs {
|
for _, v := range rs {
|
||||||
splitWords := splitWordsToLower(v)
|
splitWords := splitWordsToLower(v)
|
||||||
if len(splitWords) > 0 {
|
if len(splitWords) > 0 {
|
||||||
res = append(res, splitWords...)
|
result = append(result, splitWords...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Join(res, "_")
|
return strings.Join(result, "_")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before create substring in source string before position when char first appear
|
// Before create substring in source string before position when char first appear
|
||||||
@@ -208,8 +208,8 @@ func IsString(v any) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReverseStr return string whose char order is reversed to the given string
|
// Reverse return string whose char order is reversed to the given string
|
||||||
func ReverseStr(s string) string {
|
func Reverse(s string) string {
|
||||||
r := []rune(s)
|
r := []rune(s)
|
||||||
for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
|
for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
|
||||||
r[i], r[j] = r[j], r[i]
|
r[i], r[j] = r[j], r[i]
|
||||||
|
|||||||
@@ -4,37 +4,37 @@ import "strings"
|
|||||||
|
|
||||||
// splitWordsToLower split a string into worlds by uppercase char
|
// splitWordsToLower split a string into worlds by uppercase char
|
||||||
func splitWordsToLower(s string) []string {
|
func splitWordsToLower(s string) []string {
|
||||||
var res []string
|
var result []string
|
||||||
|
|
||||||
upperIndexes := upperIndex(s)
|
upperIndexes := upperIndex(s)
|
||||||
l := len(upperIndexes)
|
l := len(upperIndexes)
|
||||||
if upperIndexes == nil || l == 0 {
|
if upperIndexes == nil || l == 0 {
|
||||||
if s != "" {
|
if s != "" {
|
||||||
res = append(res, s)
|
result = append(result, s)
|
||||||
}
|
}
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
if i < l-1 {
|
if i < l-1 {
|
||||||
res = append(res, strings.ToLower(s[upperIndexes[i]:upperIndexes[i+1]]))
|
result = append(result, strings.ToLower(s[upperIndexes[i]:upperIndexes[i+1]]))
|
||||||
} else {
|
} else {
|
||||||
res = append(res, strings.ToLower(s[upperIndexes[i]:]))
|
result = append(result, strings.ToLower(s[upperIndexes[i]:]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// upperIndex get a int slice which elements are all the uppercase char index of a string
|
// upperIndex get a int slice which elements are all the uppercase char index of a string
|
||||||
func upperIndex(s string) []int {
|
func upperIndex(s string) []int {
|
||||||
var res []int
|
var result []int
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
if 64 < s[i] && s[i] < 91 {
|
if 64 < s[i] && s[i] < 91 {
|
||||||
res = append(res, i)
|
result = append(result, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(s) > 0 && res != nil && res[0] != 0 {
|
if len(s) > 0 && result != nil && result[0] != 0 {
|
||||||
res = append([]int{0}, res...)
|
result = append([]int{0}, result...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,11 +143,11 @@ func TestIsString(t *testing.T) {
|
|||||||
assert.Equal(false, IsString([]string{}))
|
assert.Equal(false, IsString([]string{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReverseStr(t *testing.T) {
|
func TestReverse(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestReverseStr")
|
assert := internal.NewAssert(t, "TestReverse")
|
||||||
|
|
||||||
assert.Equal("cba", ReverseStr("abc"))
|
assert.Equal("cba", Reverse("abc"))
|
||||||
assert.Equal("54321", ReverseStr("12345"))
|
assert.Equal("54321", Reverse("12345"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWrap(t *testing.T) {
|
func TestWrap(t *testing.T) {
|
||||||
|
|||||||
@@ -70,3 +70,9 @@ func ExecCommand(command string) (stdout, stderr string, err error) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetOsBits get this system bits 32bit or 64bit
|
||||||
|
// return bit int (32/64)
|
||||||
|
func GetOsBits() int {
|
||||||
|
return 32 << (^uint(0) >> 63)
|
||||||
|
}
|
||||||
|
|||||||
@@ -60,3 +60,13 @@ func TestExecCommand(t *testing.T) {
|
|||||||
assert.IsNotNil(err)
|
assert.IsNotNil(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetOsBits(t *testing.T) {
|
||||||
|
osBits := GetOsBits()
|
||||||
|
switch osBits {
|
||||||
|
case 32, 64:
|
||||||
|
t.Logf("os is %d", osBits)
|
||||||
|
default:
|
||||||
|
t.Error("os is not 32 or 64 bits")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -253,3 +254,32 @@ func IsWeakPassword(password string) bool {
|
|||||||
|
|
||||||
return (num || letter) && !special
|
return (num || letter) && !special
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsZeroValue checks if value is a zero value
|
||||||
|
func IsZeroValue(value any) bool {
|
||||||
|
if value == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
rv := reflect.ValueOf(value)
|
||||||
|
if !rv.IsValid() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
return rv.Len() == 0
|
||||||
|
case reflect.Bool:
|
||||||
|
return !rv.Bool()
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return rv.Int() == 0
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return rv.Uint() == 0
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return rv.Float() == 0
|
||||||
|
case reflect.Ptr, reflect.Chan, reflect.Func, reflect.Interface, reflect.Slice, reflect.Map:
|
||||||
|
return rv.IsNil()
|
||||||
|
}
|
||||||
|
|
||||||
|
return reflect.DeepEqual(rv.Interface(), reflect.Zero(rv.Type()).Interface())
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package validator
|
package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
)
|
)
|
||||||
@@ -279,3 +281,110 @@ func TestIsWeakPassword(t *testing.T) {
|
|||||||
assert.Equal(true, IsWeakPassword("abcABC123"))
|
assert.Equal(true, IsWeakPassword("abcABC123"))
|
||||||
assert.Equal(false, IsWeakPassword("abc123@#$"))
|
assert.Equal(false, IsWeakPassword("abc123@#$"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsZeroValue(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIsZeroValue")
|
||||||
|
|
||||||
|
var (
|
||||||
|
zeroPtr *string
|
||||||
|
zeroSlice []int
|
||||||
|
zeroFunc func() string
|
||||||
|
zeroMap map[string]string
|
||||||
|
nilIface interface{}
|
||||||
|
zeroIface fmt.Formatter
|
||||||
|
)
|
||||||
|
zeroValues := []interface{}{
|
||||||
|
nil,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
int8(0),
|
||||||
|
int16(0),
|
||||||
|
int32(0),
|
||||||
|
int64(0),
|
||||||
|
uint(0),
|
||||||
|
uint8(0),
|
||||||
|
uint16(0),
|
||||||
|
uint32(0),
|
||||||
|
uint64(0),
|
||||||
|
|
||||||
|
0.0,
|
||||||
|
float32(0.0),
|
||||||
|
float64(0.0),
|
||||||
|
|
||||||
|
"",
|
||||||
|
|
||||||
|
// func
|
||||||
|
zeroFunc,
|
||||||
|
|
||||||
|
// array / slice
|
||||||
|
[0]int{},
|
||||||
|
zeroSlice,
|
||||||
|
|
||||||
|
// map
|
||||||
|
zeroMap,
|
||||||
|
|
||||||
|
// interface
|
||||||
|
nilIface,
|
||||||
|
zeroIface,
|
||||||
|
|
||||||
|
// pointer
|
||||||
|
zeroPtr,
|
||||||
|
|
||||||
|
// struct
|
||||||
|
time.Time{},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, value := range zeroValues {
|
||||||
|
assert.Equal(true, IsZeroValue(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
var nonZeroIface fmt.Stringer = time.Now()
|
||||||
|
|
||||||
|
nonZeroValues := []interface{}{
|
||||||
|
// bool
|
||||||
|
true,
|
||||||
|
|
||||||
|
// int
|
||||||
|
1,
|
||||||
|
int8(1),
|
||||||
|
int16(1),
|
||||||
|
int32(1),
|
||||||
|
int64(1),
|
||||||
|
uint8(1),
|
||||||
|
uint16(1),
|
||||||
|
uint32(1),
|
||||||
|
uint64(1),
|
||||||
|
|
||||||
|
// float
|
||||||
|
1.0,
|
||||||
|
float32(1.0),
|
||||||
|
float64(1.0),
|
||||||
|
|
||||||
|
// string
|
||||||
|
"test",
|
||||||
|
|
||||||
|
// func
|
||||||
|
time.Now,
|
||||||
|
|
||||||
|
// array / slice
|
||||||
|
[]int{},
|
||||||
|
[]int{42},
|
||||||
|
[1]int{42},
|
||||||
|
|
||||||
|
// map
|
||||||
|
make(map[string]string, 1),
|
||||||
|
|
||||||
|
// interface
|
||||||
|
nonZeroIface,
|
||||||
|
|
||||||
|
// pointer
|
||||||
|
&nonZeroIface,
|
||||||
|
|
||||||
|
// struct
|
||||||
|
time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, value := range nonZeroValues {
|
||||||
|
assert.Equal(false, IsZeroValue(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user