mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-23 13:52:26 +08:00
Compare commits
21 Commits
v2.2.8
...
66dfd9c4fd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66dfd9c4fd | ||
|
|
be62aaac9b | ||
|
|
e0c9ccbce3 | ||
|
|
d2d1e5a055 | ||
|
|
bbc58c7e46 | ||
|
|
ac2ecceaec | ||
|
|
a06bb8ee6a | ||
|
|
27b5702fd3 | ||
|
|
b2c3fa0ab8 | ||
|
|
4afc838937 | ||
|
|
3482f80d1c | ||
|
|
565f2893b9 | ||
|
|
1b1b10d0ee | ||
|
|
c5c3888ffc | ||
|
|
11214986cc | ||
|
|
0bc7b83e59 | ||
|
|
6225418074 | ||
|
|
ddd265de78 | ||
|
|
80e48f06ca | ||
|
|
0b976e9a4c | ||
|
|
96320069f4 |
113
README.md
113
README.md
@@ -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. <a href="#index">index</a> </h3>
|
<h3 id="convertor"> 5. Convertor package contains some functions for data conversion. <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. <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. <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. <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. <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 index(exclude).
|
||||||
|
[[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. <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. <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. <a href="#index">index</a></h3>
|
<h3 id="strutil"> 21. Strutil package contains some functions to manipulate string. <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)]
|
||||||
|
|
||||||
|
|||||||
@@ -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。 <a href="#index">回到目录</a></h3>
|
<h3 id="retry"> 17. retry 重试执行函数直到函数运行成功或被 context cancel。 <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 实现,功能有限。 <a href="#index">回到目录</a></h3>
|
<h3 id="stream"> 19. stream 流,该包仅验证简单的 stream 实现,功能有限。 <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 包含字符串处理的相关函数。 <a href="#index">回到目录</a></h3>
|
<h3 id="strutil"> 21. strutil 包含字符串处理的相关函数。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 {
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -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
|
||||||
|
}
|
||||||
```
|
```
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -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 index(exclude)</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
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
```
|
||||||
173
fileutil/file.go
173
fileutil/file.go
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
2
fileutil/testdata/test1.csv
vendored
2
fileutil/testdata/test1.csv
vendored
@@ -1,3 +1,5 @@
|
|||||||
Lili,22,female
|
Lili,22,female
|
||||||
Jim,21,male
|
Jim,21,male
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
|
2
fileutil/testdata/test2.csv
vendored
2
fileutil/testdata/test2.csv
vendored
@@ -1,3 +1,5 @@
|
|||||||
Lili,22,female
|
Lili,22,female
|
||||||
Jim,21,male
|
Jim,21,male
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
|
3
fileutil/testdata/test3.csv
vendored
Normal file
3
fileutil/testdata/test3.csv
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Name;Age;Gender
|
||||||
|
Lili;22;female
|
||||||
|
Jim;21;male
|
||||||
|
3
fileutil/testdata/test4.csv
vendored
Normal file
3
fileutil/testdata/test4.csv
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Name;Age;Gender
|
||||||
|
Lili;22;female
|
||||||
|
Jim;21;male
|
||||||
|
@@ -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.
|
||||||
|
|||||||
@@ -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:])
|
|
||||||
}
|
|
||||||
@@ -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.
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 index(exclude).
|
||||||
|
// 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
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|
||||||
|
|||||||
@@ -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"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user