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

Compare commits

...

21 Commits

Author SHA1 Message Date
dudaodong
66dfd9c4fd refactor: refact Comma function 2024-01-25 16:45:17 +08:00
dudaodong
be62aaac9b refactor: update signature of WriteMapsToCsv function
g
2024-01-24 11:54:42 +08:00
dudaodong
e0c9ccbce3 doc: add DeleteRange 2024-01-23 17:27:28 +08:00
dudaodong
d2d1e5a055 feat: refact DeleteAt and add DeleteRange function 2024-01-22 15:34:35 +08:00
dudaodong
bbc58c7e46 fix: fix the map key order issue of WriteMapsToCsv 2024-01-22 11:10:02 +08:00
dudaodong
ac2ecceaec refactor: refact reduce function 2024-01-03 10:46:28 +08:00
dudaodong
a06bb8ee6a fix: fix unit test for WriteMapsToCsv 2024-01-01 18:32:41 +08:00
dudaodong
27b5702fd3 fix: fix unit test for WriteMapsToCsv 2024-01-01 17:51:32 +08:00
dudaodong
b2c3fa0ab8 fix: fix golint issue 2024-01-01 17:43:11 +08:00
dudaodong
4afc838937 doc: add doc for WriteMapsToCsv 2024-01-01 17:40:32 +08:00
colorcrow
3482f80d1c WriteCsvFile自定义分割符,增加map切片写入csv,增加追踪函数运行时间的函数 (#157)
* WriteCsvFile now support custom delimiter,Add write map slice to csv

* add trace func time
2024-01-01 16:54:04 +08:00
suacrbah
565f2893b9 feat: add support for seeking and read one line at a time from file (#158)
* feat: add support for seeking and read one line at a time from file

* feat: add support for calculating folder total size

---------

Co-authored-by: Suacrbah <5744580+Suacrbah@user.noreply.gitee.com>
2024-01-01 16:50:54 +08:00
dudaodong
1b1b10d0ee merge main branch 2023-12-29 10:17:04 +08:00
Gregory Koganovskiy
c5c3888ffc Fix typos in README (#154) 2023-12-29 10:12:29 +08:00
duckjiangwei
11214986cc add new func & docs error repair (#153)
* feat: add method IsTargetType()

* docs:document error repair
2023-12-28 10:27:32 +08:00
dudaodong
0bc7b83e59 Merge branch 'main' into v2 2023-12-21 10:03:35 +08:00
duckjiangwei
6225418074 improvement:optimize bubble sort (#152) 2023-12-21 10:02:23 +08:00
dudaodong
ddd265de78 fix: fix comment error 2023-12-19 15:36:07 +08:00
dudaodong
80e48f06ca refactor: rename lancetconstraints package name to constraints 2023-12-16 19:29:06 +08:00
dudaodong
0b976e9a4c fix: fix failed unit test 2023-12-11 15:45:02 +08:00
dudaodong
96320069f4 doc: update for release v2.2.8 2023-12-11 15:30:33 +08:00
45 changed files with 952 additions and 414 deletions

113
README.md
View File

@@ -32,7 +32,7 @@
### Note: ### Note:
1. <b>For users who use go1.18 and above, it is recommended to install lancet v2.x.x. Cause in v2.x.x all functions was rewriten 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 in v2.x.x all functions were rewritten 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
@@ -201,10 +201,10 @@ import "github.com/duke-git/lancet/v2/concurrency"
- **<big>OrDone</big>** : read a channel into another channel, will close until cancel context. - **<big>OrDone</big>** : read a channel into another channel, will close until cancel context.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/concurrency.md#OrDone)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/concurrency.md#OrDone)]
[[play](https://go.dev/play/p/lm_GoS6aDjo)] [[play](https://go.dev/play/p/lm_GoS6aDjo)]
- **<big>Repeat</big>** : create channel, put values into the channel repeatly until cancel the context. - **<big>Repeat</big>** : create channel, put values into the channel repeatedly until cancel the context.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/concurrency.md#Repeat)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/concurrency.md#Repeat)]
[[play](https://go.dev/play/p/k5N_ALVmYjE)] [[play](https://go.dev/play/p/k5N_ALVmYjE)]
- **<big>RepeatFn</big>** : create a channel, excutes fn repeatly, and put the result into the channel, until close context. - **<big>RepeatFn</big>** : create a channel, executes fn repeatedly, and put the result into the channel, until close context.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/concurrency.md#RepeatFn)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/concurrency.md#RepeatFn)]
[[play](https://go.dev/play/p/4J1zAWttP85)] [[play](https://go.dev/play/p/4J1zAWttP85)]
- **<big>Take</big>** : create a channel whose values are taken from another channel with limit number. - **<big>Take</big>** : create a channel whose values are taken from another channel with limit number.
@@ -247,7 +247,7 @@ import "github.com/duke-git/lancet/v2/condition"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/condition.md#TernaryOperator)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/condition.md#TernaryOperator)]
[[play](https://go.dev/play/p/ElllPZY0guT)] [[play](https://go.dev/play/p/ElllPZY0guT)]
<h3 id="convertor"> 5. Convertor package contains some functions for data convertion. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a> </h3> <h3 id="convertor"> 5. Convertor package contains some functions for data conversion. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a> </h3>
```go ```go
import "github.com/duke-git/lancet/v2/convertor" import "github.com/duke-git/lancet/v2/convertor"
@@ -596,7 +596,7 @@ import "github.com/duke-git/lancet/v2/datetime"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#TimestampNano)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#TimestampNano)]
[[play](https://go.dev/play/p/A9Oq_COrcCF)] [[play](https://go.dev/play/p/A9Oq_COrcCF)]
<h3 id="datastructure"> 8. Datastructure package constains some common data structure. eg. list, linklist, stack, queue, set, tree, graph. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3> <h3 id="datastructure"> 8. Datastructure package contains some common data structure. eg. list, linklist, stack, queue, set, tree, graph. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go ```go
import list "github.com/duke-git/lancet/v2/datastructure/list" import list "github.com/duke-git/lancet/v2/datastructure/list"
@@ -706,6 +706,8 @@ import "github.com/duke-git/lancet/v2/fileutil"
[[play](https://go.dev/play/p/OExTkhGEd3_u)] [[play](https://go.dev/play/p/OExTkhGEd3_u)]
- **<big>WriteCsvFile</big>** : write content to target csv file. - **<big>WriteCsvFile</big>** : write content to target csv file.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteCsvFile)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteCsvFile)]
- **<big>WriteMapsToCsv</big>** : write slice of map to csv file.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteMapsToCsv)]
[[play](https://go.dev/play/p/dAXm58Q5U1o)] [[play](https://go.dev/play/p/dAXm58Q5U1o)]
- **<big>WriteBytesToFile</big>** : write bytes to target file. - **<big>WriteBytesToFile</big>** : write bytes to target file.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteBytesToFile)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteBytesToFile)]
@@ -754,10 +756,10 @@ import "github.com/duke-git/lancet/v2/function"
#### Function list: #### Function list:
- **<big>After</big>** : return a function that invokes passed funcation once the returned function is called more than n times. - **<big>After</big>** : return a function that invokes passed function once the returned function is called more than n times.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#After)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#After)]
[[play](https://go.dev/play/p/eRD5k2vzUVX)] [[play](https://go.dev/play/p/eRD5k2vzUVX)]
- **<big>Before</big>** : return a function that invokes passed funcation once the returned function is called less than n times - **<big>Before</big>** : return a function that invokes passed function once the returned function is called less than n times
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Before)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Before)]
[[play](https://go.dev/play/p/0HqUDIFZ3IL)] [[play](https://go.dev/play/p/0HqUDIFZ3IL)]
- **<big>CurryFn</big>** : make a curry function. - **<big>CurryFn</big>** : make a curry function.
@@ -778,7 +780,7 @@ import "github.com/duke-git/lancet/v2/function"
- **<big>Pipeline</big>** : takes a list of functions and returns a function whose param will be passed into the functions one by one. - **<big>Pipeline</big>** : takes a list of functions and returns a function whose param will be passed into the functions one by one.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Pipeline)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Pipeline)]
[[play](https://go.dev/play/p/mPdUVvj6HD6)] [[play](https://go.dev/play/p/mPdUVvj6HD6)]
- **<big>Watcher</big>** : Watcher is used for record code excution time. can start/stop/reset the watch timer. get the elapsed time of function execution. - **<big>Watcher</big>** : Watcher is used for record code execution time. can start/stop/reset the watch timer. get the elapsed time of function execution.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Watcher)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Watcher)]
[[play](https://go.dev/play/p/l2yrOpCLd1I)] [[play](https://go.dev/play/p/l2yrOpCLd1I)]
@@ -793,7 +795,7 @@ import "github.com/duke-git/lancet/v2/maputil"
- **<big>MapTo</big>** : quick map any value to struct or any base type. - **<big>MapTo</big>** : quick map any value to struct or any base type.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#MapTo)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#MapTo)]
[[play](https://go.dev/play/p/4K7KBEPgS5M)] [[play](https://go.dev/play/p/4K7KBEPgS5M)]
- **<big>ForEach</big>** : executes iteratee funcation for every key and value pair in map. - **<big>ForEach</big>** : executes iteratee function for every key and value pair in map.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#ForEach)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#ForEach)]
[[play](https://go.dev/play/p/OaThj6iNVXK)] [[play](https://go.dev/play/p/OaThj6iNVXK)]
- **<big>Filter</big>** : iterates over map, return a new map contains all key and value pairs pass the predicate function. - **<big>Filter</big>** : iterates over map, return a new map contains all key and value pairs pass the predicate function.
@@ -811,7 +813,7 @@ import "github.com/duke-git/lancet/v2/maputil"
- **<big>OmitByKeys</big>** : the opposite of FilterByKeys, extracts all the map elements which keys are not omitted. - **<big>OmitByKeys</big>** : the opposite of FilterByKeys, extracts all the map elements which keys are not omitted.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#OmitByKeys)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#OmitByKeys)]
[[play](https://go.dev/play/p/jXGrWDBfSRp)] [[play](https://go.dev/play/p/jXGrWDBfSRp)]
- **<big>OmitByValues</big>** : the opposite of FilterByValues. remov all elements whose value are in the give slice. - **<big>OmitByValues</big>** : the opposite of FilterByValues. remove all elements whose value are in the give slice.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#OmitByValues)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#OmitByValues)]
[[play](https://go.dev/play/p/XB7Y10uw20_U)] [[play](https://go.dev/play/p/XB7Y10uw20_U)]
- **<big>Intersect</big>** : iterates over maps, return a new map of key and value pairs in all given maps. - **<big>Intersect</big>** : iterates over maps, return a new map of key and value pairs in all given maps.
@@ -961,7 +963,7 @@ import "github.com/duke-git/lancet/v2/mathutil"
- **<big>Sum</big>** : return sum of passed numbers. - **<big>Sum</big>** : return sum of passed numbers.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/mathutil.md#Sum)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/mathutil.md#Sum)]
[[play](https://go.dev/play/p/1To2ImAMJA7)] [[play](https://go.dev/play/p/1To2ImAMJA7)]
- **<big>Abs</big>** : returns the absolute value of param nubmer. - **<big>Abs</big>** : returns the absolute value of param number.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/mathutil.md#Sum)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/mathutil.md#Sum)]
[[play](https://go.dev/play/p/fsyBh1Os-1d)] [[play](https://go.dev/play/p/fsyBh1Os-1d)]
@@ -1012,7 +1014,7 @@ import "github.com/duke-git/lancet/v2/netutil"
- **<big>DecodeResponse</big>** : decode http response into target object. - **<big>DecodeResponse</big>** : decode http response into target object.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/netutil.md#DecodeResponse)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/netutil.md#DecodeResponse)]
[[play](https://go.dev/play/p/jUSgynekH7G)] [[play](https://go.dev/play/p/jUSgynekH7G)]
- **<big>StructToUrlValues</big>** : convert struct to url valuse. - **<big>StructToUrlValues</big>** : convert struct to url values.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/netutil.md#StructToUrlValues)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/netutil.md#StructToUrlValues)]
[[play](https://go.dev/play/p/pFqMkM40w9z)] [[play](https://go.dev/play/p/pFqMkM40w9z)]
- **<big>HttpGet<sup>deprecated</sup></big>** : send http get request. - **<big>HttpGet<sup>deprecated</sup></big>** : send http get request.
@@ -1099,10 +1101,16 @@ import "github.com/duke-git/lancet/v2/random"
[[play](https://go.dev/play/p/uBkRSOz73Ec)] [[play](https://go.dev/play/p/uBkRSOz73Ec)]
- **<big>RandSymbolChar</big>** : Generate a random symbol char of specified length. - **<big>RandSymbolChar</big>** : Generate a random symbol char of specified length.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/random.md#RandSymbolChar)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/random.md#RandSymbolChar)]
[[play](https://go.dev/play/p/Im6ZJxAykOm)]
- **<big>RandFloat</big>** : Generate a random float64 number between [min, max) with specific precision. - **<big>RandFloat</big>** : Generate a random float64 number between [min, max) with specific precision.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/random.md#RandFloat)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/random.md#RandFloat)]
[[play](https://go.dev/play/p/zbD_tuobJtr)]
- **<big>RandFloats</big>** : Generate a slice of random float64 numbers of length n that do not repeat. - **<big>RandFloats</big>** : Generate a slice of random float64 numbers of length n that do not repeat.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/random.md#RandFloats)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/random.md#RandFloats)]
[[play](https://go.dev/play/p/I3yndUQ-rhh)]
<h3 id="retry"> 17. Retry package is for executing a function repeatedly until it was successful or canceled by the context. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3> <h3 id="retry"> 17. Retry package is for executing a function repeatedly until it was successful or canceled by the context. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
@@ -1151,7 +1159,7 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>Chunk</big>** : creates a slice of elements split into groups the length of size. - **<big>Chunk</big>** : creates a slice of elements split into groups the length of size.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Chunk)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Chunk)]
[[play](https://go.dev/play/p/b4Pou5j2L_C)] [[play](https://go.dev/play/p/b4Pou5j2L_C)]
- **<big>Compact</big>** : creates an slice with all falsey values removed. The values false, nil, 0, and "" are falsey. - **<big>Compact</big>** : creates an slice with all falsy values removed. The values false, nil, 0, and "" are falsy.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Compact)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Compact)]
[[play](https://go.dev/play/p/pO5AnxEr3TK)] [[play](https://go.dev/play/p/pO5AnxEr3TK)]
- **<big>Concat</big>** : creates a new slice concatenating slice with any additional slices. - **<big>Concat</big>** : creates a new slice concatenating slice with any additional slices.
@@ -1172,9 +1180,10 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>DifferenceWith</big>** : accepts comparator which is invoked to compare elements of slice to values. - **<big>DifferenceWith</big>** : accepts comparator which is invoked to compare elements of slice to values.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#DifferenceWith)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#DifferenceWith)]
[[play](https://go.dev/play/p/v2U2deugKuV)] [[play](https://go.dev/play/p/v2U2deugKuV)]
- **<big>DeleteAt</big>** : delete the element of slice from specific start index to end index - 1. - **<big>DeleteAt</big>** : delete the element of slice at index.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#DeleteAt)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#DeleteAt)]
[[play](https://go.dev/play/p/pJ-d6MUWcvK)] - **<big>DeleteRange</big>** : delete the element of slice from start index to end indexexclude).
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#DeleteRange)]
- **<big>Drop</big>** : drop n elements from the start of a slice. - **<big>Drop</big>** : drop n elements from the start of a slice.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Drop)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Drop)]
[[play](https://go.dev/play/p/jnPO2yQsT8H)] [[play](https://go.dev/play/p/jnPO2yQsT8H)]
@@ -1232,7 +1241,7 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>GroupBy</big>** : iterate over elements of the slice, each element will be group by criteria, returns two slices. - **<big>GroupBy</big>** : iterate over elements of the slice, each element will be group by criteria, returns two slices.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#GroupBy)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#GroupBy)]
[[play](https://go.dev/play/p/QVkPxzPR0iA)] [[play](https://go.dev/play/p/QVkPxzPR0iA)]
- **<big>GroupWith</big>** : return a map composed of keys generated from the resultults of running each element of slice thru iteratee. - **<big>GroupWith</big>** : return a map composed of keys generated from the results of running each element of slice thru iteratee.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#GroupWith)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#GroupWith)]
[[play](https://go.dev/play/p/ApCvMNTLO8a)] [[play](https://go.dev/play/p/ApCvMNTLO8a)]
- **<big>IntSlice<sup>deprecated</sup></big>** : convert param to int slice. - **<big>IntSlice<sup>deprecated</sup></big>** : convert param to int slice.
@@ -1348,6 +1357,8 @@ import "github.com/duke-git/lancet/v2/slice"
[[play](https://go.dev/play/p/lkQ3Ri2NQhV)] [[play](https://go.dev/play/p/lkQ3Ri2NQhV)]
- **<big>Random</big>** : get a random item of slice, return its index, when slice is empty, return -1. - **<big>Random</big>** : get a random item of slice, return its index, when slice is empty, return -1.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Random)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Random)]
[[play](https://go.dev/play/p/UzpGQptWppw)]
<h3 id="stream"> 19. Stream package implements a sequence of elements supporting sequential and operations. this package is an experiment to explore if stream in go can work as the way java does. its function is very limited. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3> <h3 id="stream"> 19. Stream package implements a sequence of elements supporting sequential and operations. this package is an experiment to explore if stream in go can work as the way java does. its function is very limited. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
@@ -1369,7 +1380,7 @@ import "github.com/duke-git/lancet/v2/stream"
- **<big>FromRange</big>** : creates a number stream from start to end. both start and end are included. [start, end] - **<big>FromRange</big>** : creates a number stream from start to end. both start and end are included. [start, end]
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#FromRange)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#FromRange)]
[[play](https://go.dev/play/p/9Ex1-zcg-B-)] [[play](https://go.dev/play/p/9Ex1-zcg-B-)]
- **<big>Generate</big>** : creates a stream where each element is generated by the provided generater function. - **<big>Generate</big>** : creates a stream where each element is generated by the provided generator function.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#Generate)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#Generate)]
[[play](https://go.dev/play/p/rkOWL1yA3j9)] [[play](https://go.dev/play/p/rkOWL1yA3j9)]
- **<big>Concat</big>** : creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream. - **<big>Concat</big>** : creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream.
@@ -1414,10 +1425,10 @@ import "github.com/duke-git/lancet/v2/stream"
- **<big>FindLast</big>** : returns the last element of this stream and true, or zero value and false if the stream is empty. - **<big>FindLast</big>** : returns the last element of this stream and true, or zero value and false if the stream is empty.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#FindLast)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#FindLast)]
[[play](https://go.dev/play/p/WZD2rDAW-2h)] [[play](https://go.dev/play/p/WZD2rDAW-2h)]
- **<big>Max</big>** : returns the maximum element of this stream according to the provided less function. less fuction: a > b - **<big>Max</big>** : returns the maximum element of this stream according to the provided less function. less function: a > b
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#Max)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#Max)]
[[play](https://go.dev/play/p/fm-1KOPtGzn)] [[play](https://go.dev/play/p/fm-1KOPtGzn)]
- **<big>Min</big>** : returns the minimum element of this stream according to the provided less function. less fuction: a < b - **<big>Min</big>** : returns the minimum element of this stream according to the provided less function. less function: a < b
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#Min)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#Min)]
[[play](https://go.dev/play/p/vZfIDgGNRe_0)] [[play](https://go.dev/play/p/vZfIDgGNRe_0)]
- **<big>AllMatch</big>** : returns whether all elements of this stream match the provided predicate. - **<big>AllMatch</big>** : returns whether all elements of this stream match the provided predicate.
@@ -1445,29 +1456,31 @@ import "github.com/duke-git/lancet/v2/structs"
#### Function list: #### Function list:
- **<big>New</big>** : creates a `Struct` instance. - **<big>New</big>** : creates a `Struct` instance.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/structs/struct.md#New)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#New)]
- **<big>ToMap</big>** : converts a valid struct to a map. - **<big>ToMap</big>** : converts a valid struct to a map.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/structs/struct.md#ToMap)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#ToMap)]
- **<big>Fields</big>** : get all fields of a given struct, that the fields are abstract struct field. - **<big>Fields</big>** : get all fields of a given struct, that the fields are abstract struct field.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/structs/struct.md#Fields)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#Fields)]
- **<big>IsStruct</big>** : check if the struct is valid. - **<big>IsStruct</big>** : check if the struct is valid.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/structs/struct.md#IsStruct)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#IsStruct)]
- **<big>Tag</big>** : get a `Tag` of the `Field`, `Tag` is a abstract struct field tag - **<big>Tag</big>** : get a `Tag` of the `Field`, `Tag` is a abstract struct field tag.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/structs/field.md#Tag)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#Tag)]
- **<big>Name</big>** : get the field name. - **<big>Name</big>** : get the field name.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/structs/field.md#Name)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#Name)]
- **<big>Value</big>** : get the `Field` underlying value. - **<big>Value</big>** : get the `Field` underlying value.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/structs/field.md#Value)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#Value)]
- **<big>Kind</big>** : get the field's kind - **<big>Kind</big>** : get the field's kind.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/structs/field.md#Kind)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#Kind)]
- **<big>IsEmbedded</big>** : check if the field is an embedded field. - **<big>IsEmbedded</big>** : check if the field is an embedded field.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/structs/field.md#IsEmbedded)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#IsEmbedded)]
- **<big>IsExported</big>** : check if the field is exporte - **<big>IsExported</big>** : check if the field is exported.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/structs/field.md#IsExported)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#IsExported)]
- **<big>IsZero</big>** : check if the field is zero value - **<big>IsZero</big>** : check if the field is zero value.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/structs/field.md#IsZero)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#IsZero)]
- **<big>IsSlice</big>** : check if the field is a slice - **<big>IsSlice</big>** : check if the field is a slice.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/structs/field.md#IsSlice)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#IsSlice)]
- **<big>IsTargetType</big>** : check if the field is target type.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#IsTargetType)]
<h3 id="strutil"> 21. Strutil package contains some functions to manipulate string. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3> <h3 id="strutil"> 21. Strutil package contains some functions to manipulate string. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
@@ -1636,7 +1649,7 @@ import "github.com/duke-git/lancet/v2/tuple"
#### Function list: #### Function list:
- **<big>Tuple2</big>** : represents a 2 elemnets tuple. - **<big>Tuple2</big>** : represents a 2 elements tuple.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple2)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple2)]
[[play](https://go.dev/play/p/3sHVqBQpLYN)] [[play](https://go.dev/play/p/3sHVqBQpLYN)]
- **<big>Tuple2_Unbox</big>** : returns values in Tuple2. - **<big>Tuple2_Unbox</big>** : returns values in Tuple2.
@@ -1648,7 +1661,7 @@ import "github.com/duke-git/lancet/v2/tuple"
- **<big>Unzip2</big>** : create a group of slice from a slice of Tuple2. - **<big>Unzip2</big>** : create a group of slice from a slice of Tuple2.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip2)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip2)]
[[play](https://go.dev/play/p/KBecr60feXb)] [[play](https://go.dev/play/p/KBecr60feXb)]
- **<big>Tuple3</big>** : represents a 3 elemnets tuple. - **<big>Tuple3</big>** : represents a 3 elements tuple.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple3)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple3)]
[[play](https://go.dev/play/p/FtH2sdCLlCf)] [[play](https://go.dev/play/p/FtH2sdCLlCf)]
- **<big>Tuple3_Unbox</big>** : returns values in Tuple3. - **<big>Tuple3_Unbox</big>** : returns values in Tuple3.
@@ -1660,7 +1673,7 @@ import "github.com/duke-git/lancet/v2/tuple"
- **<big>Unzip3</big>** : create a group of slice from a slice of Tuple3. - **<big>Unzip3</big>** : create a group of slice from a slice of Tuple3.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip3)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip3)]
[[play](https://go.dev/play/p/bba4cpAa7KO)] [[play](https://go.dev/play/p/bba4cpAa7KO)]
- **<big>Tuple4</big>** : represents a 4 elemnets tuple. - **<big>Tuple4</big>** : represents a 4 elements tuple.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple4)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple4)]
[[play](https://go.dev/play/p/D2EqDz096tk)] [[play](https://go.dev/play/p/D2EqDz096tk)]
- **<big>Tuple4_Unbox</big>** : returns values in Tuple4. - **<big>Tuple4_Unbox</big>** : returns values in Tuple4.
@@ -1672,7 +1685,7 @@ import "github.com/duke-git/lancet/v2/tuple"
- **<big>Unzip4</big>** : create a group of slice from a slice of Tuple4. - **<big>Unzip4</big>** : create a group of slice from a slice of Tuple4.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip4)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip4)]
[[play](https://go.dev/play/p/rb8z4gyYSRN)] [[play](https://go.dev/play/p/rb8z4gyYSRN)]
- **<big>Tuple5</big>** : represents a 5 elemnets tuple. - **<big>Tuple5</big>** : represents a 5 elements tuple.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple5)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple5)]
[[play](https://go.dev/play/p/2WndmVxPg-r)] [[play](https://go.dev/play/p/2WndmVxPg-r)]
- **<big>Tuple5_Unbox</big>** : returns values in Tuple4. - **<big>Tuple5_Unbox</big>** : returns values in Tuple4.
@@ -1684,7 +1697,7 @@ import "github.com/duke-git/lancet/v2/tuple"
- **<big>Unzip5</big>** : create a group of slice from a slice of Tuple5. - **<big>Unzip5</big>** : create a group of slice from a slice of Tuple5.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip5)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip5)]
[[play](https://go.dev/play/p/gyl6vKfhqPb)] [[play](https://go.dev/play/p/gyl6vKfhqPb)]
- **<big>Tuple6</big>** : represents a 6 elemnets tuple. - **<big>Tuple6</big>** : represents a 6 elements tuple.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple6)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple6)]
[[play](https://go.dev/play/p/VjqcCwEJZbs)] [[play](https://go.dev/play/p/VjqcCwEJZbs)]
- **<big>Tuple6_Unbox</big>** : returns values in Tuple6. - **<big>Tuple6_Unbox</big>** : returns values in Tuple6.
@@ -1696,7 +1709,7 @@ import "github.com/duke-git/lancet/v2/tuple"
- **<big>Unzip6</big>** : create a group of slice from a slice of Tuple6. - **<big>Unzip6</big>** : create a group of slice from a slice of Tuple6.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip6)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip6)]
[[play](https://go.dev/play/p/l41XFqCyh5E)] [[play](https://go.dev/play/p/l41XFqCyh5E)]
- **<big>Tuple7</big>** : represents a 7 elemnets tuple. - **<big>Tuple7</big>** : represents a 7 elements tuple.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple7)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple7)]
[[play](https://go.dev/play/p/dzAgv_Ezub9)] [[play](https://go.dev/play/p/dzAgv_Ezub9)]
- **<big>Tuple7_Unbox</big>** : returns values in Tuple7. - **<big>Tuple7_Unbox</big>** : returns values in Tuple7.
@@ -1708,7 +1721,7 @@ import "github.com/duke-git/lancet/v2/tuple"
- **<big>Unzip7</big>** : create a group of slice from a slice of Tuple7. - **<big>Unzip7</big>** : create a group of slice from a slice of Tuple7.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip7)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip7)]
[[play](https://go.dev/play/p/hws_P1Fr2j3)] [[play](https://go.dev/play/p/hws_P1Fr2j3)]
- **<big>Tuple8</big>** : represents a 8 elemnets tuple. - **<big>Tuple8</big>** : represents a 8 elements tuple.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple8)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple8)]
[[play](https://go.dev/play/p/YA9S0rz3dRz)] [[play](https://go.dev/play/p/YA9S0rz3dRz)]
- **<big>Tuple8_Unbox</big>** : returns values in Tuple8. - **<big>Tuple8_Unbox</big>** : returns values in Tuple8.
@@ -1720,7 +1733,7 @@ import "github.com/duke-git/lancet/v2/tuple"
- **<big>Unzip8</big>** : create a group of slice from a slice of Tuple8. - **<big>Unzip8</big>** : create a group of slice from a slice of Tuple8.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip8)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip8)]
[[play](https://go.dev/play/p/1SndOwGsZB4)] [[play](https://go.dev/play/p/1SndOwGsZB4)]
- **<big>Tuple9</big>** : represents a 9 elemnets tuple. - **<big>Tuple9</big>** : represents a 9 elements tuple.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple9)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple9)]
[[play](https://go.dev/play/p/yS2NGGtZpQr)] [[play](https://go.dev/play/p/yS2NGGtZpQr)]
- **<big>Tuple9_Unbox</big>** : returns values in Tuple9. - **<big>Tuple9_Unbox</big>** : returns values in Tuple9.
@@ -1732,7 +1745,7 @@ import "github.com/duke-git/lancet/v2/tuple"
- **<big>Unzip9</big>** : create a group of slice from a slice of Tuple9. - **<big>Unzip9</big>** : create a group of slice from a slice of Tuple9.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip9)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip9)]
[[play](https://go.dev/play/p/91-BU_KURSA)] [[play](https://go.dev/play/p/91-BU_KURSA)]
- **<big>Tuple10</big>** : represents a 10 elemnets tuple. - **<big>Tuple10</big>** : represents a 10 elements tuple.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple10)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Tuple10)]
[[play](https://go.dev/play/p/799qqZg0hUv)] [[play](https://go.dev/play/p/799qqZg0hUv)]
- **<big>Tuple10_Unbox</big>** : returns values in Tuple10. - **<big>Tuple10_Unbox</big>** : returns values in Tuple10.
@@ -1864,19 +1877,19 @@ import "github.com/duke-git/lancet/v2/validator"
- **<big>IsJWT</big>** : check if a give string is a valid JSON Web Token (JWT). - **<big>IsJWT</big>** : check if a give string is a valid JSON Web Token (JWT).
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsJWT)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsJWT)]
[[play](https://go.dev/play/p/R6Op7heJbKI)] [[play](https://go.dev/play/p/R6Op7heJbKI)]
- **<big>IsVisa</big>** : check if a give string is a valid visa card nubmer or not. - **<big>IsVisa</big>** : check if a give string is a valid visa card number or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsVisa)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsVisa)]
[[play](https://go.dev/play/p/SdS2keOyJsl)] [[play](https://go.dev/play/p/SdS2keOyJsl)]
- **<big>IsMasterCard</big>** : check if a give string is a valid master card nubmer or not. - **<big>IsMasterCard</big>** : check if a give string is a valid master card number or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsMasterCard)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsMasterCard)]
[[play](https://go.dev/play/p/CwWBFRrG27b)] [[play](https://go.dev/play/p/CwWBFRrG27b)]
- **<big>IsAmericanExpress</big>** : check if a give string is a valid american expression card nubmer or not. - **<big>IsAmericanExpress</big>** : check if a give string is a valid american expression card number or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsAmericanExpress)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsAmericanExpress)]
[[play](https://go.dev/play/p/HIDFpcOdpkd)] [[play](https://go.dev/play/p/HIDFpcOdpkd)]
- **<big>IsUnionPay</big>** : check if a give string is a valid union pay nubmer or not. - **<big>IsUnionPay</big>** : check if a give string is a valid union pay number or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsUnionPay)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsUnionPay)]
[[play](https://go.dev/play/p/CUHPEwEITDf)] [[play](https://go.dev/play/p/CUHPEwEITDf)]
- **<big>IsChinaUnionPay</big>** : check if a give string is a valid china union pay nubmer or not. - **<big>IsChinaUnionPay</big>** : check if a give string is a valid china union pay number or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsChinaUnionPay)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsChinaUnionPay)]
[[play](https://go.dev/play/p/yafpdxLiymu)] [[play](https://go.dev/play/p/yafpdxLiymu)]

View File

@@ -705,8 +705,10 @@ import "github.com/duke-git/lancet/v2/fileutil"
- **<big>ReadCsvFile</big>** : 读取 csv 文件内容到切片。 - **<big>ReadCsvFile</big>** : 读取 csv 文件内容到切片。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#ReadCsvFile)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#ReadCsvFile)]
[[play](https://go.dev/play/p/OExTkhGEd3_u)] [[play](https://go.dev/play/p/OExTkhGEd3_u)]
- **<big>WriteCsvFile</big>** : 向 csv 文件写入内容 - **<big>WriteCsvFile</big>** : 向csv文件写入切片数据
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteCsvFile)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteCsvFile)]
- **<big>WriteMapsToCsv</big>** : 将map切片写入csv文件中。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteMapsToCsv)]
[[play](https://go.dev/play/p/dAXm58Q5U1o)] [[play](https://go.dev/play/p/dAXm58Q5U1o)]
- **<big>WriteBytesToFile</big>** : 将 bytes 写入文件。 - **<big>WriteBytesToFile</big>** : 将 bytes 写入文件。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteBytesToFile)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteBytesToFile)]
@@ -1100,12 +1102,14 @@ import "github.com/duke-git/lancet/v2/random"
[[play](https://go.dev/play/p/uBkRSOz73Ec)] [[play](https://go.dev/play/p/uBkRSOz73Ec)]
- **<big>RandSymbolChar</big>** : 生成给定长度的随机符号字符串。 - **<big>RandSymbolChar</big>** : 生成给定长度的随机符号字符串。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandSymbolChar)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandSymbolChar)]
[[play](https://go.dev/play/p/uBkRSOz73Ec)] [[play](https://go.dev/play/p/Im6ZJxAykOm)]
- **<big>RandFloat</big>** : 生成随机float64数字可以指定范围和精度。 - **<big>RandFloat</big>** : 生成随机float64数字可以指定范围和精度。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandFloat)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandFloat)]
[[play](https://go.dev/play/p/uBkRSOz73Ec)] [[play](https://go.dev/play/p/zbD_tuobJtr)]
- **<big>RandFloats</big>** : 生成随机float64数字切片可以指定长度范围和精度. - **<big>RandFloats</big>** : 生成随机float64数字切片可以指定长度范围和精度.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandFloats)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandFloats)]
[[play](https://go.dev/play/p/uBkRSOz73Ec)]
<h3 id="retry"> 17. retry 重试执行函数直到函数运行成功或被 context cancel。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3> <h3 id="retry"> 17. retry 重试执行函数直到函数运行成功或被 context cancel。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
@@ -1175,9 +1179,10 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>DifferenceWith</big>** : 接受比较器函数,该比较器被调用以将切片的元素与值进行比较。 结果值的顺序和引用由第一个切片确定。 - **<big>DifferenceWith</big>** : 接受比较器函数,该比较器被调用以将切片的元素与值进行比较。 结果值的顺序和引用由第一个切片确定。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#DifferenceWith)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#DifferenceWith)]
[[play](https://go.dev/play/p/v2U2deugKuV)] [[play](https://go.dev/play/p/v2U2deugKuV)]
- **<big>DeleteAt</big>** : 删除切片中指定开始索引到结束索引的元素。 - **<big>DeleteAt</big>** : 删除切片中指定索引到的元素。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#DeleteAt)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#DeleteAt)]
[[play](https://go.dev/play/p/pJ-d6MUWcvK)] - **<big>DeleteRange</big>** : 删除切片中指定开始索引到结束索引的元素。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#DeleteRange)]
- **<big>Drop</big>** : 从切片头部删除 n 个元素。 - **<big>Drop</big>** : 从切片头部删除 n 个元素。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Drop)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Drop)]
[[play](https://go.dev/play/p/jnPO2yQsT8H)] [[play](https://go.dev/play/p/jnPO2yQsT8H)]
@@ -1340,7 +1345,6 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>Without</big>** : 创建一个不包括所有给定值的切片。 - **<big>Without</big>** : 创建一个不包括所有给定值的切片。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Without)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Without)]
[[play](https://go.dev/play/p/bwhEXEypThg)] [[play](https://go.dev/play/p/bwhEXEypThg)]
- **<big>KeyBy</big>** :将切片每个元素调用函数后转为 map。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#KeyBy)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#KeyBy)]
[[play](https://go.dev/play/p/uXod2LWD1Kg)] [[play](https://go.dev/play/p/uXod2LWD1Kg)]
- **<big>Join</big>** : 用指定的分隔符链接切片元素。 - **<big>Join</big>** : 用指定的分隔符链接切片元素。
@@ -1351,6 +1355,8 @@ import "github.com/duke-git/lancet/v2/slice"
[[play](https://go.dev/play/p/lkQ3Ri2NQhV)] [[play](https://go.dev/play/p/lkQ3Ri2NQhV)]
- **<big>Random</big>** : 随机返回切片中元素以及下标, 当切片长度为0时返回下标-1。 - **<big>Random</big>** : 随机返回切片中元素以及下标, 当切片长度为0时返回下标-1。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Random)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Random)]
[[play](https://go.dev/play/p/UzpGQptWppw)]
<h3 id="stream"> 19. stream 流,该包仅验证简单的 stream 实现,功能有限。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3> <h3 id="stream"> 19. stream 流,该包仅验证简单的 stream 实现,功能有限。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
@@ -1449,31 +1455,33 @@ import "github.com/duke-git/lancet/v2/structs"
#### 函数列表: #### 函数列表:
- **<big>New</big>** : `Struct`结构体的构造函数。 - **<big>New</big>** : `Struct`结构体的构造函数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/struct.md#New)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#New)]
- **<big>ToMap</big>** : 将一个合法的 struct 对象转换为 map[string]any。 - **<big>ToMap</big>** : 将一个合法的 struct 对象转换为 map[string]any。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/struct.md#ToMap)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#ToMap)]
- **<big>Fields</big>** : 获取一个 struct 对象的属性列表。 - **<big>Fields</big>** : 获取一个 struct 对象的属性列表。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/struct.md#Fields)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Fields)]
- **<big>Field</big>** : 根据属性名获取一个 struct 对象的属性。 - **<big>Field</big>** : 根据属性名获取一个 struct 对象的属性。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/struct.md#Fields)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Fields)]
- **<big>IsStruct</big>** : 判断是否为一个合法的 struct 对象。 - **<big>IsStruct</big>** : 判断是否为一个合法的 struct 对象。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/struct.md#IsStruct)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsStruct)]
- **<big>Tag</big>** : 获取`Field``Tag`,默认的 tag key 是 json。 - **<big>Tag</big>** : 获取`Field``Tag`,默认的 tag key 是 json。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/field.md#Tag)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Tag)]
- **<big>Name</big>** : 获取属性名。 - **<big>Name</big>** : 获取属性名。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/field.md#Name)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Name)]
- **<big>Value</big>** : 获取`Field`属性的值。 - **<big>Value</big>** : 获取`Field`属性的值。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/field.md#Value)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Value)]
- **<big>Kind</big>** : 获取属性 Kind。 - **<big>Kind</big>** : 获取属性 Kind。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/field.md#Kind)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Kind)]
- **<big>IsEmbedded</big>** : 判断属性是否为嵌入。 - **<big>IsEmbedded</big>** : 判断属性是否为嵌入。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/field.md#IsEmbedded)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsEmbedded)]
- **<big>IsExported</big>** : 判断属性是否导出。 - **<big>IsExported</big>** : 判断属性是否导出。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/field.md#IsExported)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsExported)]
- **<big>IsZero</big>** : 判断属性是否为零值。 - **<big>IsZero</big>** : 判断属性是否为零值。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/field.md#IsZero)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsZero)]
- **<big>IsSlice</big>** : 判断属性是否是切片。 - **<big>IsSlice</big>** : 判断属性是否是切片。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/structs/field.md#IsSlice)] [[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsSlice)]
- **<big>IsTargetType</big>** : 判断属性是否是目标类型。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsTargetType)]
<h3 id="strutil"> 21. strutil 包含字符串处理的相关函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3> <h3 id="strutil"> 21. strutil 包含字符串处理的相关函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>

View File

@@ -4,7 +4,7 @@
// Package algorithm contain some basic algorithm functions. eg. sort, search, list, linklist, stack, queue, tree, graph. // Package algorithm contain some basic algorithm functions. eg. sort, search, list, linklist, stack, queue, tree, graph.
package algorithm package algorithm
import "github.com/duke-git/lancet/v2/lancetconstraints" import "github.com/duke-git/lancet/v2/constraints"
// Search algorithms see https://github.com/TheAlgorithms/Go/tree/master/search // Search algorithms see https://github.com/TheAlgorithms/Go/tree/master/search
@@ -23,7 +23,7 @@ func LinearSearch[T any](slice []T, target T, equal func(a, b T) bool) int {
// BinarySearch return the index of target within a sorted slice, use binary search (recursive call itself). // BinarySearch return the index of target within a sorted slice, use binary search (recursive call itself).
// If not found return -1. // If not found return -1.
// Play: https://go.dev/play/p/t6MeGiUSN47 // Play: https://go.dev/play/p/t6MeGiUSN47
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int { func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator constraints.Comparator) int {
if highIndex < lowIndex || len(sortedSlice) == 0 { if highIndex < lowIndex || len(sortedSlice) == 0 {
return -1 return -1
} }
@@ -44,7 +44,7 @@ func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, com
// BinaryIterativeSearch return the index of target within a sorted slice, use binary search (no recursive). // BinaryIterativeSearch return the index of target within a sorted slice, use binary search (no recursive).
// If not found return -1. // If not found return -1.
// Play: https://go.dev/play/p/Anozfr8ZLH3 // Play: https://go.dev/play/p/Anozfr8ZLH3
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int { func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator constraints.Comparator) int {
startIndex := lowIndex startIndex := lowIndex
endIndex := highIndex endIndex := highIndex

View File

@@ -3,24 +3,29 @@
package algorithm package algorithm
import "github.com/duke-git/lancet/v2/lancetconstraints" import "github.com/duke-git/lancet/v2/constraints"
// BubbleSort applys the bubble sort algorithm to sort the collection, will change the original collection data. // BubbleSort applys the bubble sort algorithm to sort the collection, will change the original collection data.
// Play: https://go.dev/play/p/GNdv7Jg2Taj // Play: https://go.dev/play/p/GNdv7Jg2Taj
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) { func BubbleSort[T any](slice []T, comparator constraints.Comparator) {
for i := 0; i < len(slice); i++ { for i := 0; i < len(slice); i++ {
breakTag := false
for j := 0; j < len(slice)-1-i; j++ { for j := 0; j < len(slice)-1-i; j++ {
isCurrGreatThanNext := comparator.Compare(slice[j], slice[j+1]) == 1 isCurrGreatThanNext := comparator.Compare(slice[j], slice[j+1]) == 1
if isCurrGreatThanNext { if isCurrGreatThanNext {
swap(slice, j, j+1) swap(slice, j, j+1)
breakTag = true
} }
} }
if !breakTag {
break
}
} }
} }
// InsertionSort applys the insertion sort algorithm to sort the collection, will change the original collection data. // InsertionSort applys the insertion sort algorithm to sort the collection, will change the original collection data.
// Play: https://go.dev/play/p/G5LJiWgJJW6 // Play: https://go.dev/play/p/G5LJiWgJJW6
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) { func InsertionSort[T any](slice []T, comparator constraints.Comparator) {
for i := 0; i < len(slice); i++ { for i := 0; i < len(slice); i++ {
for j := i; j > 0; j-- { for j := i; j > 0; j-- {
isPreLessThanCurrent := comparator.Compare(slice[j], slice[j-1]) == -1 isPreLessThanCurrent := comparator.Compare(slice[j], slice[j-1]) == -1
@@ -35,7 +40,7 @@ func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) {
// SelectionSort applys the selection sort algorithm to sort the collection, will change the original collection data. // SelectionSort applys the selection sort algorithm to sort the collection, will change the original collection data.
// Play: https://go.dev/play/p/oXovbkekayS // Play: https://go.dev/play/p/oXovbkekayS
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) { func SelectionSort[T any](slice []T, comparator constraints.Comparator) {
for i := 0; i < len(slice); i++ { for i := 0; i < len(slice); i++ {
min := i min := i
for j := i + 1; j < len(slice); j++ { for j := i + 1; j < len(slice); j++ {
@@ -49,7 +54,7 @@ func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) {
// ShellSort applys the shell sort algorithm to sort the collection, will change the original collection data. // ShellSort applys the shell sort algorithm to sort the collection, will change the original collection data.
// Play: https://go.dev/play/p/3ibkszpJEu3 // Play: https://go.dev/play/p/3ibkszpJEu3
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) { func ShellSort[T any](slice []T, comparator constraints.Comparator) {
size := len(slice) size := len(slice)
gap := 1 gap := 1
@@ -69,11 +74,11 @@ 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.
// Play: https://go.dev/play/p/7Y7c1Elk3ax // Play: https://go.dev/play/p/7Y7c1Elk3ax
func QuickSort[T any](slice []T, comparator lancetconstraints.Comparator) { func QuickSort[T any](slice []T, comparator constraints.Comparator) {
quickSort(slice, 0, len(slice)-1, comparator) quickSort(slice, 0, len(slice)-1, comparator)
} }
func quickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) { func quickSort[T any](slice []T, lowIndex, highIndex int, comparator constraints.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)
@@ -82,7 +87,7 @@ func quickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconst
} }
// partition split slice into two parts // partition split slice into two parts
func partition[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int { func partition[T any](slice []T, lowIndex, highIndex int, comparator constraints.Comparator) int {
p := slice[highIndex] p := slice[highIndex]
i := lowIndex i := lowIndex
for j := lowIndex; j < highIndex; j++ { for j := lowIndex; j < highIndex; j++ {
@@ -99,7 +104,7 @@ func partition[T any](slice []T, lowIndex, highIndex int, comparator lancetconst
// HeapSort applys the heap sort algorithm to sort the collection, will change the original collection data. // HeapSort applys the heap sort algorithm to sort the collection, will change the original collection data.
// Play: https://go.dev/play/p/u6Iwa1VZS_f // Play: https://go.dev/play/p/u6Iwa1VZS_f
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) { func HeapSort[T any](slice []T, comparator constraints.Comparator) {
size := len(slice) size := len(slice)
for i := size/2 - 1; i >= 0; i-- { for i := size/2 - 1; i >= 0; i-- {
@@ -111,7 +116,7 @@ func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) {
} }
} }
func sift[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) { func sift[T any](slice []T, lowIndex, highIndex int, comparator constraints.Comparator) {
i := lowIndex i := lowIndex
j := 2*i + 1 j := 2*i + 1
@@ -133,11 +138,11 @@ func sift[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraint
// MergeSort applys the merge sort algorithm to sort the collection, will change the original collection data. // MergeSort applys the merge sort algorithm to sort the collection, will change the original collection data.
// Play: https://go.dev/play/p/ydinn9YzUJn // Play: https://go.dev/play/p/ydinn9YzUJn
func MergeSort[T any](slice []T, comparator lancetconstraints.Comparator) { func MergeSort[T any](slice []T, comparator constraints.Comparator) {
mergeSort(slice, 0, len(slice)-1, comparator) mergeSort(slice, 0, len(slice)-1, comparator)
} }
func mergeSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) { func mergeSort[T any](slice []T, lowIndex, highIndex int, comparator constraints.Comparator) {
if lowIndex < highIndex { if lowIndex < highIndex {
mid := (lowIndex + highIndex) / 2 mid := (lowIndex + highIndex) / 2
mergeSort(slice, lowIndex, mid, comparator) mergeSort(slice, lowIndex, mid, comparator)
@@ -146,7 +151,7 @@ func mergeSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconst
} }
} }
func merge[T any](slice []T, lowIndex, midIndex, highIndex int, comparator lancetconstraints.Comparator) { func merge[T any](slice []T, lowIndex, midIndex, highIndex int, comparator constraints.Comparator) {
i := lowIndex i := lowIndex
j := midIndex + 1 j := midIndex + 1
temp := []T{} temp := []T{}
@@ -175,7 +180,7 @@ func merge[T any](slice []T, lowIndex, midIndex, highIndex int, comparator lance
// CountSort applys the count sort algorithm to sort the collection, don't change the original collection data. // CountSort applys the count sort algorithm to sort the collection, don't change the original collection data.
// Play: https://go.dev/play/p/tB-Umgm0DrP // Play: https://go.dev/play/p/tB-Umgm0DrP
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { func CountSort[T any](slice []T, comparator constraints.Comparator) []T {
size := len(slice) size := len(slice)
out := make([]T, size) out := make([]T, size)

View File

@@ -16,7 +16,7 @@ type people struct {
// PeopleAageComparator sort people slice by age field // PeopleAageComparator sort people slice by age field
type peopleAgeComparator struct{} type peopleAgeComparator struct{}
// Compare implements github.com/duke-git/lancet/v2/lancetconstraints/constraints.go/Comparator // Compare implements github.com/duke-git/lancet/v2/constraints/constraints.go/Comparator
func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int { func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int {
p1, _ := v1.(people) p1, _ := v1.(people)
p2, _ := v2.(people) p2, _ := v2.(people)

View File

@@ -1,8 +1,8 @@
// Copyright 2021 dudaodong@gmail.com. All rights reserved. // Copyright 2021 dudaodong@gmail.com. All rights reserved.
// Use of this source code is governed by MIT license // Use of this source code is governed by MIT license
// Package lancetconstraints contain some comstomer constraints. // Package constraints contain some custom interface.
package lancetconstraints package constraints
// Comparator is for comparing two values // Comparator is for comparing two values
type Comparator interface { type Comparator interface {

View File

@@ -7,18 +7,18 @@ package datastructure
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/v2/lancetconstraints" "github.com/duke-git/lancet/v2/constraints"
) )
// MaxHeap implements a binary max heap // MaxHeap implements a binary max heap
// type T should implements Compare function in lancetconstraints.Comparator interface. // type T should implements Compare function in constraints.Comparator interface.
type MaxHeap[T any] struct { type MaxHeap[T any] struct {
data []T data []T
comparator lancetconstraints.Comparator comparator constraints.Comparator
} }
// NewMaxHeap returns a MaxHeap instance with the given comparator. // NewMaxHeap returns a MaxHeap instance with the given comparator.
func NewMaxHeap[T any](comparator lancetconstraints.Comparator) *MaxHeap[T] { func NewMaxHeap[T any](comparator constraints.Comparator) *MaxHeap[T] {
return &MaxHeap[T]{ return &MaxHeap[T]{
data: make([]T, 0), data: make([]T, 0),
comparator: comparator, comparator: comparator,
@@ -26,7 +26,7 @@ func NewMaxHeap[T any](comparator lancetconstraints.Comparator) *MaxHeap[T] {
} }
// BuildMaxHeap builds a MaxHeap instance with data and given comparator. // BuildMaxHeap builds a MaxHeap instance with data and given comparator.
func BuildMaxHeap[T any](data []T, comparator lancetconstraints.Comparator) *MaxHeap[T] { func BuildMaxHeap[T any](data []T, comparator constraints.Comparator) *MaxHeap[T] {
heap := &MaxHeap[T]{ heap := &MaxHeap[T]{
data: make([]T, 0, len(data)), data: make([]T, 0, len(data)),
comparator: comparator, comparator: comparator,

View File

@@ -8,20 +8,20 @@ package datastructure
import ( import (
"errors" "errors"
"github.com/duke-git/lancet/v2/lancetconstraints" "github.com/duke-git/lancet/v2/constraints"
) )
// PriorityQueue is a priority queue implemented by binary heap tree // PriorityQueue is a priority queue implemented by binary heap tree
// type T should implements Compare function in lancetconstraints.Comparator interface. // type T should implements Compare function in constraints.Comparator interface.
type PriorityQueue[T any] struct { type PriorityQueue[T any] struct {
items []T items []T
size int size int
comparator lancetconstraints.Comparator comparator constraints.Comparator
} }
// NewPriorityQueue return a pointer of PriorityQueue // NewPriorityQueue return a pointer of PriorityQueue
// param `comparator` is used to compare values in the queue // param `comparator` is used to compare values in the queue
func NewPriorityQueue[T any](capacity int, comparator lancetconstraints.Comparator) *PriorityQueue[T] { func NewPriorityQueue[T any](capacity int, comparator constraints.Comparator) *PriorityQueue[T] {
return &PriorityQueue[T]{ return &PriorityQueue[T]{
items: make([]T, capacity+1), items: make([]T, capacity+1),
size: 0, size: 0,

View File

@@ -7,22 +7,22 @@ package datastructure
import ( import (
"math" "math"
"github.com/duke-git/lancet/v2/constraints"
"github.com/duke-git/lancet/v2/datastructure" "github.com/duke-git/lancet/v2/datastructure"
"github.com/duke-git/lancet/v2/lancetconstraints"
) )
// BSTree is a binary search tree data structure in which each node has at most two children, // BSTree is a binary search tree data structure in which each node has at most two children,
// which are referred to as the left child and the right child. // which are referred to as the left child and the right child.
// In BSTree: leftNode < rootNode < rightNode // In BSTree: leftNode < rootNode < rightNode
// type T should implements Compare function in lancetconstraints.Comparator interface. // type T should implements Compare function in constraints.Comparator interface.
type BSTree[T any] struct { type BSTree[T any] struct {
root *datastructure.TreeNode[T] root *datastructure.TreeNode[T]
comparator lancetconstraints.Comparator comparator constraints.Comparator
} }
// NewBSTree create a BSTree pointer // NewBSTree create a BSTree pointer
// param `comparator` is used to compare values in the tree // param `comparator` is used to compare values in the tree
func NewBSTree[T any](rootData T, comparator lancetconstraints.Comparator) *BSTree[T] { func NewBSTree[T any](rootData T, comparator constraints.Comparator) *BSTree[T] {
root := datastructure.NewTreeNode(rootData) root := datastructure.NewTreeNode(rootData)
return &BSTree[T]{root, comparator} return &BSTree[T]{root, comparator}
} }
@@ -87,7 +87,7 @@ 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 constraints.Comparator) bool {
result := false result := false
if superTreeRoot != nil && subTreeRoot != nil { if superTreeRoot != nil && subTreeRoot != nil {

View File

@@ -4,8 +4,8 @@ import (
"fmt" "fmt"
"math" "math"
"github.com/duke-git/lancet/v2/constraints"
"github.com/duke-git/lancet/v2/datastructure" "github.com/duke-git/lancet/v2/datastructure"
"github.com/duke-git/lancet/v2/lancetconstraints"
) )
func preOrderTraverse[T any](node *datastructure.TreeNode[T]) []T { func preOrderTraverse[T any](node *datastructure.TreeNode[T]) []T {
@@ -86,7 +86,7 @@ func levelOrderTraverse[T any](root *datastructure.TreeNode[T], traversal *[]T)
} }
} }
func insertTreeNode[T any](rootNode, newNode *datastructure.TreeNode[T], comparator lancetconstraints.Comparator) { func insertTreeNode[T any](rootNode, newNode *datastructure.TreeNode[T], comparator constraints.Comparator) {
if comparator.Compare(newNode.Value, rootNode.Value) == -1 { if comparator.Compare(newNode.Value, rootNode.Value) == -1 {
if rootNode.Left == nil { if rootNode.Left == nil {
rootNode.Left = newNode rootNode.Left = newNode
@@ -103,7 +103,7 @@ func insertTreeNode[T any](rootNode, newNode *datastructure.TreeNode[T], compara
} }
// todo, delete root node failed // todo, delete root node failed
func deleteTreeNode[T any](node *datastructure.TreeNode[T], data T, comparator lancetconstraints.Comparator) *datastructure.TreeNode[T] { func deleteTreeNode[T any](node *datastructure.TreeNode[T], data T, comparator constraints.Comparator) *datastructure.TreeNode[T] {
if node == nil { if node == nil {
return nil return nil
} }
@@ -216,7 +216,7 @@ func calculateDepth[T any](node *datastructure.TreeNode[T], depth int) int {
return max(calculateDepth(node.Left, depth+1), calculateDepth(node.Right, depth+1)) return max(calculateDepth(node.Left, depth+1), calculateDepth(node.Right, depth+1))
} }
func isSubTree[T any](superTreeRoot, subTreeRoot *datastructure.TreeNode[T], comparator lancetconstraints.Comparator) bool { func isSubTree[T any](superTreeRoot, subTreeRoot *datastructure.TreeNode[T], comparator constraints.Comparator) bool {
if subTreeRoot == nil { if subTreeRoot == nil {
return true return true
} }

View File

@@ -381,3 +381,12 @@ func TimestampNano(timezone ...string) int64 {
return t.UnixNano() return t.UnixNano()
} }
// TraceFuncTime: trace the func costed time,just call it at top of the func like `defer TraceFuncTime()()`
func TraceFuncTime() func() {
pre := time.Now()
return func() {
elapsed := time.Since(pre)
fmt.Println("Costs Time:\t", elapsed)
}
}

View File

@@ -43,12 +43,12 @@ import (
### <span id="BubbleSort">BubbleSort</span> ### <span id="BubbleSort">BubbleSort</span>
<p>冒泡排序参数comparator需要实现包lancetconstraints.Comparator。</p> <p>冒泡排序参数comparator需要实现包constraints.Comparator。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) func BubbleSort[T any](slice []T, comparator constraints.Comparator)
``` ```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/GNdv7Jg2Taj)</span></b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/GNdv7Jg2Taj)</span></b>
@@ -91,12 +91,12 @@ func main() {
### <span id="InsertionSort">InsertionSort</span> ### <span id="InsertionSort">InsertionSort</span>
<p>插入排序参数comparator需要实现包lancetconstraints.Comparator。</p> <p>插入排序参数comparator需要实现包constraints.Comparator。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) func InsertionSort[T any](slice []T, comparator constraints.Comparator)
``` ```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/G5LJiWgJJW6)</span></b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/G5LJiWgJJW6)</span></b>
@@ -117,7 +117,7 @@ type people struct {
// PeopleAageComparator sort people slice by age field // PeopleAageComparator sort people slice by age field
type peopleAgeComparator struct{} type peopleAgeComparator struct{}
// Compare implements github.com/duke-git/lancet/lancetconstraints/constraints.go/Comparator // Compare implements github.com/duke-git/lancet/constraints/constraints.go/Comparator
func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int { func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int {
p1, _ := v1.(people) p1, _ := v1.(people)
p2, _ := v2.(people) p2, _ := v2.(people)
@@ -154,12 +154,12 @@ func main() {
### <span id="SelectionSort">SelectionSort</span> ### <span id="SelectionSort">SelectionSort</span>
<p>选择排序参数comparator需要实现包lancetconstraints.Comparator。</p> <p>选择排序参数comparator需要实现包constraints.Comparator。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) func SelectionSort[T any](slice []T, comparator constraints.Comparator)
``` ```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/oXovbkekayS)</span></b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/oXovbkekayS)</span></b>
@@ -202,12 +202,12 @@ func main() {
### <span id="ShellSort">ShellSort</span> ### <span id="ShellSort">ShellSort</span>
<p>希尔排序参数comparator需要实现包lancetconstraints.Comparator。</p> <p>希尔排序参数comparator需要实现包constraints.Comparator。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) func ShellSort[T any](slice []T, comparator constraints.Comparator)
``` ```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/3ibkszpJEu3)</span></b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/3ibkszpJEu3)</span></b>
@@ -250,12 +250,12 @@ func main() {
### <span id="QuickSort">QuickSort</span> ### <span id="QuickSort">QuickSort</span>
<p>快速排序参数comparator需要实现包lancetconstraints.Comparator。</p> <p>快速排序参数comparator需要实现包constraints.Comparator。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func QuickSort[T any](slice []T comparator lancetconstraints.Comparator) func QuickSort[T any](slice []T comparator constraints.Comparator)
``` ```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/7Y7c1Elk3ax)</span></b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/7Y7c1Elk3ax)</span></b>
@@ -298,12 +298,12 @@ func main() {
### <span id="HeapSort">HeapSort</span> ### <span id="HeapSort">HeapSort</span>
<p>堆排序参数comparator需要实现包lancetconstraints.Comparator。</p> <p>堆排序参数comparator需要实现包constraints.Comparator。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) func HeapSort[T any](slice []T, comparator constraints.Comparator)
``` ```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/u6Iwa1VZS_f)</span></b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/u6Iwa1VZS_f)</span></b>
@@ -346,12 +346,12 @@ func main() {
### <span id="MergeSort">MergeSort</span> ### <span id="MergeSort">MergeSort</span>
<p>归并排序参数comparator需要实现包lancetconstraints.Comparator。</p> <p>归并排序参数comparator需要实现包constraints.Comparator。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func MergeSort[T any](slice []T, comparator lancetconstraints.Comparator) func MergeSort[T any](slice []T, comparator constraints.Comparator)
``` ```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/ydinn9YzUJn)</span></b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/ydinn9YzUJn)</span></b>
@@ -394,12 +394,12 @@ func main() {
### <span id="CountSort">CountSort</span> ### <span id="CountSort">CountSort</span>
<p>计数排序参数comparator需要实现包lancetconstraints.Comparator。</p> <p>计数排序参数comparator需要实现包constraints.Comparator。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T func CountSort[T any](slice []T, comparator constraints.Comparator) []T
``` ```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/tB-Umgm0DrP)</span></b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/tB-Umgm0DrP)</span></b>
@@ -443,12 +443,12 @@ func main() {
### <span id="BinarySearch">BinarySearch</span> ### <span id="BinarySearch">BinarySearch</span>
<p>二分递归查找,返回元素索引,未找到元素返回-1参数comparator需要实现包lancetconstraints.Comparator。</p> <p>二分递归查找,返回元素索引,未找到元素返回-1参数comparator需要实现包constraints.Comparator。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator constraints.Comparator) int
``` ```
<b>示例: <span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/t6MeGiUSN47)</span></b> <b>示例: <span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/t6MeGiUSN47)</span></b>
@@ -494,12 +494,12 @@ func main() {
### <span id="BinaryIterativeSearch">BinaryIterativeSearch</span> ### <span id="BinaryIterativeSearch">BinaryIterativeSearch</span>
<p>二分迭代查找,返回元素索引,未找到元素返回-1参数comparator需要实现包lancetconstraints.Comparator。</p> <p>二分迭代查找,返回元素索引,未找到元素返回-1参数comparator需要实现包constraints.Comparator。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator constraints.Comparator) int
``` ```
<b>示例: <span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/Anozfr8ZLH3)</span></b> <b>示例: <span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/Anozfr8ZLH3)</span></b>

View File

@@ -44,9 +44,9 @@ MaxHeap是通过slice实现的二叉堆树根节点的key既大于等于左
```go ```go
type MaxHeap[T any] struct { type MaxHeap[T any] struct {
data []T data []T
comparator lancetconstraints.Comparator comparator constraints.Comparator
} }
func NewMaxHeap[T any](comparator lancetconstraints.Comparator) *MaxHeap[T] func NewMaxHeap[T any](comparator constraints.Comparator) *MaxHeap[T]
``` ```
<b>示例:</b> <b>示例:</b>

View File

@@ -1100,12 +1100,12 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func NewPriorityQueue[T any](capacity int, comparator lancetconstraints.Comparator) *PriorityQueue[T] func NewPriorityQueue[T any](capacity int, comparator constraints.Comparator) *PriorityQueue[T]
type PriorityQueue[T any] struct { type PriorityQueue[T any] struct {
items []T items []T
size int size int
comparator lancetconstraints.Comparator comparator constraints.Comparator
} }
``` ```
<b>示例:</b> <b>示例:</b>

View File

@@ -41,7 +41,7 @@ import (
## 文档 ## 文档
## 1. BSTree ## 1. BSTree
BSTree是一种二叉搜索树数据结构其中每个节点有两个孩子分别称为左孩子和右孩子。 在 BSTree 中leftNode < rootNode < rightNode。 T类型应该实现lancetconstraints.Comparator。 BSTree是一种二叉搜索树数据结构其中每个节点有两个孩子分别称为左孩子和右孩子。 在 BSTree 中leftNode < rootNode < rightNode。 T类型应该实现constraints.Comparator。
### <span id="NewBSTree">NewBSTree</span> ### <span id="NewBSTree">NewBSTree</span>
<p>返回BSTree指针实例</p> <p>返回BSTree指针实例</p>
@@ -49,11 +49,11 @@ BSTree是一种二叉搜索树数据结构其中每个节点有两个孩子
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func NewBSTree[T any](rootData T, comparator lancetconstraints.Comparator) *BSTree[T] func NewBSTree[T any](rootData T, comparator constraints.Comparator) *BSTree[T]
type BSTree[T any] struct { type BSTree[T any] struct {
root *datastructure.TreeNode[T] root *datastructure.TreeNode[T]
comparator lancetconstraints.Comparator comparator constraints.Comparator
} }
type TreeNode[T any] struct { type TreeNode[T any] struct {

View File

@@ -45,6 +45,7 @@ import (
- [Sha](#Sha) - [Sha](#Sha)
- [ReadCsvFile](#ReadCsvFile) - [ReadCsvFile](#ReadCsvFile)
- [WriteCsvFile](#WriteCsvFile) - [WriteCsvFile](#WriteCsvFile)
- [WriteMapsToCsv](#WriteMapsToCsv)
- [WriteStringToFile](#WriteStringToFile) - [WriteStringToFile](#WriteStringToFile)
- [WriteBytesToFile](#WriteBytesToFile) - [WriteBytesToFile](#WriteBytesToFile)
- [ReadFile](#ReadFile) - [ReadFile](#ReadFile)
@@ -669,7 +670,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ReadCsvFile(filepath string) ([][]string, error) func ReadCsvFile(filepath string, delimiter ...rune) ([][]string, error)
``` ```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/OExTkhGEd3_u)</span></b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/OExTkhGEd3_u)</span></b>
@@ -701,7 +702,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func WriteCsvFile(filepath string, records [][]string, append bool) error func WriteCsvFile(filepath string, records [][]string, append bool, delimiter ...rune) error
``` ```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/dAXm58Q5U1o)</span></b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/dAXm58Q5U1o)</span></b>
@@ -743,6 +744,59 @@ func main() {
} }
``` ```
### <span id="WriteMapsToCsv">WriteMapsToCsv</span>
<p>将map切片写入csv文件中。</p>
<b>函数签名:</b>
```go
// filepath: CSV文件路径。
// records: 写入文件的map切片。map值必须为基本类型。会以map键的字母顺序写入。
// appendToExistingFile: 是否为追加写模式。
// delimiter: CSV文件分割符。
// headers: CSV文件表头顺序需要与map key保持一致),不指定时按字母排序。
func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune, headers ...[]string) error
```
<b>示例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/fileutil"
)
func main() {
fpath := "./test.csv"
fileutil.CreateFile(fpath)
f, _ := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0777)
defer f.Close()
records := []map[string]any{
{"Name": "Lili", "Age": "22", "Gender": "female"},
{"Name": "Jim", "Age": "21", "Gender": "male"},
}
headers := []string{"Name", "Age", "Gender"}
err := WriteMapsToCsv(csvFilePath, records, false, ';', headers)
if err != nil {
log.Fatal(err)
}
content, err := fileutil.ReadCsvFile(csvFilePath, ';')
fmt.Println(content)
// Output:
// [[Name Age Gender] [Lili 22 female] [Jim 21 male]]
}
```
### <span id="WriteBytesToFile">WriteBytesToFile</span> ### <span id="WriteBytesToFile">WriteBytesToFile</span>
<p>将bytes写入文件。</p> <p>将bytes写入文件。</p>

View File

@@ -223,7 +223,7 @@ func main() {
### <span id="RandSymbolChar">RandSymbolChar</span> ### <span id="RandSymbolChar">RandSymbolChar</span>
<p>生成给定长度的随机符号字符串. 符号字符包括: !@#$%^&*()_+-=[]{}|;':\",./<>?。</p> <p>生成给定长度的随机符号字符串。</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -231,7 +231,7 @@ func main() {
func RandSymbolChar(length int) string func RandSymbolChar(length int) string
``` ```
<b>示例:</b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/Im6ZJxAykOm)</span></b>
```go ```go
package main package main
@@ -243,7 +243,7 @@ import (
func main() { func main() {
randStr := random.RandSymbolChar(6) randStr := random.RandSymbolChar(6)
fmt.Println(randStr) //@#(_") fmt.Println(randStr) // 随机特殊字符字符串,例如: @#(_")
} }
``` ```
@@ -312,7 +312,7 @@ func main() {
func RandFloat(min, max float64, precision int) float64 func RandFloat(min, max float64, precision int) float64
``` ```
<b>实例:</b> <b>实例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/zbD_tuobJtr)</span></b>
```go ```go
package main package main
@@ -338,7 +338,7 @@ func main() {
func RandFloats(n int, min, max float64, precision int) []float64 func RandFloats(n int, min, max float64, precision int) []float64
``` ```
<b>实例:</b> <b>实例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/I3yndUQ-rhh)</span></b>
```go ```go
package main package main

View File

@@ -35,6 +35,7 @@ import (
- [DifferenceBy](#DifferenceBy) - [DifferenceBy](#DifferenceBy)
- [DifferenceWith](#DifferenceWith) - [DifferenceWith](#DifferenceWith)
- [DeleteAt](#DeleteAt) - [DeleteAt](#DeleteAt)
- [DeleteRange](#DeleteRange)
- [Drop](#Drop) - [Drop](#Drop)
- [DropRight](#DropRight) - [DropRight](#DropRight)
- [DropWhile](#DropWhile) - [DropWhile](#DropWhile)
@@ -516,12 +517,12 @@ func main() {
### <span id="DeleteAt">DeleteAt</span> ### <span id="DeleteAt">DeleteAt</span>
<p>删除切片中指定开始索引到结束索引的元素</p> <p>删除切片中指定索引的元素(不修改原切片)。</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func DeleteAt[T any](slice []T, start int, end ...int) func DeleteAt[T any](slice []T, index int) []T
``` ```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/pJ-d6MUWcvK)</span></b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/pJ-d6MUWcvK)</span></b>
@@ -533,18 +534,66 @@ import (
) )
func main() { func main() {
result1 := slice.DeleteAt([]string{"a", "b", "c"}, -1) chars := []string{"a", "b", "c", "d", "e"}
result2 := slice.DeleteAt([]string{"a", "b", "c"}, 0)
result3 := slice.DeleteAt([]string{"a", "b", "c"}, 0, 2) result1 := slice.DeleteAt(chars, 0)
result2 := slice.DeleteAt(chars, 4)
result3 := slice.DeleteAt(chars, 5)
result4 := slice.DeleteAt(chars, 6)
fmt.Println(result1) fmt.Println(result1)
fmt.Println(result2) fmt.Println(result2)
fmt.Println(result3) fmt.Println(result3)
fmt.Println(result4)
// Output: // Output:
// [a b c] // [b c d e]
// [b c] // [a b c d]
// [c] // [a b c d]
// [a b c d]
}
```
### <span id="DeleteRange">DeleteRange</span>
<p>删除切片中指定索引范围的元素(不修改原切片)。</p>
<b>函数签名:</b>
```go
func DeleteRange[T any](slice []T, start, end int) []T
```
<b>示例:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
chars := []string{"a", "b", "c", "d", "e"}
result1 := DeleteRange(chars, 0, 0)
result2 := DeleteRange(chars, 0, 1)
result3 := DeleteRange(chars, 0, 3)
result4 := DeleteRange(chars, 0, 4)
result5 := DeleteRange(chars, 0, 5)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result5)
// Output:
// [a b c d e]
// [b c d e]
// [d e]
// [e]
// []
} }
``` ```
@@ -2475,18 +2524,18 @@ import (
func main() { func main() {
nums := []int{1, 2, 3, 4, 5} nums := []int{1, 2, 3, 4, 5}
result1 := slice.Partition(nums) result1 := slice.Partition(nums)
result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 }) result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 })
result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 }) result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 })
fmt.Println(result1) fmt.Println(result1)
fmt.Println(result2) fmt.Println(result2)
fmt.Println(result3) fmt.Println(result3)
// Output: // Output:
// [[1 2 3 4 5]] // [[1 2 3 4 5]]
// [[2 4] [1 3 5]] // [[2 4] [1 3 5]]
// [[1 2] [3 4] [5]] // [[1 2] [3 4] [5]]
} }
``` ```
@@ -2501,7 +2550,7 @@ func main() {
func Random[T any](slice []T) (val T, idx int) func Random[T any](slice []T) (val T, idx int)
``` ```
<b>示例:<span style="float:right;display:inline-block;">[运行](TODO)</span></b> <b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/UzpGQptWppw)</span></b>
```go ```go
import ( import (
@@ -2510,13 +2559,13 @@ import (
) )
func main() { func main() {
nums := []int{1, 2, 3, 4, 5} nums := []int{1, 2, 3, 4, 5}
val, idx := slice.Random(nums) val, idx := slice.Random(nums)
if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) { if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) {
fmt.Println("okk") fmt.Println("okk")
} }
// Output: // Output:
// okk // okk
} }
``` ```

View File

@@ -37,6 +37,7 @@ import (
- [IsExported](#IsExported) - [IsExported](#IsExported)
- [IsZero](#IsZero) - [IsZero](#IsZero)
- [IsSlice](#IsSlice) - [IsSlice](#IsSlice)
- [IsTargetType](#IsTargetType)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -531,4 +532,45 @@ func main() {
// Output: // Output:
// true // true
} }
```
### <span id="IsTargetType">IsTargetType</span>
<p>判断属性是否是目标类型</p>
<b>函数签名:</b>
```go
func (f *Field) IsTargetType(targetType reflect.Kind) bool
```
<b>示例:</b>
```go
package main
import (
"fmt"
"reflect"
"github.com/duke-git/lancet/v2/structs"
)
func main() {
type Parent struct {
Name string
arr []int
}
p1 := &Parent{arr: []int{1, 2, 3}}
s := structs.New(p1)
n, _ := s.Field("Name")
a, _ := s.Field("arr")
fmt.Println(n.IsTargetType(reflect.String))
fmt.Println(a.IsTargetType(reflect.Slice))
// Output:
// true
// true
}
``` ```

View File

@@ -43,12 +43,12 @@ import (
### <span id="BubbleSort">BubbleSort</span> ### <span id="BubbleSort">BubbleSort</span>
<p>Sort slice with bubble sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p> <p>Sort slice with bubble sort algorithm. Param comparator should implements constraints.Comparator.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) func BubbleSort[T any](slice []T, comparator constraints.Comparator)
``` ```
<b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/GNdv7Jg2Taj)</span></b> <b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/GNdv7Jg2Taj)</span></b>
@@ -91,12 +91,12 @@ func main() {
### <span id="InsertionSort">InsertionSort</span> ### <span id="InsertionSort">InsertionSort</span>
<p>Sort slice with insertion sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p> <p>Sort slice with insertion sort algorithm. Param comparator should implements constraints.Comparator.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) func InsertionSort[T any](slice []T, comparator constraints.Comparator)
``` ```
<b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/G5LJiWgJJW6)</span></b> <b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/G5LJiWgJJW6)</span></b>
@@ -117,7 +117,7 @@ type people struct {
// PeopleAageComparator sort people slice by age field // PeopleAageComparator sort people slice by age field
type peopleAgeComparator struct{} type peopleAgeComparator struct{}
// Compare implements github.com/duke-git/lancet/lancetconstraints/constraints.go/Comparator // Compare implements github.com/duke-git/lancet/constraints/constraints.go/Comparator
func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int { func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int {
p1, _ := v1.(people) p1, _ := v1.(people)
p2, _ := v2.(people) p2, _ := v2.(people)
@@ -154,12 +154,12 @@ func main() {
### <span id="SelectionSort">SelectionSort</span> ### <span id="SelectionSort">SelectionSort</span>
<p>Sort slice with selection sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p> <p>Sort slice with selection sort algorithm. Param comparator should implements constraints.Comparator.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) func SelectionSort[T any](slice []T, comparator constraints.Comparator)
``` ```
<b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/oXovbkekayS)</span></b> <b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/oXovbkekayS)</span></b>
@@ -202,12 +202,12 @@ func main() {
### <span id="ShellSort">ShellSort</span> ### <span id="ShellSort">ShellSort</span>
<p>Sort slice with shell sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p> <p>Sort slice with shell sort algorithm. Param comparator should implements constraints.Comparator.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) func ShellSort[T any](slice []T, comparator constraints.Comparator)
``` ```
<b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/3ibkszpJEu3)</span></b> <b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/3ibkszpJEu3)</span></b>
@@ -250,12 +250,12 @@ func main() {
### <span id="QuickSort">QuickSort</span> ### <span id="QuickSort">QuickSort</span>
<p>Sort slice with quick sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p> <p>Sort slice with quick sort algorithm. Param comparator should implements constraints.Comparator.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func QuickSort[T any](slice []T comparator lancetconstraints.Comparator) func QuickSort[T any](slice []T comparator constraints.Comparator)
``` ```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/7Y7c1Elk3ax)</span></b> <b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/7Y7c1Elk3ax)</span></b>
@@ -298,12 +298,12 @@ func main() {
### <span id="HeapSort">HeapSort</span> ### <span id="HeapSort">HeapSort</span>
<p>Sort slice with heap sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p> <p>Sort slice with heap sort algorithm. Param comparator should implements constraints.Comparator.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) func HeapSort[T any](slice []T, comparator constraints.Comparator)
``` ```
<b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/u6Iwa1VZS_f)</span></b> <b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/u6Iwa1VZS_f)</span></b>
@@ -346,12 +346,12 @@ func main() {
### <span id="MergeSort">MergeSort</span> ### <span id="MergeSort">MergeSort</span>
<p>Sort slice with merge sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p> <p>Sort slice with merge sort algorithm. Param comparator should implements constraints.Comparator.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func MergeSort[T any](slice []T, comparator lancetconstraints.Comparator) func MergeSort[T any](slice []T, comparator constraints.Comparator)
``` ```
<b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/ydinn9YzUJn)</span></b> <b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/ydinn9YzUJn)</span></b>
@@ -394,12 +394,12 @@ func main() {
### <span id="CountSort">CountSort</span> ### <span id="CountSort">CountSort</span>
<p>Sort slice with count sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p> <p>Sort slice with count sort algorithm. Param comparator should implements constraints.Comparator.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T func CountSort[T any](slice []T, comparator constraints.Comparator) []T
``` ```
<b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/tB-Umgm0DrP)</span></b> <b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/tB-Umgm0DrP)</span></b>
@@ -448,7 +448,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator constraints.Comparator) int
``` ```
<b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/t6MeGiUSN47)</span></b> <b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/t6MeGiUSN47)</span></b>
@@ -499,7 +499,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator constraints.Comparator) int
``` ```
<b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/Anozfr8ZLH3)</span></b> <b>Example: <span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/Anozfr8ZLH3)</span></b>

View File

@@ -44,9 +44,9 @@ MaxHeap is a binary heap tree implemented by slice, The key of the root node is
```go ```go
type MaxHeap[T any] struct { type MaxHeap[T any] struct {
data []T data []T
comparator lancetconstraints.Comparator comparator constraints.Comparator
} }
func NewMaxHeap[T any](comparator lancetconstraints.Comparator) *MaxHeap[T] func NewMaxHeap[T any](comparator constraints.Comparator) *MaxHeap[T]
``` ```
<b>Example:</b> <b>Example:</b>

View File

@@ -1100,12 +1100,12 @@ Common queue implemented by slice.
<b>Signature:</b> <b>Signature:</b>
```go ```go
func NewPriorityQueue[T any](capacity int, comparator lancetconstraints.Comparator) *PriorityQueue[T] func NewPriorityQueue[T any](capacity int, comparator constraints.Comparator) *PriorityQueue[T]
type PriorityQueue[T any] struct { type PriorityQueue[T any] struct {
items []T items []T
size int size int
comparator lancetconstraints.Comparator comparator constraints.Comparator
} }
``` ```
<b>Example:</b> <b>Example:</b>

View File

@@ -41,7 +41,7 @@ import (
## Documentation ## Documentation
## 1. BSTree ## 1. BSTree
BSTree is a binary search tree data structure in which each node has at two children, which are referred to as the left child and the right child. In BSTree: leftNode < rootNode < rightNode. Type T should implements Compare function in lancetconstraints.Comparator interface. BSTree is a binary search tree data structure in which each node has at two children, which are referred to as the left child and the right child. In BSTree: leftNode < rootNode < rightNode. Type T should implements Compare function in constraints.Comparator interface.
### <span id="NewBSTree">NewBSTree</span> ### <span id="NewBSTree">NewBSTree</span>
<p>Make a BSTree pointer instance</p> <p>Make a BSTree pointer instance</p>
@@ -49,11 +49,11 @@ BSTree is a binary search tree data structure in which each node has at two chil
<b>Signature:</b> <b>Signature:</b>
```go ```go
func NewBSTree[T any](rootData T, comparator lancetconstraints.Comparator) *BSTree[T] func NewBSTree[T any](rootData T, comparator constraints.Comparator) *BSTree[T]
type BSTree[T any] struct { type BSTree[T any] struct {
root *datastructure.TreeNode[T] root *datastructure.TreeNode[T]
comparator lancetconstraints.Comparator comparator constraints.Comparator
} }
type TreeNode[T any] struct { type TreeNode[T any] struct {

View File

@@ -45,6 +45,8 @@ import (
- [Sha](#Sha) - [Sha](#Sha)
- [ReadCsvFile](#ReadCsvFile) - [ReadCsvFile](#ReadCsvFile)
- [WriteCsvFile](#WriteCsvFile) - [WriteCsvFile](#WriteCsvFile)
- [WriteCsvFile](#WriteCsvFile)
- [WriteMapsToCsv](#WriteMapsToCsv)
- [WriteStringToFile](#WriteStringToFile) - [WriteStringToFile](#WriteStringToFile)
- [WriteBytesToFile](#WriteBytesToFile) - [WriteBytesToFile](#WriteBytesToFile)
- [ReadFile](#ReadFile) - [ReadFile](#ReadFile)
@@ -669,7 +671,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ReadCsvFile(filepath string) ([][]string, error) func ReadCsvFile(filepath string, delimiter ...rune) ([][]string, error)
``` ```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/OExTkhGEd3_u)</span></b> <b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/OExTkhGEd3_u)</span></b>
@@ -701,7 +703,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func WriteCsvFile(filepath string, records [][]string, append bool) error func WriteCsvFile(filepath string, records [][]string, append bool, delimiter ...rune) error
``` ```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/dAXm58Q5U1o)</span></b> <b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/dAXm58Q5U1o)</span></b>
@@ -743,6 +745,59 @@ func main() {
} }
``` ```
### <span id="WriteMapsToCsv">WriteMapsToCsv</span>
<p>Write slice of map to csv file.</p>
<b>Signature:</b>
```go
// filepath: path of the CSV file.
// records: slice of maps to be written. the value of map should be basic type. The maps will be sorted by key in alphabeta order, then be written into csv file.
// appendToExistingFile: If true, data will be appended to the file if it exists.
// delimiter: Delimiter to use in the CSV file.
// headers: order of the csv column headers, needs to be consistent with the key of the map.
func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune, headers ...[]string) error
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/fileutil"
)
func main() {
fpath := "./test.csv"
fileutil.CreateFile(fpath)
f, _ := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0777)
defer f.Close()
records := []map[string]any{
{"Name": "Lili", "Age": "22", "Gender": "female"},
{"Name": "Jim", "Age": "21", "Gender": "male"},
}
headers := []string{"Name", "Age", "Gender"}
err := fileutil.WriteMapsToCsv(csvFilePath, records, false, ';', headers)
if err != nil {
log.Fatal(err)
}
content, err := fileutil.ReadCsvFile(csvFilePath, ';')
fmt.Println(content)
// Output:
// [[Name Age Gender] [Lili 22 female] [Jim 21 male]]
}
```
### <span id="WriteBytesToFile">WriteBytesToFile</span> ### <span id="WriteBytesToFile">WriteBytesToFile</span>
<p>Writes bytes to target file.</p> <p>Writes bytes to target file.</p>

View File

@@ -223,7 +223,7 @@ func main() {
### <span id="RandSymbolChar">RandSymbolChar</span> ### <span id="RandSymbolChar">RandSymbolChar</span>
<p>Generate a random symbol char of specified length. Symbol chars: !@#$%^&*()_+-=[]{}|;':\",./<>?.</p> <p>Generate a random symbol char of specified length.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -231,7 +231,7 @@ func main() {
func RandSymbolChar(length int) string func RandSymbolChar(length int) string
``` ```
<b>Example:</b> <b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/Im6ZJxAykOm)</span></b>
```go ```go
package main package main
@@ -243,7 +243,7 @@ import (
func main() { func main() {
randStr := random.RandSymbolChar(6) randStr := random.RandSymbolChar(6)
fmt.Println(randStr) //@#(_") fmt.Println(randStr) // random string like: @#(_")
} }
``` ```
@@ -313,7 +313,7 @@ func main() {
func RandFloat(min, max float64, precision int) float64 func RandFloat(min, max float64, precision int) float64
``` ```
<b>Example:</b> <b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/zbD_tuobJtr)</span></b>
```go ```go
package main package main
@@ -339,7 +339,7 @@ func main() {
func RandFloats(n int, min, max float64, precision int) []float64 func RandFloats(n int, min, max float64, precision int) []float64
``` ```
<b>Example:</b> <b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/I3yndUQ-rhh)</span></b>
```go ```go
package main package main
@@ -351,6 +351,6 @@ import (
func main() { func main() {
floatNumbers := random.RandFloats(5, 1.0, 5.0, 2) floatNumbers := random.RandFloats(5, 1.0, 5.0, 2)
fmt.Println(floatNumber) //[3.42 3.99 1.3 2.38 4.23] (random) fmt.Println(floatNumbers) //[3.42 3.99 1.3 2.38 4.23] (random)
} }
``` ```

View File

@@ -35,6 +35,7 @@ import (
- [DifferenceBy](#DifferenceBy) - [DifferenceBy](#DifferenceBy)
- [DifferenceWith](#DifferenceWith) - [DifferenceWith](#DifferenceWith)
- [DeleteAt](#DeleteAt) - [DeleteAt](#DeleteAt)
- [DeleteRange](#DeleteRange)
- [Drop](#Drop) - [Drop](#Drop)
- [DropRight](#DropRight) - [DropRight](#DropRight)
- [DropWhile](#DropWhile) - [DropWhile](#DropWhile)
@@ -515,12 +516,12 @@ 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 delete the element of slice at index.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func DeleteAt[T any](slice []T, start int, end ...int) func DeleteAt[T any](slice []T, index int)
``` ```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/pJ-d6MUWcvK)</span></b> <b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/pJ-d6MUWcvK)</span></b>
@@ -532,18 +533,66 @@ import (
) )
func main() { func main() {
result1 := slice.DeleteAt([]string{"a", "b", "c"}, -1) chars := []string{"a", "b", "c", "d", "e"}
result2 := slice.DeleteAt([]string{"a", "b", "c"}, 0)
result3 := slice.DeleteAt([]string{"a", "b", "c"}, 0, 2) result1 := slice.DeleteAt(chars, 0)
result2 := slice.DeleteAt(chars, 4)
result3 := slice.DeleteAt(chars, 5)
result4 := slice.DeleteAt(chars, 6)
fmt.Println(result1) fmt.Println(result1)
fmt.Println(result2) fmt.Println(result2)
fmt.Println(result3) fmt.Println(result3)
fmt.Println(result4)
// Output: // Output:
// [a b c] // [b c d e]
// [b c] // [a b c d]
// [c] // [a b c d]
// [a b c d]
}
```
### <span id="DeleteRange">DeleteRange</span>
<p>Delete the element of slice from start index to end indexexclude)</p>
<b>Signature:</b>
```go
func DeleteRange[T any](slice []T, start, end int) []T
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
chars := []string{"a", "b", "c", "d", "e"}
result1 := DeleteRange(chars, 0, 0)
result2 := DeleteRange(chars, 0, 1)
result3 := DeleteRange(chars, 0, 3)
result4 := DeleteRange(chars, 0, 4)
result5 := DeleteRange(chars, 0, 5)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result5)
// Output:
// [a b c d e]
// [b c d e]
// [d e]
// [e]
// []
} }
``` ```
@@ -2473,18 +2522,18 @@ import (
func main() { func main() {
nums := []int{1, 2, 3, 4, 5} nums := []int{1, 2, 3, 4, 5}
result1 := slice.Partition(nums) result1 := slice.Partition(nums)
result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 }) result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 })
result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 }) result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 })
fmt.Println(result1) fmt.Println(result1)
fmt.Println(result2) fmt.Println(result2)
fmt.Println(result3) fmt.Println(result3)
// Output: // Output:
// [[1 2 3 4 5]] // [[1 2 3 4 5]]
// [[2 4] [1 3 5]] // [[2 4] [1 3 5]]
// [[1 2] [3 4] [5]] // [[1 2] [3 4] [5]]
} }
``` ```
@@ -2498,7 +2547,7 @@ func main() {
func Random[T any](slice []T) (val T, idx int) func Random[T any](slice []T) (val T, idx int)
``` ```
<b>Example:<span style="float:right;display:inline-block;">[Run](TODO)</span></b> <b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/UzpGQptWppw)</span></b>
```go ```go
import ( import (
@@ -2507,13 +2556,13 @@ import (
) )
func main() { func main() {
nums := []int{1, 2, 3, 4, 5} nums := []int{1, 2, 3, 4, 5}
val, idx := slice.Random(nums) val, idx := slice.Random(nums)
if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) { if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) {
fmt.Println("okk") fmt.Println("okk")
} }
// Output: // Output:
// okk // okk
} }
``` ```

View File

@@ -37,6 +37,7 @@ import (
- [IsExported](#IsExported) - [IsExported](#IsExported)
- [IsZero](#IsZero) - [IsZero](#IsZero)
- [IsSlice](#IsSlice) - [IsSlice](#IsSlice)
- [IsTargetType](#IsTargetType)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -533,3 +534,44 @@ func main() {
// true // true
} }
``` ```
### <span id="IsTargetType">IsTargetType</span>
<p>check if a struct field type is target type or not</p>
<b>Signature:</b>
```go
func (f *Field) IsTargetType(targetType reflect.Kind) bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
"reflect"
"github.com/duke-git/lancet/v2/structs"
)
func main() {
type Parent struct {
Name string
arr []int
}
p1 := &Parent{arr: []int{1, 2, 3}}
s := structs.New(p1)
n, _ := s.Field("Name")
a, _ := s.Field("arr")
fmt.Println(n.IsTargetType(reflect.String))
fmt.Println(a.IsTargetType(reflect.Slice))
// Output:
// true
// true
}
```

View File

@@ -20,11 +20,67 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"sort"
"strings" "strings"
"github.com/duke-git/lancet/v2/validator" "github.com/duke-git/lancet/v2/validator"
) )
// FileReader is a reader supporting offset seeking and reading one
// line at a time, this is especially useful for large files
type FileReader struct {
*bufio.Reader
file *os.File
offset int64
}
// NewFileReader creates the FileReader struct for reading
func NewFileReader(path string) (*FileReader, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
return &FileReader{
file: f,
Reader: bufio.NewReader(f),
offset: 0,
}, nil
}
// ReadLine reads and returns one line at a time excluding the trailing '\r' and '\n'
func (f *FileReader) ReadLine() (string, error) {
data, err := f.Reader.ReadBytes('\n')
f.offset += int64(len(data))
if err == nil || err == io.EOF {
for len(data) > 0 && (data[len(data)-1] == '\r' || data[len(data)-1] == '\n') {
data = data[:len(data)-1]
}
return string(data), err
}
return "", err
}
// Offset returns the current offset of the file
func (f *FileReader) Offset() int64 {
return f.offset
}
// Seek sets the current offset of the reading
func (f *FileReader) Seek(offset int64) error {
_, err := f.file.Seek(offset, 0)
if err != nil {
return err
}
f.Reader = bufio.NewReader(f.file)
f.offset = offset
return nil
}
// Close takes care of the opened file
func (f *FileReader) Close() error {
return f.file.Close()
}
// IsExist checks if a file or directory exists. // IsExist checks if a file or directory exists.
// Play: https://go.dev/play/p/nKKXt8ZQbmh // Play: https://go.dev/play/p/nKKXt8ZQbmh
func IsExist(path string) bool { func IsExist(path string) bool {
@@ -508,6 +564,25 @@ func FileSize(path string) (int64, error) {
return f.Size(), nil return f.Size(), nil
} }
// DirSize walks the folder recursively and returns folder size in bytes.
func DirSize(path string) (int64, error) {
var size int64
err := filepath.WalkDir(path, func(_ string, d os.DirEntry, err error) error {
if err != nil {
return err
}
if !d.IsDir() {
info, err := d.Info()
if err != nil {
return err
}
size += info.Size()
}
return err
})
return size, err
}
// MTime returns file modified time. // MTime returns file modified time.
// Play: https://go.dev/play/p/s_Tl7lZoAaY // Play: https://go.dev/play/p/s_Tl7lZoAaY
func MTime(filepath string) (int64, error) { func MTime(filepath string) (int64, error) {
@@ -536,7 +611,7 @@ func Sha(filepath string, shaType ...int) (string, error) {
} else if shaType[0] == 512 { } else if shaType[0] == 512 {
h = sha512.New() h = sha512.New()
} else { } else {
return "", errors.New("param `shaType` should be 1, 256 or 512.") return "", errors.New("param `shaType` should be 1, 256 or 512")
} }
} }
@@ -554,15 +629,19 @@ func Sha(filepath string, shaType ...int) (string, error) {
// ReadCsvFile read file content into slice. // ReadCsvFile read file content into slice.
// Play: https://go.dev/play/p/OExTkhGEd3_u // Play: https://go.dev/play/p/OExTkhGEd3_u
func ReadCsvFile(filepath string) ([][]string, error) { func ReadCsvFile(filepath string, delimiter ...rune) ([][]string, error) {
f, err := os.Open(filepath) f, err := os.Open(filepath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer f.Close() defer f.Close()
csvReader := csv.NewReader(f) reader := csv.NewReader(f)
records, err := csvReader.ReadAll() if len(delimiter) > 0 {
reader.Comma = delimiter[0]
}
records, err := reader.ReadAll()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -571,8 +650,10 @@ func ReadCsvFile(filepath string) ([][]string, error) {
} }
// WriteCsvFile write content to target csv file. // WriteCsvFile write content to target csv file.
// append: append to existing csv file
// delimiter: specifies csv delimiter
// Play: https://go.dev/play/p/dAXm58Q5U1o // Play: https://go.dev/play/p/dAXm58Q5U1o
func WriteCsvFile(filepath string, records [][]string, append bool) error { func WriteCsvFile(filepath string, records [][]string, append bool, delimiter ...rune) error {
flag := os.O_RDWR | os.O_CREATE flag := os.O_RDWR | os.O_CREATE
if append { if append {
@@ -587,7 +668,19 @@ func WriteCsvFile(filepath string, records [][]string, append bool) error {
defer f.Close() defer f.Close()
writer := csv.NewWriter(f) writer := csv.NewWriter(f)
writer.Comma = ',' // 设置默认分隔符为逗号,除非另外指定
if len(delimiter) > 0 {
writer.Comma = delimiter[0]
} else {
writer.Comma = ','
}
// 遍历所有记录并处理包含分隔符或双引号的单元格
for i := range records {
for j := range records[i] {
records[i][j] = escapeCSVField(records[i][j], writer.Comma)
}
}
return writer.WriteAll(records) return writer.WriteAll(records)
} }
@@ -646,3 +739,71 @@ func ReadFile(path string) (reader io.ReadCloser, closeFn func(), err error) {
return nil, func() {}, errors.New("unknown file type") return nil, func() {}, errors.New("unknown file type")
} }
} }
// escapeCSVField 处理单元格内容,如果包含分隔符,则用双引号包裹
func escapeCSVField(field string, delimiter rune) string {
// 替换所有的双引号为两个双引号
escapedField := strings.ReplaceAll(field, "\"", "\"\"")
// 如果字段包含分隔符、双引号或换行符,用双引号包裹整个字段
if strings.ContainsAny(escapedField, string(delimiter)+"\"\n") {
escapedField = fmt.Sprintf("\"%s\"", escapedField)
}
return escapedField
}
// WriteMapsToCsv write slice of map to csv file.
// Play: todo
// filepath: Path to the CSV file.
// records: Slice of maps to be written. the value of map should be basic type.
// the maps will be sorted by key in alphabeta order, then be written into csv file.
// appendToExistingFile: If true, data will be appended to the file if it exists.
// delimiter: Delimiter to use in the CSV file.
// headers: order of the csv column headers, needs to be consistent with the key of the map.
func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune,
headers ...[]string) error {
for _, record := range records {
for _, value := range record {
if !isCsvSupportedType(value) {
return errors.New("unsupported value type detected; only basic types are supported: \nbool, rune, string, int, int64, float32, float64, uint, byte, complex128, complex64, uintptr")
}
}
}
var columnHeaders []string
if len(headers) > 0 {
columnHeaders = headers[0]
} else {
for key := range records[0] {
columnHeaders = append(columnHeaders, key)
}
// sort keys in alphabeta order
sort.Strings(columnHeaders)
}
var datasToWrite [][]string
if !appendToExistingFile {
datasToWrite = append(datasToWrite, columnHeaders)
}
for _, record := range records {
var row []string
for _, h := range columnHeaders {
row = append(row, fmt.Sprintf("%v", record[h]))
}
datasToWrite = append(datasToWrite, row)
}
return WriteCsvFile(filepath, datasToWrite, appendToExistingFile, delimiter)
}
// check if the value of map which to be written into csv is basic type.
func isCsvSupportedType(v interface{}) bool {
switch v.(type) {
case bool, rune, string, int, int64, float32, float64, uint, byte, complex128, complex64, uintptr:
return true
default:
return false
}
}

View File

@@ -3,6 +3,7 @@ package fileutil
import ( import (
"fmt" "fmt"
"io" "io"
"log"
"os" "os"
) )
@@ -331,6 +332,28 @@ func ExampleWriteCsvFile() {
// [[Lili 22 female] [Jim 21 male]] // [[Lili 22 female] [Jim 21 male]]
} }
func ExampleWriteMapsToCsv() {
csvFilePath := "./testdata/test3.csv"
records := []map[string]any{
{"Name": "Lili", "Age": "22", "Gender": "female"},
{"Name": "Jim", "Age": "21", "Gender": "male"},
}
headers := []string{"Name", "Age", "Gender"}
err := WriteMapsToCsv(csvFilePath, records, false, ';', headers)
if err != nil {
log.Fatal(err)
}
content, err := ReadCsvFile(csvFilePath, ';')
fmt.Println(content)
// Output:
// [[Name Age Gender] [Lili 22 female] [Jim 21 male]]
}
func ExampleWriteStringToFile() { func ExampleWriteStringToFile() {
filepath := "./test.txt" filepath := "./test.txt"

View File

@@ -27,7 +27,7 @@ func TestCreateFile(t *testing.T) {
assert := internal.NewAssert(t, "TestCreateFile") assert := internal.NewAssert(t, "TestCreateFile")
f := "./text.txt" f := "./testdata/text.txt"
if CreateFile(f) { if CreateFile(f) {
file, err := os.Open(f) file, err := os.Open(f)
assert.IsNil(err) assert.IsNil(err)
@@ -340,10 +340,14 @@ func TestSha(t *testing.T) {
assert := internal.NewAssert(t, "TestSha") assert := internal.NewAssert(t, "TestSha")
sha1, err := Sha("./testdata/test.txt", 1) sha1, err := Sha("./testdata/test.txt", 1)
sha256, err := Sha("./testdata/test.txt", 256)
sha512, err := Sha("./testdata/test.txt", 512)
assert.IsNil(err) assert.IsNil(err)
sha256, err := Sha("./testdata/test.txt", 256)
assert.IsNil(err)
sha512, err := Sha("./testdata/test.txt", 512)
assert.IsNil(err)
assert.Equal("dda3cf10c5a6ff6c6659a497bf7261b287af2bc7", sha1) assert.Equal("dda3cf10c5a6ff6c6659a497bf7261b287af2bc7", sha1)
assert.Equal("aa6d0a3fbc3442c228d606da09e0c1dc98c69a1cac3da1909199e0266171df35", sha256) assert.Equal("aa6d0a3fbc3442c228d606da09e0c1dc98c69a1cac3da1909199e0266171df35", sha256)
assert.Equal("d22aba2a1b7a2e2f512756255cc1c3708905646920cb1eb95e45b531ba74774dbbb89baebf1f716220eb9cf4908f1cfc5b2a01267704d9a59f59d77cab609870", sha512) assert.Equal("d22aba2a1b7a2e2f512756255cc1c3708905646920cb1eb95e45b531ba74774dbbb89baebf1f716220eb9cf4908f1cfc5b2a01267704d9a59f59d77cab609870", sha512)
@@ -379,11 +383,36 @@ func TestWriteCsvFile(t *testing.T) {
assert.Equal(2, len(readContent)) assert.Equal(2, len(readContent))
assert.Equal(3, len(readContent[0])) assert.Equal(3, len(readContent[0]))
assert.Equal("Lili", content[0][0]) assert.Equal("Lili", readContent[0][0])
// RemoveFile(csvFilePath) // RemoveFile(csvFilePath)
} }
func TestWriteMapsToCsv(t *testing.T) {
assert := internal.NewAssert(t, "TestWriteMapsToCSV")
csvFilePath := "./testdata/test4.csv"
records := []map[string]any{
{"Name": "Lili", "Age": "22", "Gender": "female"},
{"Name": "Jim", "Age": "21", "Gender": "male"},
}
headers := []string{"Name", "Age", "Gender"}
err := WriteMapsToCsv(csvFilePath, records, false, ';', headers)
assert.IsNil(err)
content, err := ReadCsvFile(csvFilePath, ';')
assert.IsNil(err)
assert.Equal(3, len(content))
assert.Equal(3, len(content[0]))
assert.Equal("Lili", content[1][0])
assert.Equal("22", content[1][1])
assert.Equal("female", content[1][2])
}
func TestWriteStringToFile(t *testing.T) { func TestWriteStringToFile(t *testing.T) {
assert := internal.NewAssert(t, "TestWriteStringToFile") assert := internal.NewAssert(t, "TestWriteStringToFile")
@@ -476,3 +505,42 @@ Disallow: /deny
` `
internal.NewAssert(t, "TestReadFile").Equal(want, string(dat)) internal.NewAssert(t, "TestReadFile").Equal(want, string(dat))
} }
func TestReadlineFile(t *testing.T) {
path := "./testdata/demo.csv"
reader, err := NewFileReader(path)
if err != nil {
t.Fail()
}
defer reader.Close()
indexMap := make(map[string]int64)
defer reader.Close()
for {
offset := reader.Offset()
line, err := reader.ReadLine()
if err == io.EOF {
break
}
indexMap[line] = offset
}
lines, err := ReadFileByLine(path)
if err != nil {
t.Fail()
}
for _, line := range lines {
offset, ok := indexMap[line]
if !ok {
t.Fail()
}
if err = reader.Seek(offset); err != nil {
t.Fail()
}
lineRead, err := reader.ReadLine()
if err == io.EOF {
break
}
internal.NewAssert(t, "TestReadlineFile").Equal(line, lineRead)
}
}

View File

@@ -1,3 +1,5 @@
Lili,22,female Lili,22,female
Jim,21,male Jim,21,male
1 Lili 22 female
2 Jim 21 male
3
4
5

View File

@@ -1,3 +1,5 @@
Lili,22,female Lili,22,female
Jim,21,male Jim,21,male
1 Lili 22 female
2 Jim 21 male
3
4
5

3
fileutil/testdata/test3.csv vendored Normal file
View File

@@ -0,0 +1,3 @@
Name;Age;Gender
Lili;22;female
Jim;21;male
1 Name Age Gender
2 Lili 22 female
3 Jim 21 male

3
fileutil/testdata/test4.csv vendored Normal file
View File

@@ -0,0 +1,3 @@
Name;Age;Gender
Lili;22;female
Jim;21;male
1 Name Age Gender
2 Lili 22 female
3 Jim 21 male

View File

@@ -6,12 +6,11 @@ package formatter
import ( import (
"encoding/json" "encoding/json"
"fmt"
"io" "io"
"strconv"
"strings"
"github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/v2/convertor"
"github.com/duke-git/lancet/v2/strutil"
"github.com/duke-git/lancet/v2/validator"
"golang.org/x/exp/constraints" "golang.org/x/exp/constraints"
) )
@@ -20,31 +19,24 @@ import (
// Comma("12345", "$") => "$12,345", Comma(12345, "$") => "$12,345" // Comma("12345", "$") => "$12,345", Comma(12345, "$") => "$12,345"
// Play: https://go.dev/play/p/eRD5k2vzUVX // Play: https://go.dev/play/p/eRD5k2vzUVX
func Comma[T constraints.Float | constraints.Integer | string](value T, symbol string) string { func Comma[T constraints.Float | constraints.Integer | string](value T, symbol string) string {
if validator.IsInt(value) { numString := convertor.ToString(value)
v, err := convertor.ToInt(value)
if err != nil {
return ""
}
return symbol + commaInt(v)
}
if validator.IsFloat(value) { _, err := strconv.ParseFloat(numString, 64)
v, err := convertor.ToFloat(value) if err != nil {
if err != nil {
return ""
}
return symbol + commaFloat(v)
}
if strutil.IsString(value) {
v := fmt.Sprintf("%v", value)
if validator.IsNumberStr(v) {
return symbol + commaStr(v)
}
return "" return ""
} }
return "" index := strings.Index(numString, ".")
if index == -1 {
index = len(numString)
}
for index > 3 {
index = index - 3
numString = numString[:index] + "," + numString[index:]
}
return symbol + numString
} }
// Pretty data to JSON string. // Pretty data to JSON string.

View File

@@ -1,85 +0,0 @@
package formatter
import (
"bytes"
"math"
"strconv"
"strings"
)
// see https://github.com/dustin/go-humanize/blob/master/comma.go
func commaInt(v int64) string {
sign := ""
// Min int64 can't be negated to a usable value, so it has to be special cased.
if v == math.MinInt64 {
return "-9,223,372,036,854,775,808"
}
if v < 0 {
sign = "-"
v = 0 - v
}
parts := []string{"", "", "", "", "", "", ""}
j := len(parts) - 1
for v > 999 {
parts[j] = strconv.FormatInt(v%1000, 10)
switch len(parts[j]) {
case 2:
parts[j] = "0" + parts[j]
case 1:
parts[j] = "00" + parts[j]
}
v = v / 1000
j--
}
parts[j] = strconv.Itoa(int(v))
return sign + strings.Join(parts[j:], ",")
}
func commaFloat(v float64) string {
buf := &bytes.Buffer{}
if v < 0 {
buf.Write([]byte{'-'})
v = 0 - v
}
comma := []byte{','}
parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".")
pos := 0
if len(parts[0])%3 != 0 {
pos += len(parts[0]) % 3
buf.WriteString(parts[0][:pos])
buf.Write(comma)
}
for ; pos < len(parts[0]); pos += 3 {
buf.WriteString(parts[0][pos : pos+3])
buf.Write(comma)
}
buf.Truncate(buf.Len() - 1)
if len(parts) > 1 {
buf.Write([]byte{'.'})
buf.WriteString(parts[1])
}
return buf.String()
}
func commaStr(s string) string {
dotIndex := strings.Index(s, ".")
if dotIndex != -1 {
return commaStrRecursive(s[:dotIndex]) + s[dotIndex:]
}
return commaStrRecursive(s)
}
func commaStrRecursive(s string) string {
if len(s) <= 3 {
return s
}
return commaStrRecursive(s[:len(s)-3]) + "," + commaStrRecursive(s[len(s)-3:])
}

View File

@@ -330,10 +330,10 @@ func Cos(radian float64, precision ...int) float64 {
return TruncRound(radian, 3) return TruncRound(radian, 3)
} }
// Cos returns the sine of the radian argument. // Sin returns the sine of the radian argument.
// Play: https://go.dev/play/p/TWMQlMywDsP // Play: https://go.dev/play/p/TWMQlMywDsP
func Sin(radian float64, precision ...int) float64 { func Sin(radian float64, precision ...int) float64 {
return Cos((math.Pi / 2) - radian) return Cos((math.Pi/2)-radian, precision...)
} }
// Log returns the logarithm of base n. // Log returns the logarithm of base n.

View File

@@ -230,7 +230,6 @@ func UploadFile(filepath string, server string) (bool, error) {
} }
// DownloadFile will download the file exist in url to a local file. // DownloadFile will download the file exist in url to a local file.
// Play: todo
func DownloadFile(filepath string, url string) error { func DownloadFile(filepath string, url string) error {
resp, err := http.Get(url) resp, err := http.Get(url)
if err != nil { if err != nil {

View File

@@ -41,7 +41,7 @@ func RandInt(min, max int) int {
} }
// RandFloat generate random float64 number between [min, max) with specific precision. // RandFloat generate random float64 number between [min, max) with specific precision.
// Play: todo // Play: https://go.dev/play/p/zbD_tuobJtr
func RandFloat(min, max float64, precision int) float64 { func RandFloat(min, max float64, precision int) float64 {
if min == max { if min == max {
return min return min
@@ -103,7 +103,7 @@ func RandNumeralOrLetter(length int) string {
// RandSymbolChar generate a random symbol char of specified length. // RandSymbolChar generate a random symbol char of specified length.
// symbol chars: !@#$%^&*()_+-=[]{}|;':\",./<>?. // symbol chars: !@#$%^&*()_+-=[]{}|;':\",./<>?.
// Play: todo // Play: https://go.dev/play/p/Im6ZJxAykOm
func RandSymbolChar(length int) string { func RandSymbolChar(length int) string {
return random(SymbolChars, length) return random(SymbolChars, length)
} }
@@ -164,7 +164,7 @@ func RandUniqueIntSlice(n, min, max int) []int {
} }
// RandFloats generate a slice of random float64 numbers of length n that do not repeat. // RandFloats generate a slice of random float64 numbers of length n that do not repeat.
// Play: todo // Play: https://go.dev/play/p/I3yndUQ-rhh
func RandFloats(n int, min, max float64, precision int) []float64 { func RandFloats(n int, min, max float64, precision int) []float64 {
nums := make([]float64, n) nums := make([]float64, n)
used := make(map[float64]struct{}, n) used := make(map[float64]struct{}, n)

View File

@@ -498,20 +498,13 @@ func FlatMap[T any, U any](slice []T, iteratee func(index int, item T) []U) []U
// 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.
// Play: https://go.dev/play/p/_RfXJJWIsIm // Play: https://go.dev/play/p/_RfXJJWIsIm
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 len(slice) == 0 { accumulator := initial
return initial
for i, v := range slice {
accumulator = iteratee(i, v, accumulator)
} }
result := iteratee(0, initial, slice[0]) return accumulator
tmp := make([]T, 2)
for i := 1; i < len(slice); i++ {
tmp[0] = result
tmp[1] = slice[i]
result = iteratee(i, tmp[0], tmp[1])
}
return result
} }
// ReduceBy produces a value from slice by accumulating the result of each element as passed through the reducer function. // ReduceBy produces a value from slice by accumulating the result of each element as passed through the reducer function.
@@ -625,35 +618,34 @@ func IntSlice(slice any) []int {
return result return result
} }
// DeleteAt delete the element of slice from start index to end index - 1. // DeleteAt delete the element of slice at index.
// Play: https://go.dev/play/p/pJ-d6MUWcvK // Play: https://go.dev/play/p/pJ-d6MUWcvK
func DeleteAt[T any](slice []T, start int, end ...int) []T { func DeleteAt[T any](slice []T, index int) []T {
size := len(slice) if index >= len(slice) {
index = len(slice) - 1
if start < 0 || start >= size {
return slice
} }
if len(end) > 0 { result := make([]T, len(slice)-1)
end := end[0] copy(result, slice[:index])
if end <= start { copy(result[index:], slice[index+1:])
return slice
}
if end > size {
end = size
}
slice = append(slice[:start], slice[end:]...) return result
return slice }
// DeleteRange delete the element of slice from start index to end indexexclude).
// Play: todo
func DeleteRange[T any](slice []T, start, end int) []T {
result := make([]T, 0, len(slice)-(end-start))
for i := 0; i < start; i++ {
result = append(result, slice[i])
} }
if start == size-1 { for i := end; i < len(slice); i++ {
slice = slice[:start] result = append(result, slice[i])
} else {
slice = append(slice[:start], slice[start+1:]...)
} }
return slice return result
} }
// Drop drop n elements from the start of a slice. // Drop drop n elements from the start of a slice.
@@ -1232,7 +1224,7 @@ func Partition[T any](slice []T, predicates ...func(item T) bool) [][]T {
} }
// Random get a random item of slice, return idx=-1 when slice is empty // Random get a random item of slice, return idx=-1 when slice is empty
// Play: todo // Play: https://go.dev/play/p/UzpGQptWppw
func Random[T any](slice []T) (val T, idx int) { func Random[T any](slice []T) (val T, idx int) {
if len(slice) == 0 { if len(slice) == 0 {
return val, -1 return val, -1

View File

@@ -594,18 +594,46 @@ func ExampleIntSlice() {
} }
func ExampleDeleteAt() { func ExampleDeleteAt() {
result1 := DeleteAt([]string{"a", "b", "c"}, -1) chars := []string{"a", "b", "c", "d", "e"}
result2 := DeleteAt([]string{"a", "b", "c"}, 0)
result3 := DeleteAt([]string{"a", "b", "c"}, 0, 2) result1 := DeleteAt(chars, 0)
result2 := DeleteAt(chars, 4)
result3 := DeleteAt(chars, 5)
result4 := DeleteAt(chars, 6)
fmt.Println(result1) fmt.Println(result1)
fmt.Println(result2) fmt.Println(result2)
fmt.Println(result3) fmt.Println(result3)
fmt.Println(result4)
// Output: // Output:
// [a b c] // [b c d e]
// [b c] // [a b c d]
// [c] // [a b c d]
// [a b c d]
}
func ExampleDeleteRange() {
chars := []string{"a", "b", "c", "d", "e"}
result1 := DeleteRange(chars, 0, 0)
result2 := DeleteRange(chars, 0, 1)
result3 := DeleteRange(chars, 0, 3)
result4 := DeleteRange(chars, 0, 4)
result5 := DeleteRange(chars, 0, 5)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result5)
// Output:
// [a b c d e]
// [b c d e]
// [d e]
// [e]
// []
} }
func ExampleDrop() { func ExampleDrop() {

View File

@@ -572,19 +572,27 @@ func TestDeleteAt(t *testing.T) {
t.Parallel() t.Parallel()
assert := internal.NewAssert(t, "TestDeleteAt") assert := internal.NewAssert(t, "TestDeleteAt")
arr := []int{1, 2, 3, 4, 5}
assert.Equal([]string{"a", "b", "c"}, DeleteAt([]string{"a", "b", "c"}, -1)) assert.Equal([]int{2, 3, 4, 5}, DeleteAt(arr, 0))
assert.Equal([]string{"a", "b", "c"}, DeleteAt([]string{"a", "b", "c"}, 3)) assert.Equal([]int{1, 2, 3, 4}, DeleteAt(arr, 4))
assert.Equal([]string{"b", "c"}, DeleteAt([]string{"a", "b", "c"}, 0))
assert.Equal([]string{"a", "c"}, DeleteAt([]string{"a", "b", "c"}, 1))
assert.Equal([]string{"a", "b"}, DeleteAt([]string{"a", "b", "c"}, 2))
assert.Equal([]string{"b", "c"}, DeleteAt([]string{"a", "b", "c"}, 0, 1)) assert.Equal([]int{1, 2, 3, 4}, DeleteAt(arr, 5))
assert.Equal([]string{"c"}, DeleteAt([]string{"a", "b", "c"}, 0, 2)) assert.Equal([]int{1, 2, 3, 4}, DeleteAt(arr, 6))
assert.Equal([]string{}, DeleteAt([]string{"a", "b", "c"}, 0, 3))
assert.Equal([]string{}, DeleteAt([]string{"a", "b", "c"}, 0, 4)) assert.Equal([]int{1, 2, 3, 4, 5}, arr)
assert.Equal([]string{"a"}, DeleteAt([]string{"a", "b", "c"}, 1, 3)) }
assert.Equal([]string{"a"}, DeleteAt([]string{"a", "b", "c"}, 1, 4))
func TestDeleteRange(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestDeleteRange")
arr := []int{1, 2, 3, 4, 5}
assert.Equal([]int{1, 2, 3, 4, 5}, DeleteRange(arr, 0, 0))
assert.Equal([]int{2, 3, 4, 5}, DeleteRange(arr, 0, 1))
assert.Equal([]int{4, 5}, DeleteRange(arr, 0, 3))
} }
func TestDrop(t *testing.T) { func TestDrop(t *testing.T) {

View File

@@ -68,6 +68,11 @@ func (f *Field) IsSlice() bool {
return k == reflect.Slice return k == reflect.Slice
} }
// IsTargetType check if a struct field type is target type or not
func (f *Field) IsTargetType(targetType reflect.Kind) bool {
return f.rvalue.Kind() == targetType
}
// mapValue covert field value to map // mapValue covert field value to map
func (f *Field) mapValue(value any) any { func (f *Field) mapValue(value any) any {
val := pointer.ExtractPointer(value) val := pointer.ExtractPointer(value)

View File

@@ -154,6 +154,25 @@ func TestField_IsSlice(t *testing.T) {
assert.Equal(true, a.IsSlice()) assert.Equal(true, a.IsSlice())
} }
func TestField_IsTargetType(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestField_IsTargetType")
type Parent struct {
Name string
arr []int
}
p1 := &Parent{Name: "test", arr: []int{1, 2, 3}}
s := New(p1)
n, _ := s.Field("Name")
a, _ := s.Field("arr")
assert.Equal(true, n.IsTargetType(reflect.String))
assert.Equal(true, a.IsTargetType(reflect.Slice))
}
func TestField_MapValue(t *testing.T) { func TestField_MapValue(t *testing.T) {
t.Parallel() t.Parallel()

View File

@@ -14,12 +14,6 @@ func TestTryUnwrap(t *testing.T) {
assert := internal.NewAssert(t, "TestTryUnwrap") assert := internal.NewAssert(t, "TestTryUnwrap")
assert.Equal(42, TryUnwrap(strconv.Atoi("42"))) assert.Equal(42, TryUnwrap(strconv.Atoi("42")))
}
func TestTryUnwrapFail(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestTryUnwrapFail")
_, err := strconv.Atoi("4o2") _, err := strconv.Atoi("4o2")
defer func() { defer func() {
@@ -76,8 +70,6 @@ func TestXError_Unwrap(t *testing.T) {
} }
func TestXError_StackTrace(t *testing.T) { func TestXError_StackTrace(t *testing.T) {
// t.Parallel()
assert := internal.NewAssert(t, "TestXError_StackTrace") assert := internal.NewAssert(t, "TestXError_StackTrace")
err := New("error") err := New("error")
@@ -86,7 +78,7 @@ func TestXError_StackTrace(t *testing.T) {
assert.Equal(3, len(stacks)) assert.Equal(3, len(stacks))
assert.Equal("github.com/duke-git/lancet/v2/xerror.TestXError_StackTrace", stacks[0].Func) assert.Equal("github.com/duke-git/lancet/v2/xerror.TestXError_StackTrace", stacks[0].Func)
assert.Equal(83, stacks[0].Line) assert.Equal(75, stacks[0].Line)
assert.Equal(true, strings.Contains(stacks[0].File, "xerror_test.go")) assert.Equal(true, strings.Contains(stacks[0].File, "xerror_test.go"))
} }