mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-23 13:52:26 +08:00
Compare commits
10 Commits
v2.2.2
...
17ff84fa1f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17ff84fa1f | ||
|
|
bf50baa07d | ||
|
|
7d56da8108 | ||
|
|
16c2df711b | ||
|
|
015f8c3f5c | ||
|
|
ba25701d89 | ||
|
|
a0cb4bb266 | ||
|
|
d6ba7497f9 | ||
|
|
7da931e0a0 | ||
|
|
8f49078eb3 |
@@ -284,8 +284,11 @@ import "github.com/duke-git/lancet/v2/convertor"
|
|||||||
[[play](https://go.dev/play/p/syqw0-WG7Xd)]
|
[[play](https://go.dev/play/p/syqw0-WG7Xd)]
|
||||||
- **<big>Utf8ToGbk</big>** : converts utf8 encoding data to GBK encoding data
|
- **<big>Utf8ToGbk</big>** : converts utf8 encoding data to GBK encoding data
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#Utf8ToGbk)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#Utf8ToGbk)]
|
||||||
|
[[play](https://go.dev/play/p/9FlIaFLArIL)]
|
||||||
- **<big>GbkToUtf8</big>** : converts GBK encoding data to utf8 encoding data.
|
- **<big>GbkToUtf8</big>** : converts GBK encoding data to utf8 encoding data.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#GbkToUtf8)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#GbkToUtf8)]
|
||||||
|
[[play](https://go.dev/play/p/OphmHCN_9u8)]
|
||||||
|
|
||||||
|
|
||||||
### 6. Cryptor package is for data encryption and decryption.
|
### 6. Cryptor package is for data encryption and decryption.
|
||||||
|
|
||||||
@@ -613,6 +616,7 @@ 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/fileutil.md#WriteCsvFile)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#WriteCsvFile)]
|
||||||
|
[[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/fileutil.md#WriteBytesToFile)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#WriteBytesToFile)]
|
||||||
[[play](https://go.dev/play/p/s7QlDxMj3P8)]
|
[[play](https://go.dev/play/p/s7QlDxMj3P8)]
|
||||||
@@ -835,8 +839,11 @@ import "github.com/duke-git/lancet/v2/mathutil"
|
|||||||
[[play](https://go.dev/play/p/TWMQlMywDsP)]
|
[[play](https://go.dev/play/p/TWMQlMywDsP)]
|
||||||
- **<big>Log</big>** : returns the logarithm of base n.
|
- **<big>Log</big>** : returns the logarithm of base n.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Log)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Log)]
|
||||||
|
[[play](https://go.dev/play/p/_d4bi8oyhat)]
|
||||||
- **<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/mathutil.md#Sum)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Sum)]
|
||||||
|
[[play](https://go.dev/play/p/1To2ImAMJA7)]
|
||||||
|
|
||||||
|
|
||||||
### 14. Netutil package contains functions to get net information and send http request.
|
### 14. Netutil package contains functions to get net information and send http request.
|
||||||
|
|
||||||
@@ -945,6 +952,8 @@ import "github.com/duke-git/lancet/v2/random"
|
|||||||
[[play](https://go.dev/play/p/_Z9SFmr28ft)]
|
[[play](https://go.dev/play/p/_Z9SFmr28ft)]
|
||||||
- **<big>RandUniqueIntSlice</big>** : generate a slice of random int of length n that do not repeat.
|
- **<big>RandUniqueIntSlice</big>** : generate a slice of random int of length n that do not repeat.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandUniqueIntSlice)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandUniqueIntSlice)]
|
||||||
|
[[play](https://go.dev/play/p/uBkRSOz73Ec)]
|
||||||
|
|
||||||
|
|
||||||
### 16. Retry package is for executing a function repeatedly until it was successful or canceled by the context.
|
### 16. Retry package is for executing a function repeatedly until it was successful or canceled by the context.
|
||||||
|
|
||||||
|
|||||||
@@ -283,8 +283,11 @@ import "github.com/duke-git/lancet/v2/convertor"
|
|||||||
[[play](https://go.dev/play/p/syqw0-WG7Xd)]
|
[[play](https://go.dev/play/p/syqw0-WG7Xd)]
|
||||||
- **<big>Utf8ToGbk</big>** : utf8 编码转 GBK 编码。
|
- **<big>Utf8ToGbk</big>** : utf8 编码转 GBK 编码。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#Utf8ToGbk)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#Utf8ToGbk)]
|
||||||
|
[[play](https://go.dev/play/p/9FlIaFLArIL)]
|
||||||
- **<big>GbkToUtf8</big>** : GBK 编码转 utf8 编码。
|
- **<big>GbkToUtf8</big>** : GBK 编码转 utf8 编码。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#GbkToUtf8)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#GbkToUtf8)]
|
||||||
|
[[play](https://go.dev/play/p/OphmHCN_9u8)]
|
||||||
|
|
||||||
|
|
||||||
### 6. cryptor 加密包支持数据加密和解密,获取 md5,hash 值。支持 base64, md5, hmac, aes, des, rsa。
|
### 6. cryptor 加密包支持数据加密和解密,获取 md5,hash 值。支持 base64, md5, hmac, aes, des, rsa。
|
||||||
|
|
||||||
@@ -614,6 +617,7 @@ 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>** : 向 csv 文件写入内容。
|
- **<big>WriteCsvFile</big>** : 向 csv 文件写入内容。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#WriteCsvFile)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#WriteCsvFile)]
|
||||||
|
[[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/fileutil_zh-CN.md#WriteBytesToFile)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#WriteBytesToFile)]
|
||||||
[[play](https://go.dev/play/p/s7QlDxMj3P8)]
|
[[play](https://go.dev/play/p/s7QlDxMj3P8)]
|
||||||
@@ -835,8 +839,11 @@ import "github.com/duke-git/lancet/v2/mathutil"
|
|||||||
[[play](https://go.dev/play/p/TWMQlMywDsP)]
|
[[play](https://go.dev/play/p/TWMQlMywDsP)]
|
||||||
- **<big>Log</big>** : 计算以 base 为底 n 的对数。
|
- **<big>Log</big>** : 计算以 base 为底 n 的对数。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Log)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Log)]
|
||||||
|
[[play](https://go.dev/play/p/_d4bi8oyhat)]
|
||||||
- **<big>Sum</big>** : 求传入参数之和。
|
- **<big>Sum</big>** : 求传入参数之和。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Sum)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Sum)]
|
||||||
|
[[play](https://go.dev/play/p/1To2ImAMJA7)]
|
||||||
|
|
||||||
|
|
||||||
### 14. netutil 网络包支持获取 ip 地址,发送 http 请求。
|
### 14. netutil 网络包支持获取 ip 地址,发送 http 请求。
|
||||||
|
|
||||||
@@ -945,6 +952,8 @@ import "github.com/duke-git/lancet/v2/random"
|
|||||||
[[play](https://go.dev/play/p/_Z9SFmr28ft)]
|
[[play](https://go.dev/play/p/_Z9SFmr28ft)]
|
||||||
- **<big>RandUniqueIntSlice</big>** : 生成一个不重复的长度为n的随机int切片。
|
- **<big>RandUniqueIntSlice</big>** : 生成一个不重复的长度为n的随机int切片。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandUniqueIntSlice)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandUniqueIntSlice)]
|
||||||
|
[[play](https://go.dev/play/p/uBkRSOz73Ec)]
|
||||||
|
|
||||||
|
|
||||||
### 16. retry 重试执行函数直到函数运行成功或被 context cancel。
|
### 16. retry 重试执行函数直到函数运行成功或被 context cancel。
|
||||||
|
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ func ToInterface(v reflect.Value) (value interface{}, ok bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Utf8ToGbk convert utf8 encoding data to GBK encoding data.
|
// Utf8ToGbk convert utf8 encoding data to GBK encoding data.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/9FlIaFLArIL
|
||||||
func Utf8ToGbk(bs []byte) ([]byte, error) {
|
func Utf8ToGbk(bs []byte) ([]byte, error) {
|
||||||
r := transform.NewReader(bytes.NewReader(bs), simplifiedchinese.GBK.NewEncoder())
|
r := transform.NewReader(bytes.NewReader(bs), simplifiedchinese.GBK.NewEncoder())
|
||||||
b, err := io.ReadAll(r)
|
b, err := io.ReadAll(r)
|
||||||
@@ -388,7 +388,7 @@ func Utf8ToGbk(bs []byte) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GbkToUtf8 convert GBK encoding data to utf8 encoding data.
|
// GbkToUtf8 convert GBK encoding data to utf8 encoding data.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/OphmHCN_9u8
|
||||||
func GbkToUtf8(bs []byte) ([]byte, error) {
|
func GbkToUtf8(bs []byte) ([]byte, error) {
|
||||||
r := transform.NewReader(bytes.NewReader(bs), simplifiedchinese.GBK.NewDecoder())
|
r := transform.NewReader(bytes.NewReader(bs), simplifiedchinese.GBK.NewDecoder())
|
||||||
b, err := io.ReadAll(r)
|
b, err := io.ReadAll(r)
|
||||||
|
|||||||
@@ -40,6 +40,14 @@ func Md5String(s string) string {
|
|||||||
return hex.EncodeToString(h.Sum(nil))
|
return hex.EncodeToString(h.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Md5String return the md5 string of byte slice.
|
||||||
|
// Play: todo
|
||||||
|
func Md5Byte(data []byte) string {
|
||||||
|
h := md5.New()
|
||||||
|
h.Write(data)
|
||||||
|
return hex.EncodeToString(h.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
// Md5File return the md5 value of file.
|
// Md5File return the md5 value of file.
|
||||||
func Md5File(filename string) (string, error) {
|
func Md5File(filename string) (string, error) {
|
||||||
if fileInfo, err := os.Stat(filename); err != nil {
|
if fileInfo, err := os.Stat(filename); err != nil {
|
||||||
|
|||||||
@@ -21,6 +21,12 @@ func TestMd5String(t *testing.T) {
|
|||||||
assert.Equal("5d41402abc4b2a76b9719d911017c592", Md5String("hello"))
|
assert.Equal("5d41402abc4b2a76b9719d911017c592", Md5String("hello"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMd5Byte(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestMd5Byte")
|
||||||
|
data := []byte{'a'}
|
||||||
|
assert.Equal("0cc175b9c0f1b6a831c399e269772661", Md5Byte(data))
|
||||||
|
}
|
||||||
|
|
||||||
func TestMd5File(t *testing.T) {
|
func TestMd5File(t *testing.T) {
|
||||||
fileMd5, err := Md5File("./basic.go")
|
fileMd5, err := Md5File("./basic.go")
|
||||||
assert := internal.NewAssert(t, "TestMd5File")
|
assert := internal.NewAssert(t, "TestMd5File")
|
||||||
|
|||||||
@@ -366,21 +366,22 @@ func ExampleHmacSha512() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExampleMd5String() {
|
func ExampleMd5String() {
|
||||||
str := "hello"
|
md5Str := Md5String("hello")
|
||||||
|
|
||||||
md5Str := Md5String(str)
|
|
||||||
|
|
||||||
fmt.Println(md5Str)
|
fmt.Println(md5Str)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 5d41402abc4b2a76b9719d911017c592
|
// 5d41402abc4b2a76b9719d911017c592
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleMd5Byte() {
|
||||||
|
md5Str := Md5Byte([]byte{'a'})
|
||||||
|
fmt.Println(md5Str)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0cc175b9c0f1b6a831c399e269772661
|
||||||
|
}
|
||||||
func ExampleSha1() {
|
func ExampleSha1() {
|
||||||
str := "hello"
|
result := Sha1("hello")
|
||||||
|
|
||||||
result := Sha1(str)
|
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
@@ -388,10 +389,7 @@ func ExampleSha1() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExampleSha256() {
|
func ExampleSha256() {
|
||||||
str := "hello"
|
result := Sha256("hello")
|
||||||
|
|
||||||
result := Sha256(str)
|
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
@@ -399,10 +397,7 @@ func ExampleSha256() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExampleSha512() {
|
func ExampleSha512() {
|
||||||
str := "hello"
|
result := Sha512("hello")
|
||||||
|
|
||||||
result := Sha512(str)
|
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
|
|||||||
@@ -96,6 +96,18 @@ func GetNowDateTime() string {
|
|||||||
return time.Now().Format("2006-01-02 15:04:05")
|
return time.Now().Format("2006-01-02 15:04:05")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTodayStartTime return the start time of today, format: yyyy-mm-dd 00:00:00.
|
||||||
|
// Play: todo
|
||||||
|
func GetTodayStartTime() string {
|
||||||
|
return time.Now().Format("2006-01-02") + " 00:00:00"
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTodayEndTime return the end time of today, format: yyyy-mm-dd 23:59:59.
|
||||||
|
// Play: todo
|
||||||
|
func GetTodayEndTime() string {
|
||||||
|
return time.Now().Format("2006-01-02") + " 23:59:59"
|
||||||
|
}
|
||||||
|
|
||||||
// GetZeroHourTimestamp return timestamp of zero hour (timestamp of 00:00).
|
// GetZeroHourTimestamp return timestamp of zero hour (timestamp of 00:00).
|
||||||
// Play: https://go.dev/play/p/QmL2oIaGE3q
|
// Play: https://go.dev/play/p/QmL2oIaGE3q
|
||||||
func GetZeroHourTimestamp() int64 {
|
func GetZeroHourTimestamp() int64 {
|
||||||
|
|||||||
@@ -91,6 +91,18 @@ func TestGetNowDateTime(t *testing.T) {
|
|||||||
assert.Equal(expected, GetNowDateTime())
|
assert.Equal(expected, GetNowDateTime())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetTodayStartTime(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestGetTodayStartTime")
|
||||||
|
expected := time.Now().Format("2006-01-02") + " 00:00:00"
|
||||||
|
assert.Equal(expected, GetTodayStartTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetTodayEndTime(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestGetTodayEndTime")
|
||||||
|
expected := time.Now().Format("2006-01-02") + " 23:59:59"
|
||||||
|
assert.Equal(expected, GetTodayEndTime())
|
||||||
|
}
|
||||||
|
|
||||||
func TestFormatTimeToStr(t *testing.T) {
|
func TestFormatTimeToStr(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestFormatTimeToStr")
|
assert := internal.NewAssert(t, "TestFormatTimeToStr")
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import (
|
|||||||
- [HmacSha256](#HmacSha256)
|
- [HmacSha256](#HmacSha256)
|
||||||
- [HmacSha512](#HmacSha512)
|
- [HmacSha512](#HmacSha512)
|
||||||
- [Md5String](#Md5String)
|
- [Md5String](#Md5String)
|
||||||
|
- [Md5Byte](#Md5Byte)
|
||||||
- [Md5File](#Md5File)
|
- [Md5File](#Md5File)
|
||||||
- [Sha1](#Sha1)
|
- [Sha1](#Sha1)
|
||||||
- [Sha256](#Sha256)
|
- [Sha256](#Sha256)
|
||||||
@@ -880,6 +881,35 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="Md5Byte">Md5Byte</span>
|
||||||
|
|
||||||
|
<p>Return the md5 string of byte slice.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Md5Byte(data []byte) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/cryptor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
md5Str := cryptor.Md5Byte([]byte{'a'})
|
||||||
|
fmt.Println(md5Str)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0cc175b9c0f1b6a831c399e269772661
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Md5File">Md5File</span>
|
### <span id="Md5File">Md5File</span>
|
||||||
|
|
||||||
<p>Get the md5 value of file.</p>
|
<p>Get the md5 value of file.</p>
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import (
|
|||||||
- [HmacSha256](#HmacSha256)
|
- [HmacSha256](#HmacSha256)
|
||||||
- [HmacSha512](#HmacSha512)
|
- [HmacSha512](#HmacSha512)
|
||||||
- [Md5String](#Md5String)
|
- [Md5String](#Md5String)
|
||||||
|
- [Md5Byte](#Md5Byte)
|
||||||
- [Md5File](#Md5File)
|
- [Md5File](#Md5File)
|
||||||
- [Sha1](#Sha1)
|
- [Sha1](#Sha1)
|
||||||
- [Sha256](#Sha256)
|
- [Sha256](#Sha256)
|
||||||
@@ -879,6 +880,35 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="Md5Byte">Md5Byte</span>
|
||||||
|
|
||||||
|
<p>获取byte slice的md5至。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Md5Byte(data []byte) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/cryptor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
md5Str := cryptor.Md5Byte([]byte{'a'})
|
||||||
|
fmt.Println(md5Str)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0cc175b9c0f1b6a831c399e269772661
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Md5File">Md5File</span>
|
### <span id="Md5File">Md5File</span>
|
||||||
|
|
||||||
<p>获取文件md5值。</p>
|
<p>获取文件md5值。</p>
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ import (
|
|||||||
- [GetNowDate](#GetNowDate)
|
- [GetNowDate](#GetNowDate)
|
||||||
- [GetNowTime](#GetNowTime)
|
- [GetNowTime](#GetNowTime)
|
||||||
- [GetNowDateTime](#GetNowDateTime)
|
- [GetNowDateTime](#GetNowDateTime)
|
||||||
|
- [GetTodayStartTime](#GetTodayStartTime)
|
||||||
|
- [GetTodayEndTime](#GetTodayEndTime)
|
||||||
- [GetZeroHourTimestamp](#GetZeroHourTimestamp)
|
- [GetZeroHourTimestamp](#GetZeroHourTimestamp)
|
||||||
- [GetNightTimestamp](#GetNightTimestamp)
|
- [GetNightTimestamp](#GetNightTimestamp)
|
||||||
- [FormatTimeToStr](#FormatTimeToStr)
|
- [FormatTimeToStr](#FormatTimeToStr)
|
||||||
@@ -643,14 +645,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
"github.com/duke-git/lancet/v2/datetime"
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
|
||||||
currentDate := datetime.GetNowDate()
|
currentDate := datetime.GetNowDate()
|
||||||
|
|
||||||
fmt.Println(currentDate)
|
fmt.Println(currentDate)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
@@ -675,14 +674,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
"github.com/duke-git/lancet/v2/datetime"
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
|
||||||
currentTime := datetime.GetNowTime()
|
currentTime := datetime.GetNowTime()
|
||||||
|
|
||||||
fmt.Println(currentTime) // 15:57:33
|
fmt.Println(currentTime) // 15:57:33
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
@@ -707,14 +703,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
"github.com/duke-git/lancet/v2/datetime"
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
|
||||||
current := datetime.GetNowDateTime()
|
current := datetime.GetNowDateTime()
|
||||||
|
|
||||||
fmt.Println(current)
|
fmt.Println(current)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
@@ -722,6 +715,64 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="GetTodayStartTime">GetTodayStartTime</span>
|
||||||
|
|
||||||
|
<p>Return the start time of today, format: yyyy-mm-dd 00:00:00.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GetTodayStartTime() string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
startTime := datetime.GetTodayStartTime()
|
||||||
|
fmt.Println(startTime)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2023-06-29 00:00:00
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GetTodayEndTime">GetTodayEndTime</span>
|
||||||
|
|
||||||
|
<p>Return the end time of today, format: yyyy-mm-dd 23:59:59.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GetTodayEndTime() string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
endTime := datetime.GetTodayEndTime()
|
||||||
|
fmt.Println(endTime)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2023-06-29 23:59:59
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span>
|
### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span>
|
||||||
|
|
||||||
<p>Return timestamp of zero hour (timestamp of 00:00).</p>
|
<p>Return timestamp of zero hour (timestamp of 00:00).</p>
|
||||||
@@ -739,14 +790,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
"github.com/duke-git/lancet/v2/datetime"
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
|
||||||
zeroTime := datetime.GetZeroHourTimestamp()
|
zeroTime := datetime.GetZeroHourTimestamp()
|
||||||
|
|
||||||
fmt.Println(zeroTime)
|
fmt.Println(zeroTime)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
@@ -771,14 +819,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
"github.com/duke-git/lancet/v2/datetime"
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
|
||||||
nightTime := datetime.GetNightTimestamp()
|
nightTime := datetime.GetNightTimestamp()
|
||||||
|
|
||||||
fmt.Println(nightTime)
|
fmt.Println(nightTime)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ import (
|
|||||||
- [GetNowDate](#GetNowDate)
|
- [GetNowDate](#GetNowDate)
|
||||||
- [GetNowTime](#GetNowTime)
|
- [GetNowTime](#GetNowTime)
|
||||||
- [GetNowDateTime](#GetNowDateTime)
|
- [GetNowDateTime](#GetNowDateTime)
|
||||||
|
- [GetTodayStartTime](#GetTodayStartTime)
|
||||||
|
- [GetTodayEndTime](#GetTodayEndTime)
|
||||||
- [GetZeroHourTimestamp](#GetZeroHourTimestamp)
|
- [GetZeroHourTimestamp](#GetZeroHourTimestamp)
|
||||||
- [GetNightTimestamp](#GetNightTimestamp)
|
- [GetNightTimestamp](#GetNightTimestamp)
|
||||||
- [FormatTimeToStr](#FormatTimeToStr)
|
- [FormatTimeToStr](#FormatTimeToStr)
|
||||||
@@ -643,14 +645,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
"github.com/duke-git/lancet/v2/datetime"
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
|
||||||
currentDate := datetime.GetNowDate()
|
currentDate := datetime.GetNowDate()
|
||||||
|
|
||||||
fmt.Println(currentDate)
|
fmt.Println(currentDate)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
@@ -675,15 +674,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
"github.com/duke-git/lancet/v2/datetime"
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
|
||||||
currentTime := datetime.GetNowTime()
|
currentTime := datetime.GetNowTime()
|
||||||
|
fmt.Println(currentTime)
|
||||||
fmt.Println(currentTime) // 15:57:33
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 15:57:33
|
// 15:57:33
|
||||||
@@ -707,14 +703,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
"github.com/duke-git/lancet/v2/datetime"
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
|
||||||
current := datetime.GetNowDateTime()
|
current := datetime.GetNowDateTime()
|
||||||
|
|
||||||
fmt.Println(current)
|
fmt.Println(current)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
@@ -722,6 +715,64 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="GetTodayStartTime">GetTodayStartTime</span>
|
||||||
|
|
||||||
|
<p>返回当天开始时间, 格式: yyyy-mm-dd 00:00:00.</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GetTodayStartTime() string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
startTime := datetime.GetTodayStartTime()
|
||||||
|
fmt.Println(startTime)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2023-06-29 00:00:00
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GetTodayEndTime">GetTodayEndTime</span>
|
||||||
|
|
||||||
|
<p>返回当天结束时间,格式: yyyy-mm-dd 23:59:59.</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GetTodayEndTime() string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
endTime := datetime.GetTodayEndTime()
|
||||||
|
fmt.Println(endTime)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2023-06-29 23:59:59
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span>
|
### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span>
|
||||||
|
|
||||||
<p>获取零点时间戳(timestamp of 00:00)</p>
|
<p>获取零点时间戳(timestamp of 00:00)</p>
|
||||||
@@ -739,14 +790,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
"github.com/duke-git/lancet/v2/datetime"
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
|
||||||
zeroTime := datetime.GetZeroHourTimestamp()
|
zeroTime := datetime.GetZeroHourTimestamp()
|
||||||
|
|
||||||
fmt.Println(zeroTime)
|
fmt.Println(zeroTime)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
@@ -771,14 +819,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
"github.com/duke-git/lancet/v2/datetime"
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
|
||||||
nightTime := datetime.GetNightTimestamp()
|
nightTime := datetime.GetNightTimestamp()
|
||||||
|
|
||||||
fmt.Println(nightTime)
|
fmt.Println(nightTime)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
|
|||||||
@@ -714,18 +714,30 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
fpath := "./test.csv"
|
||||||
|
fileutil.CreateFile(fpath)
|
||||||
|
|
||||||
|
f, _ := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
data := [][]string{
|
data := [][]string{
|
||||||
{"Lili", "22", "female"},
|
{"Lili", "22", "female"},
|
||||||
{"Jim", "21", "male"},
|
{"Jim", "21", "male"},
|
||||||
}
|
}
|
||||||
err := WriteCsvFile("./testdata/test2.csv", data, false)
|
err := fileutil.WriteCsvFile(fpath, data, false)
|
||||||
fmt.Println(err)
|
|
||||||
|
|
||||||
content, _ := ReadCsvFile("./testdata/test2.csv")
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := fileutil.ReadCsvFile(fpath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
fmt.Println(content)
|
fmt.Println(content)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// <nil>
|
|
||||||
// [[Lili 22 female] [Jim 21 male]]
|
// [[Lili 22 female] [Jim 21 male]]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -714,18 +714,30 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
fpath := "./test.csv"
|
||||||
|
fileutil.CreateFile(fpath)
|
||||||
|
|
||||||
|
f, _ := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
data := [][]string{
|
data := [][]string{
|
||||||
{"Lili", "22", "female"},
|
{"Lili", "22", "female"},
|
||||||
{"Jim", "21", "male"},
|
{"Jim", "21", "male"},
|
||||||
}
|
}
|
||||||
err := WriteCsvFile("./testdata/test2.csv", data, false)
|
err := fileutil.WriteCsvFile(fpath, data, false)
|
||||||
fmt.Println(err)
|
|
||||||
|
|
||||||
content, _ := ReadCsvFile("./testdata/test2.csv")
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := fileutil.ReadCsvFile(fpath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
fmt.Println(content)
|
fmt.Println(content)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// <nil>
|
|
||||||
// [[Lili 22 female] [Jim 21 male]]
|
// [[Lili 22 female] [Jim 21 male]]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ import (
|
|||||||
- [Sin](#Sin)
|
- [Sin](#Sin)
|
||||||
- [Log](#Log)
|
- [Log](#Log)
|
||||||
- [Sum](#Sum)
|
- [Sum](#Sum)
|
||||||
|
- [Abs](#Abs)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -943,3 +945,39 @@ func main() {
|
|||||||
// 1.1
|
// 1.1
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="Abs">Abs</span>
|
||||||
|
|
||||||
|
<p>Returns the absolute value of x.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Abs[T constraints.Integer | constraints.Float](x T) T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := Abs(-1)
|
||||||
|
result2 := Abs(-0.1)
|
||||||
|
result3 := Abs(float32(0.2))
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
// 0.1
|
||||||
|
// 0.2
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -46,6 +46,7 @@ import (
|
|||||||
- [Sin](#Sin)
|
- [Sin](#Sin)
|
||||||
- [Log](#Log)
|
- [Log](#Log)
|
||||||
- [Sum](#Sum)
|
- [Sum](#Sum)
|
||||||
|
- [Abs](#Abs)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -941,3 +942,39 @@ func main() {
|
|||||||
// 1.1
|
// 1.1
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="Abs">Abs</span>
|
||||||
|
|
||||||
|
<p>求绝对值。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Abs[T constraints.Integer | constraints.Float](x T) T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := Abs(-1)
|
||||||
|
result2 := Abs(-0.1)
|
||||||
|
result3 := Abs(float32(0.2))
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
// 0.1
|
||||||
|
// 0.2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
result := RandUniqueIntSlice(5, 0, 10)
|
result := random.RandUniqueIntSlice(5, 0, 10)
|
||||||
fmt.Println(result) //[0 4 7 1 5] (random)
|
fmt.Println(result) //[0 4 7 1 5] (random)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
result := RandUniqueIntSlice(5, 0, 10)
|
result := random.RandUniqueIntSlice(5, 0, 10)
|
||||||
fmt.Println(result) //[0 4 7 1 5] (random)
|
fmt.Println(result) //[0 4 7 1 5] (random)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -507,7 +507,7 @@ func ReadCsvFile(filepath string) ([][]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WriteCsvFile write content to target csv file.
|
// WriteCsvFile write content to target csv file.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/dAXm58Q5U1o
|
||||||
func WriteCsvFile(filepath string, records [][]string, append bool) error {
|
func WriteCsvFile(filepath string, records [][]string, append bool) error {
|
||||||
flag := os.O_RDWR | os.O_CREATE
|
flag := os.O_RDWR | os.O_CREATE
|
||||||
|
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ func MinBy[T any](slice []T, comparator func(T, T) bool) T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sum return sum of passed numbers.
|
// Sum return sum of passed numbers.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/1To2ImAMJA7
|
||||||
func Sum[T constraints.Integer | constraints.Float](numbers ...T) T {
|
func Sum[T constraints.Integer | constraints.Float](numbers ...T) T {
|
||||||
var sum T
|
var sum T
|
||||||
|
|
||||||
@@ -337,7 +337,17 @@ func Sin(radian float64, precision ...int) float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Log returns the logarithm of base n.
|
// Log returns the logarithm of base n.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/_d4bi8oyhat
|
||||||
func Log(n, base float64) float64 {
|
func Log(n, base float64) float64 {
|
||||||
return math.Log(n) / math.Log(base)
|
return math.Log(n) / math.Log(base)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Abs returns the absolute value of x.
|
||||||
|
// Play: todo
|
||||||
|
func Abs[T constraints.Integer | constraints.Float](x T) T {
|
||||||
|
if x < 0 {
|
||||||
|
return (-x)
|
||||||
|
}
|
||||||
|
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|||||||
@@ -389,3 +389,18 @@ func ExampleLog() {
|
|||||||
// 2.32
|
// 2.32
|
||||||
// 3
|
// 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleAbs() {
|
||||||
|
result1 := Abs(-1)
|
||||||
|
result2 := Abs(-0.1)
|
||||||
|
result3 := Abs(float32(0.2))
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
// 0.1
|
||||||
|
// 0.2
|
||||||
|
}
|
||||||
|
|||||||
@@ -285,3 +285,16 @@ func TestLog(t *testing.T) {
|
|||||||
assert.EqualValues(3, TruncRound(Log(27, 3), 0))
|
assert.EqualValues(3, TruncRound(Log(27, 3), 0))
|
||||||
assert.EqualValues(2.32, TruncRound(Log(5, 2), 2))
|
assert.EqualValues(2.32, TruncRound(Log(5, 2), 2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAbs(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestAbs")
|
||||||
|
|
||||||
|
assert.Equal(0, Abs(0))
|
||||||
|
assert.Equal(1, Abs(-1))
|
||||||
|
|
||||||
|
assert.Equal(0.1, Abs(-0.1))
|
||||||
|
|
||||||
|
assert.Equal(int64(1), Abs(int64(-1)))
|
||||||
|
assert.Equal(float32(1), Abs(float32(-1)))
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,19 +7,19 @@ package pointer
|
|||||||
import "reflect"
|
import "reflect"
|
||||||
|
|
||||||
// Of returns a pointer to the value `v`.
|
// Of returns a pointer to the value `v`.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/HFd70x4DrMj
|
||||||
func Of[T any](v T) *T {
|
func Of[T any](v T) *T {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unwrap returns the value from the pointer.
|
// Unwrap returns the value from the pointer.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/cgeu3g7cjWb
|
||||||
func Unwrap[T any](p *T) T {
|
func Unwrap[T any](p *T) T {
|
||||||
return *p
|
return *p
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractPointer returns the underlying value by the given interface type
|
// ExtractPointer returns the underlying value by the given interface type
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/D7HFjeWU2ZP
|
||||||
func ExtractPointer(value any) any {
|
func ExtractPointer(value any) any {
|
||||||
t := reflect.TypeOf(value)
|
t := reflect.TypeOf(value)
|
||||||
v := reflect.ValueOf(value)
|
v := reflect.ValueOf(value)
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ func UUIdV4() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RandUniqueIntSlice generate a slice of random int of length n that do not repeat.
|
// RandUniqueIntSlice generate a slice of random int of length n that do not repeat.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/uBkRSOz73Ec
|
||||||
func RandUniqueIntSlice(n, min, max int) []int {
|
func RandUniqueIntSlice(n, min, max int) []int {
|
||||||
if min > max {
|
if min > max {
|
||||||
return []int{}
|
return []int{}
|
||||||
|
|||||||
@@ -561,7 +561,7 @@ var (
|
|||||||
|
|
||||||
// RemoveWhiteSpace remove whitespace characters from a string.
|
// RemoveWhiteSpace remove whitespace characters from a string.
|
||||||
// when set repalceAll is true removes all whitespace, false only replaces consecutive whitespace characters with one space.
|
// when set repalceAll is true removes all whitespace, false only replaces consecutive whitespace characters with one space.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/HzLC9vsTwkf
|
||||||
func RemoveWhiteSpace(str string, repalceAll bool) string {
|
func RemoveWhiteSpace(str string, repalceAll bool) string {
|
||||||
if repalceAll && str != "" {
|
if repalceAll && str != "" {
|
||||||
return strings.Join(strings.Fields(str), "")
|
return strings.Join(strings.Fields(str), "")
|
||||||
|
|||||||
641
tuple/tuple.go
Normal file
641
tuple/tuple.go
Normal file
@@ -0,0 +1,641 @@
|
|||||||
|
// Copyright 2023 dudaodong@gmail.com. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
// Package tuple implements tuple data type and some operations on it.
|
||||||
|
package tuple
|
||||||
|
|
||||||
|
import "github.com/duke-git/lancet/v2/mathutil"
|
||||||
|
|
||||||
|
// Tuple2 represents a 2 elemnets tuple
|
||||||
|
type Tuple2[A any, B any] struct {
|
||||||
|
FieldA A
|
||||||
|
FieldB B
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbox returns values in tuple.
|
||||||
|
// Play: todo
|
||||||
|
func (t Tuple2[A, B]) Unbox() (A, B) {
|
||||||
|
return t.FieldA, t.FieldB
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTuple2 creates a 2 elemnets tuple from a list of values.
|
||||||
|
// Play: todo
|
||||||
|
func NewTuple2[A any, B any](a A, b B) Tuple2[A, B] {
|
||||||
|
return Tuple2[A, B]{FieldA: a, FieldB: b}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip2 create a slice of Tuple2, whose elements are correspond to the given slice elements.
|
||||||
|
// Play: todo
|
||||||
|
func Zip2[A any, B any](a []A, b []B) []Tuple2[A, B] {
|
||||||
|
size := mathutil.Max(len(a), len(b))
|
||||||
|
|
||||||
|
tuples := make([]Tuple2[A, B], size)
|
||||||
|
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
v1, _ := getByIndex(a, i)
|
||||||
|
v2, _ := getByIndex(b, i)
|
||||||
|
|
||||||
|
tuples[i] = Tuple2[A, B]{FieldA: v1, FieldB: v2}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuples
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unzip2 creates a group of slice from a slice of Tuple2.
|
||||||
|
// Play: todo
|
||||||
|
func Unzip2[A any, B any](tuples []Tuple2[A, B]) ([]A, []B) {
|
||||||
|
size := len(tuples)
|
||||||
|
|
||||||
|
r1 := make([]A, size)
|
||||||
|
r2 := make([]B, size)
|
||||||
|
|
||||||
|
for i, t := range tuples {
|
||||||
|
r1[i] = t.FieldA
|
||||||
|
r2[i] = t.FieldB
|
||||||
|
}
|
||||||
|
|
||||||
|
return r1, r2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tuple3 represents a 3 elemnets tuple
|
||||||
|
type Tuple3[A any, B any, C any] struct {
|
||||||
|
FieldA A
|
||||||
|
FieldB B
|
||||||
|
FieldC C
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbox returns values in tuple.
|
||||||
|
// Play: todo
|
||||||
|
func (t Tuple3[A, B, C]) Unbox() (A, B, C) {
|
||||||
|
return t.FieldA, t.FieldB, t.FieldC
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTuple3 creates a 3 elemnets tuple from a list of values.
|
||||||
|
// Play: todo
|
||||||
|
func NewTuple3[A any, B any, C any](a A, b B, c C) Tuple3[A, B, C] {
|
||||||
|
return Tuple3[A, B, C]{FieldA: a, FieldB: b, FieldC: c}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip3 create a slice of Tuple3, whose elements are correspond to the given slice elements.
|
||||||
|
// Play: todo
|
||||||
|
func Zip3[A any, B any, C any](a []A, b []B, c []C) []Tuple3[A, B, C] {
|
||||||
|
size := mathutil.Max(len(a), len(b), len(c))
|
||||||
|
|
||||||
|
tuples := make([]Tuple3[A, B, C], size)
|
||||||
|
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
v1, _ := getByIndex(a, i)
|
||||||
|
v2, _ := getByIndex(b, i)
|
||||||
|
v3, _ := getByIndex(c, i)
|
||||||
|
|
||||||
|
tuples[i] = Tuple3[A, B, C]{FieldA: v1, FieldB: v2, FieldC: v3}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuples
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unzip3 creates a group of slice from a slice of Tuple3.
|
||||||
|
// Play: todo
|
||||||
|
func Unzip3[A any, B any, C any](tuples []Tuple3[A, B, C]) ([]A, []B, []C) {
|
||||||
|
size := len(tuples)
|
||||||
|
|
||||||
|
r1 := make([]A, size)
|
||||||
|
r2 := make([]B, size)
|
||||||
|
r3 := make([]C, size)
|
||||||
|
|
||||||
|
for i, t := range tuples {
|
||||||
|
r1[i] = t.FieldA
|
||||||
|
r2[i] = t.FieldB
|
||||||
|
r3[i] = t.FieldC
|
||||||
|
}
|
||||||
|
|
||||||
|
return r1, r2, r3
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tuple4 represents a 4 elemnets tuple
|
||||||
|
type Tuple4[A any, B any, C any, D any] struct {
|
||||||
|
FieldA A
|
||||||
|
FieldB B
|
||||||
|
FieldC C
|
||||||
|
FieldD D
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbox returns values in tuple.
|
||||||
|
// Play: todo
|
||||||
|
func (t Tuple4[A, B, C, D]) Unbox() (A, B, C, D) {
|
||||||
|
return t.FieldA, t.FieldB, t.FieldC, t.FieldD
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTuple4 creates a 4 elemnets tuple from a list of values.
|
||||||
|
// Play: todo
|
||||||
|
func NewTuple4[A any, B any, C any, D any](a A, b B, c C, d D) Tuple4[A, B, C, D] {
|
||||||
|
return Tuple4[A, B, C, D]{FieldA: a, FieldB: b, FieldC: c, FieldD: d}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip4 create a slice of Tuple4, whose elements are correspond to the given slice elements.
|
||||||
|
// Play: todo
|
||||||
|
func Zip4[A any, B any, C any, D any](a []A, b []B, c []C, d []D) []Tuple4[A, B, C, D] {
|
||||||
|
size := mathutil.Max(len(a), len(b), len(c), len(d))
|
||||||
|
|
||||||
|
tuples := make([]Tuple4[A, B, C, D], size)
|
||||||
|
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
v1, _ := getByIndex(a, i)
|
||||||
|
v2, _ := getByIndex(b, i)
|
||||||
|
v3, _ := getByIndex(c, i)
|
||||||
|
v4, _ := getByIndex(d, i)
|
||||||
|
|
||||||
|
tuples[i] = Tuple4[A, B, C, D]{FieldA: v1, FieldB: v2, FieldC: v3, FieldD: v4}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuples
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unzip4 creates a group of slice from a slice of Tuple4.
|
||||||
|
// Play: todo
|
||||||
|
func Unzip4[A any, B any, C any, D any](tuples []Tuple4[A, B, C, D]) ([]A, []B, []C, []D) {
|
||||||
|
size := len(tuples)
|
||||||
|
|
||||||
|
r1 := make([]A, size)
|
||||||
|
r2 := make([]B, size)
|
||||||
|
r3 := make([]C, size)
|
||||||
|
r4 := make([]D, size)
|
||||||
|
|
||||||
|
for i, t := range tuples {
|
||||||
|
r1[i] = t.FieldA
|
||||||
|
r2[i] = t.FieldB
|
||||||
|
r3[i] = t.FieldC
|
||||||
|
r4[i] = t.FieldD
|
||||||
|
}
|
||||||
|
|
||||||
|
return r1, r2, r3, r4
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tuple5 represents a 5 elemnets tuple
|
||||||
|
type Tuple5[A any, B any, C any, D any, E any] struct {
|
||||||
|
FieldA A
|
||||||
|
FieldB B
|
||||||
|
FieldC C
|
||||||
|
FieldD D
|
||||||
|
FieldE E
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbox returns values in tuple.
|
||||||
|
// Play: todo
|
||||||
|
func (t Tuple5[A, B, C, D, E]) Unbox() (A, B, C, D, E) {
|
||||||
|
return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTuple5 creates a 5 elemnets tuple from a list of values.
|
||||||
|
// Play: todo
|
||||||
|
func NewTuple5[A any, B any, C any, D any, E any](a A, b B, c C, d D, e E) Tuple5[A, B, C, D, E] {
|
||||||
|
return Tuple5[A, B, C, D, E]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip5 create a slice of Tuple5, whose elements are correspond to the given slice elements.
|
||||||
|
// Play: todo
|
||||||
|
func Zip5[A any, B any, C any, D any, E any](a []A, b []B, c []C, d []D, e []E) []Tuple5[A, B, C, D, E] {
|
||||||
|
size := mathutil.Max(len(a), len(b), len(c), len(d), len(e))
|
||||||
|
|
||||||
|
tuples := make([]Tuple5[A, B, C, D, E], size)
|
||||||
|
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
v1, _ := getByIndex(a, i)
|
||||||
|
v2, _ := getByIndex(b, i)
|
||||||
|
v3, _ := getByIndex(c, i)
|
||||||
|
v4, _ := getByIndex(d, i)
|
||||||
|
v5, _ := getByIndex(e, i)
|
||||||
|
|
||||||
|
tuples[i] = Tuple5[A, B, C, D, E]{
|
||||||
|
FieldA: v1, FieldB: v2, FieldC: v3,
|
||||||
|
FieldD: v4, FieldE: v5}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuples
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unzip5 creates a group of slice from a slice of Tuple5.
|
||||||
|
// Play: todo
|
||||||
|
func Unzip5[A any, B any, C any, D any, E any](tuples []Tuple5[A, B, C, D, E]) ([]A, []B, []C, []D, []E) {
|
||||||
|
size := len(tuples)
|
||||||
|
|
||||||
|
r1 := make([]A, size)
|
||||||
|
r2 := make([]B, size)
|
||||||
|
r3 := make([]C, size)
|
||||||
|
r4 := make([]D, size)
|
||||||
|
r5 := make([]E, size)
|
||||||
|
|
||||||
|
for i, t := range tuples {
|
||||||
|
r1[i] = t.FieldA
|
||||||
|
r2[i] = t.FieldB
|
||||||
|
r3[i] = t.FieldC
|
||||||
|
r4[i] = t.FieldD
|
||||||
|
r5[i] = t.FieldE
|
||||||
|
}
|
||||||
|
|
||||||
|
return r1, r2, r3, r4, r5
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tuple6 represents a 6 elemnets tuple
|
||||||
|
type Tuple6[A any, B any, C any, D any, E any, F any] struct {
|
||||||
|
FieldA A
|
||||||
|
FieldB B
|
||||||
|
FieldC C
|
||||||
|
FieldD D
|
||||||
|
FieldE E
|
||||||
|
FieldF F
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbox returns values in tuple.
|
||||||
|
// Play: todo
|
||||||
|
func (t Tuple6[A, B, C, D, E, F]) Unbox() (A, B, C, D, E, F) {
|
||||||
|
return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTuple6 creates a 6 elemnets tuple from a list of values.
|
||||||
|
// Play: todo
|
||||||
|
func NewTuple6[A any, B any, C any, D any, E any, F any](a A, b B, c C, d D, e E, f F) Tuple6[A, B, C, D, E, F] {
|
||||||
|
return Tuple6[A, B, C, D, E, F]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip6 create a slice of Tuple6, whose elements are correspond to the given slice elements.
|
||||||
|
// Play: todo
|
||||||
|
func Zip6[A any, B any, C any, D any, E any, F any](a []A, b []B, c []C, d []D, e []E, f []F) []Tuple6[A, B, C, D, E, F] {
|
||||||
|
size := mathutil.Max(len(a), len(b), len(c), len(d), len(e), len(f))
|
||||||
|
|
||||||
|
tuples := make([]Tuple6[A, B, C, D, E, F], size)
|
||||||
|
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
v1, _ := getByIndex(a, i)
|
||||||
|
v2, _ := getByIndex(b, i)
|
||||||
|
v3, _ := getByIndex(c, i)
|
||||||
|
v4, _ := getByIndex(d, i)
|
||||||
|
v5, _ := getByIndex(e, i)
|
||||||
|
v6, _ := getByIndex(f, i)
|
||||||
|
|
||||||
|
tuples[i] = Tuple6[A, B, C, D, E, F]{
|
||||||
|
FieldA: v1, FieldB: v2, FieldC: v3,
|
||||||
|
FieldD: v4, FieldE: v5, FieldF: v6}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuples
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unzip6 creates a group of slice from a slice of Tuple6.
|
||||||
|
// Play: todo
|
||||||
|
func Unzip6[A any, B any, C any, D any, E any, F any](tuples []Tuple6[A, B, C, D, E, F]) ([]A, []B, []C, []D, []E, []F) {
|
||||||
|
size := len(tuples)
|
||||||
|
|
||||||
|
r1 := make([]A, size)
|
||||||
|
r2 := make([]B, size)
|
||||||
|
r3 := make([]C, size)
|
||||||
|
r4 := make([]D, size)
|
||||||
|
r5 := make([]E, size)
|
||||||
|
r6 := make([]F, size)
|
||||||
|
|
||||||
|
for i, t := range tuples {
|
||||||
|
r1[i] = t.FieldA
|
||||||
|
r2[i] = t.FieldB
|
||||||
|
r3[i] = t.FieldC
|
||||||
|
r4[i] = t.FieldD
|
||||||
|
r5[i] = t.FieldE
|
||||||
|
r6[i] = t.FieldF
|
||||||
|
}
|
||||||
|
|
||||||
|
return r1, r2, r3, r4, r5, r6
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tuple7 represents a 7 elemnets tuple
|
||||||
|
type Tuple7[A any, B any, C any, D any, E any, F any, G any] struct {
|
||||||
|
FieldA A
|
||||||
|
FieldB B
|
||||||
|
FieldC C
|
||||||
|
FieldD D
|
||||||
|
FieldE E
|
||||||
|
FieldF F
|
||||||
|
FieldG G
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbox returns values in tuple.
|
||||||
|
// Play: todo
|
||||||
|
func (t Tuple7[A, B, C, D, E, F, G]) Unbox() (A, B, C, D, E, F, G) {
|
||||||
|
return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTuple7 creates a 7 elemnets tuple from a list of values.
|
||||||
|
// Play: todo
|
||||||
|
func NewTuple7[A any, B any, C any, D any, E any, F any, G any](a A, b B, c C, d D, e E, f F, g G) Tuple7[A, B, C, D, E, F, G] {
|
||||||
|
return Tuple7[A, B, C, D, E, F, G]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f, FieldG: g}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip7 create a slice of Tuple7, whose elements are correspond to the given slice elements.
|
||||||
|
// Play: todo
|
||||||
|
func Zip7[A any, B any, C any, D any, E any, F any, G any](a []A, b []B, c []C, d []D, e []E, f []F, g []G) []Tuple7[A, B, C, D, E, F, G] {
|
||||||
|
size := mathutil.Max(len(a), len(b), len(c), len(d), len(e), len(f), len(g))
|
||||||
|
|
||||||
|
tuples := make([]Tuple7[A, B, C, D, E, F, G], size)
|
||||||
|
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
v1, _ := getByIndex(a, i)
|
||||||
|
v2, _ := getByIndex(b, i)
|
||||||
|
v3, _ := getByIndex(c, i)
|
||||||
|
v4, _ := getByIndex(d, i)
|
||||||
|
v5, _ := getByIndex(e, i)
|
||||||
|
v6, _ := getByIndex(f, i)
|
||||||
|
v7, _ := getByIndex(g, i)
|
||||||
|
|
||||||
|
tuples[i] = Tuple7[A, B, C, D, E, F, G]{
|
||||||
|
FieldA: v1, FieldB: v2, FieldC: v3,
|
||||||
|
FieldD: v4, FieldE: v5, FieldF: v6,
|
||||||
|
FieldG: v7}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuples
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unzip7 creates a group of slice from a slice of Tuple7.
|
||||||
|
// Play: todo
|
||||||
|
func Unzip7[A any, B any, C any, D any, E any, F any, G any](tuples []Tuple7[A, B, C, D, E, F, G]) ([]A, []B, []C, []D, []E, []F, []G) {
|
||||||
|
size := len(tuples)
|
||||||
|
|
||||||
|
r1 := make([]A, size)
|
||||||
|
r2 := make([]B, size)
|
||||||
|
r3 := make([]C, size)
|
||||||
|
r4 := make([]D, size)
|
||||||
|
r5 := make([]E, size)
|
||||||
|
r6 := make([]F, size)
|
||||||
|
r7 := make([]G, size)
|
||||||
|
|
||||||
|
for i, t := range tuples {
|
||||||
|
r1[i] = t.FieldA
|
||||||
|
r2[i] = t.FieldB
|
||||||
|
r3[i] = t.FieldC
|
||||||
|
r4[i] = t.FieldD
|
||||||
|
r5[i] = t.FieldE
|
||||||
|
r6[i] = t.FieldF
|
||||||
|
r7[i] = t.FieldG
|
||||||
|
}
|
||||||
|
|
||||||
|
return r1, r2, r3, r4, r5, r6, r7
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tuple8 represents a 8 elemnets tuple
|
||||||
|
type Tuple8[A any, B any, C any, D any, E any, F any, G any, H any] struct {
|
||||||
|
FieldA A
|
||||||
|
FieldB B
|
||||||
|
FieldC C
|
||||||
|
FieldD D
|
||||||
|
FieldE E
|
||||||
|
FieldF F
|
||||||
|
FieldG G
|
||||||
|
FieldH H
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbox returns values in tuple.
|
||||||
|
// Play: todo
|
||||||
|
func (t Tuple8[A, B, C, D, E, F, G, H]) Unbox() (A, B, C, D, E, F, G, H) {
|
||||||
|
return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTuple8 creates a 8 elemnets tuple from a list of values.
|
||||||
|
// Play: todo
|
||||||
|
func NewTuple8[A any, B any, C any, D any, E any, F any, G any, H any](a A, b B, c C, d D, e E, f F, g G, h H) Tuple8[A, B, C, D, E, F, G, H] {
|
||||||
|
return Tuple8[A, B, C, D, E, F, G, H]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f, FieldG: g, FieldH: h}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip8 create a slice of Tuple8, whose elements are correspond to the given slice elements.
|
||||||
|
// Play: todo
|
||||||
|
func Zip8[A any, B any, C any, D any, E any, F any, G any, H any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H) []Tuple8[A, B, C, D, E, F, G, H] {
|
||||||
|
size := mathutil.Max(len(a), len(b), len(c), len(d), len(e), len(f), len(g), len(h))
|
||||||
|
|
||||||
|
tuples := make([]Tuple8[A, B, C, D, E, F, G, H], size)
|
||||||
|
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
v1, _ := getByIndex(a, i)
|
||||||
|
v2, _ := getByIndex(b, i)
|
||||||
|
v3, _ := getByIndex(c, i)
|
||||||
|
v4, _ := getByIndex(d, i)
|
||||||
|
v5, _ := getByIndex(e, i)
|
||||||
|
v6, _ := getByIndex(f, i)
|
||||||
|
v7, _ := getByIndex(g, i)
|
||||||
|
v8, _ := getByIndex(h, i)
|
||||||
|
|
||||||
|
tuples[i] = Tuple8[A, B, C, D, E, F, G, H]{
|
||||||
|
FieldA: v1, FieldB: v2, FieldC: v3,
|
||||||
|
FieldD: v4, FieldE: v5, FieldF: v6,
|
||||||
|
FieldG: v7, FieldH: v8}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuples
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unzip8 creates a group of slice from a slice of Tuple8.
|
||||||
|
// Play: todo
|
||||||
|
func Unzip8[A any, B any, C any, D any, E any, F any, G any, H any](tuples []Tuple8[A, B, C, D, E, F, G, H]) ([]A, []B, []C, []D, []E, []F, []G, []H) {
|
||||||
|
size := len(tuples)
|
||||||
|
|
||||||
|
r1 := make([]A, size)
|
||||||
|
r2 := make([]B, size)
|
||||||
|
r3 := make([]C, size)
|
||||||
|
r4 := make([]D, size)
|
||||||
|
r5 := make([]E, size)
|
||||||
|
r6 := make([]F, size)
|
||||||
|
r7 := make([]G, size)
|
||||||
|
r8 := make([]H, size)
|
||||||
|
|
||||||
|
for i, t := range tuples {
|
||||||
|
r1[i] = t.FieldA
|
||||||
|
r2[i] = t.FieldB
|
||||||
|
r3[i] = t.FieldC
|
||||||
|
r4[i] = t.FieldD
|
||||||
|
r5[i] = t.FieldE
|
||||||
|
r6[i] = t.FieldF
|
||||||
|
r7[i] = t.FieldG
|
||||||
|
r8[i] = t.FieldH
|
||||||
|
}
|
||||||
|
|
||||||
|
return r1, r2, r3, r4, r5, r6, r7, r8
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tuple9 represents a 9 elemnets tuple
|
||||||
|
type Tuple9[A any, B any, C any, D any, E any, F any, G any, H any, I any] struct {
|
||||||
|
FieldA A
|
||||||
|
FieldB B
|
||||||
|
FieldC C
|
||||||
|
FieldD D
|
||||||
|
FieldE E
|
||||||
|
FieldF F
|
||||||
|
FieldG G
|
||||||
|
FieldH H
|
||||||
|
FieldI I
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbox returns values in tuple.
|
||||||
|
// Play: todo
|
||||||
|
func (t Tuple9[A, B, C, D, E, F, G, H, I]) Unbox() (A, B, C, D, E, F, G, H, I) {
|
||||||
|
return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH, t.FieldI
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTuple9 creates a 9 elemnets tuple from a list of values.
|
||||||
|
// Play: todo
|
||||||
|
func NewTuple9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a A, b B, c C, d D, e E, f F, g G, h H, i I) Tuple9[A, B, C, D, E, F, G, H, I] {
|
||||||
|
return Tuple9[A, B, C, D, E, F, G, H, I]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f, FieldG: g, FieldH: h, FieldI: i}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip9 create a slice of Tuple9, whose elements are correspond to the given slice elements.
|
||||||
|
// Play: todo
|
||||||
|
func Zip9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I) []Tuple9[A, B, C, D, E, F, G, H, I] {
|
||||||
|
size := mathutil.Max(len(a), len(b), len(c), len(d), len(e), len(f), len(g), len(h), len(i))
|
||||||
|
|
||||||
|
tuples := make([]Tuple9[A, B, C, D, E, F, G, H, I], size)
|
||||||
|
|
||||||
|
for idx := 0; idx < size; idx++ {
|
||||||
|
v1, _ := getByIndex(a, idx)
|
||||||
|
v2, _ := getByIndex(b, idx)
|
||||||
|
v3, _ := getByIndex(c, idx)
|
||||||
|
v4, _ := getByIndex(d, idx)
|
||||||
|
v5, _ := getByIndex(e, idx)
|
||||||
|
v6, _ := getByIndex(f, idx)
|
||||||
|
v7, _ := getByIndex(g, idx)
|
||||||
|
v8, _ := getByIndex(h, idx)
|
||||||
|
v9, _ := getByIndex(i, idx)
|
||||||
|
|
||||||
|
tuples[idx] = Tuple9[A, B, C, D, E, F, G, H, I]{
|
||||||
|
FieldA: v1, FieldB: v2, FieldC: v3,
|
||||||
|
FieldD: v4, FieldE: v5, FieldF: v6,
|
||||||
|
FieldG: v7, FieldH: v8, FieldI: v9}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuples
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unzip9 creates a group of slice from a slice of Tuple9.
|
||||||
|
// Play: todo
|
||||||
|
func Unzip9[A any, B any, C any, D any, E any, F any, G any, H any, I any](tuples []Tuple9[A, B, C, D, E, F, G, H, I]) ([]A, []B, []C, []D, []E, []F, []G, []H, []I) {
|
||||||
|
size := len(tuples)
|
||||||
|
|
||||||
|
r1 := make([]A, size)
|
||||||
|
r2 := make([]B, size)
|
||||||
|
r3 := make([]C, size)
|
||||||
|
r4 := make([]D, size)
|
||||||
|
r5 := make([]E, size)
|
||||||
|
r6 := make([]F, size)
|
||||||
|
r7 := make([]G, size)
|
||||||
|
r8 := make([]H, size)
|
||||||
|
r9 := make([]I, size)
|
||||||
|
|
||||||
|
for i, t := range tuples {
|
||||||
|
r1[i] = t.FieldA
|
||||||
|
r2[i] = t.FieldB
|
||||||
|
r3[i] = t.FieldC
|
||||||
|
r4[i] = t.FieldD
|
||||||
|
r5[i] = t.FieldE
|
||||||
|
r6[i] = t.FieldF
|
||||||
|
r7[i] = t.FieldG
|
||||||
|
r8[i] = t.FieldH
|
||||||
|
r9[i] = t.FieldI
|
||||||
|
}
|
||||||
|
|
||||||
|
return r1, r2, r3, r4, r5, r6, r7, r8, r9
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tuple10 represents a 10 elemnets tuple
|
||||||
|
type Tuple10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any] struct {
|
||||||
|
FieldA A
|
||||||
|
FieldB B
|
||||||
|
FieldC C
|
||||||
|
FieldD D
|
||||||
|
FieldE E
|
||||||
|
FieldF F
|
||||||
|
FieldG G
|
||||||
|
FieldH H
|
||||||
|
FieldI I
|
||||||
|
FieldJ J
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbox returns values in tuple.
|
||||||
|
// Play: todo
|
||||||
|
func (t Tuple10[A, B, C, D, E, F, G, H, I, J]) Unbox() (A, B, C, D, E, F, G, H, I, J) {
|
||||||
|
return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH, t.FieldI, t.FieldJ
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTuple10 creates a 10 elemnets tuple from a list of values.
|
||||||
|
// Play: todo
|
||||||
|
func NewTuple10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](a A, b B, c C, d D, e E, f F, g G, h H, i I, j J) Tuple10[A, B, C, D, E, F, G, H, I, J] {
|
||||||
|
return Tuple10[A, B, C, D, E, F, G, H, I, J]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f, FieldG: g, FieldH: h, FieldI: i, FieldJ: j}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip10 create a slice of Tuple10, whose elements are correspond to the given slice elements.
|
||||||
|
// Play: todo
|
||||||
|
func Zip10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I, j []J) []Tuple10[A, B, C, D, E, F, G, H, I, J] {
|
||||||
|
size := mathutil.Max(len(a), len(b), len(c), len(d), len(e), len(f), len(g), len(h), len(i), len(j))
|
||||||
|
|
||||||
|
tuples := make([]Tuple10[A, B, C, D, E, F, G, H, I, J], size)
|
||||||
|
|
||||||
|
for idx := 0; idx < size; idx++ {
|
||||||
|
v1, _ := getByIndex(a, idx)
|
||||||
|
v2, _ := getByIndex(b, idx)
|
||||||
|
v3, _ := getByIndex(c, idx)
|
||||||
|
v4, _ := getByIndex(d, idx)
|
||||||
|
v5, _ := getByIndex(e, idx)
|
||||||
|
v6, _ := getByIndex(f, idx)
|
||||||
|
v7, _ := getByIndex(g, idx)
|
||||||
|
v8, _ := getByIndex(h, idx)
|
||||||
|
v9, _ := getByIndex(i, idx)
|
||||||
|
v10, _ := getByIndex(j, idx)
|
||||||
|
|
||||||
|
tuples[idx] = Tuple10[A, B, C, D, E, F, G, H, I, J]{
|
||||||
|
FieldA: v1, FieldB: v2, FieldC: v3,
|
||||||
|
FieldD: v4, FieldE: v5, FieldF: v6,
|
||||||
|
FieldG: v7, FieldH: v8, FieldI: v9,
|
||||||
|
FieldJ: v10}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuples
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unzip10 creates a group of slice from a slice of Tuple10.
|
||||||
|
// Play: todo
|
||||||
|
func Unzip10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](tuples []Tuple10[A, B, C, D, E, F, G, H, I, J]) ([]A, []B, []C, []D, []E, []F, []G, []H, []I, []J) {
|
||||||
|
size := len(tuples)
|
||||||
|
|
||||||
|
r1 := make([]A, size)
|
||||||
|
r2 := make([]B, size)
|
||||||
|
r3 := make([]C, size)
|
||||||
|
r4 := make([]D, size)
|
||||||
|
r5 := make([]E, size)
|
||||||
|
r6 := make([]F, size)
|
||||||
|
r7 := make([]G, size)
|
||||||
|
r8 := make([]H, size)
|
||||||
|
r9 := make([]I, size)
|
||||||
|
r10 := make([]J, size)
|
||||||
|
|
||||||
|
for i, t := range tuples {
|
||||||
|
r1[i] = t.FieldA
|
||||||
|
r2[i] = t.FieldB
|
||||||
|
r3[i] = t.FieldC
|
||||||
|
r4[i] = t.FieldD
|
||||||
|
r5[i] = t.FieldE
|
||||||
|
r6[i] = t.FieldF
|
||||||
|
r7[i] = t.FieldG
|
||||||
|
r8[i] = t.FieldH
|
||||||
|
r9[i] = t.FieldI
|
||||||
|
r10[i] = t.FieldJ
|
||||||
|
}
|
||||||
|
|
||||||
|
return r1, r2, r3, r4, r5, r6, r7, r8, r9, r10
|
||||||
|
}
|
||||||
|
|
||||||
|
func getByIndex[T any](slice []T, index int) (T, bool) {
|
||||||
|
l := len(slice)
|
||||||
|
if index >= l || -index > l {
|
||||||
|
var zeroVal T
|
||||||
|
return zeroVal, false
|
||||||
|
}
|
||||||
|
|
||||||
|
if index >= 0 {
|
||||||
|
return slice[index], true
|
||||||
|
}
|
||||||
|
|
||||||
|
return slice[l+index], true
|
||||||
|
}
|
||||||
129
tuple/tuple_example_test.go
Normal file
129
tuple/tuple_example_test.go
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
// Copyright 2023 dudaodong@gmail.com. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
// Package tuple implements tuple data type and some operations on it.
|
||||||
|
package tuple
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func ExampleNewTuple2() {
|
||||||
|
t := NewTuple2(1, 0.1)
|
||||||
|
fmt.Printf("%v %v", t.FieldA, t.FieldB)
|
||||||
|
// Output: 1 0.1
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleTuple2_Unbox() {
|
||||||
|
t := NewTuple2(1, 0.1)
|
||||||
|
v1, v2 := t.Unbox()
|
||||||
|
fmt.Printf("%v %v", v1, v2)
|
||||||
|
// Output: 1 0.1
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleNewTuple3() {
|
||||||
|
t := NewTuple3(1, 0.1, "a")
|
||||||
|
fmt.Printf("%v %v %v", t.FieldA, t.FieldB, t.FieldC)
|
||||||
|
// Output: 1 0.1 a
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleTuple3_Unbox() {
|
||||||
|
t := NewTuple3(1, 0.1, "a")
|
||||||
|
v1, v2, v3 := t.Unbox()
|
||||||
|
fmt.Printf("%v %v %v", v1, v2, v3)
|
||||||
|
// Output: 1 0.1 a
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleNewTuple4() {
|
||||||
|
t := NewTuple4(1, 0.1, "a", true)
|
||||||
|
fmt.Printf("%v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD)
|
||||||
|
// Output: 1 0.1 a true
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleTuple4_Unbox() {
|
||||||
|
t := NewTuple4(1, 0.1, "a", true)
|
||||||
|
v1, v2, v3, v4 := t.Unbox()
|
||||||
|
fmt.Printf("%v %v %v %v", v1, v2, v3, v4)
|
||||||
|
// Output: 1 0.1 a true
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleNewTuple5() {
|
||||||
|
t := NewTuple5(1, 0.1, "a", true, 2)
|
||||||
|
fmt.Printf("%v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE)
|
||||||
|
// Output: 1 0.1 a true 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleTuple5_Unbox() {
|
||||||
|
t := NewTuple5(1, 0.1, "a", true, 2)
|
||||||
|
v1, v2, v3, v4, v5 := t.Unbox()
|
||||||
|
fmt.Printf("%v %v %v %v %v", v1, v2, v3, v4, v5)
|
||||||
|
// Output: 1 0.1 a true 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleNewTuple6() {
|
||||||
|
t := NewTuple6(1, 0.1, "a", true, 2, 2.2)
|
||||||
|
fmt.Printf("%v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF)
|
||||||
|
// Output: 1 0.1 a true 2 2.2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleTuple6_Unbox() {
|
||||||
|
t := NewTuple6(1, 0.1, "a", true, 2, 2.2)
|
||||||
|
v1, v2, v3, v4, v5, v6 := t.Unbox()
|
||||||
|
fmt.Printf("%v %v %v %v %v %v", v1, v2, v3, v4, v5, v6)
|
||||||
|
// Output: 1 0.1 a true 2 2.2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleNewTuple7() {
|
||||||
|
t := NewTuple7(1, 0.1, "a", true, 2, 2.2, "b")
|
||||||
|
fmt.Printf("%v %v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG)
|
||||||
|
// Output: 1 0.1 a true 2 2.2 b
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleTuple7_Unbox() {
|
||||||
|
t := NewTuple7(1, 0.1, "a", true, 2, 2.2, "b")
|
||||||
|
v1, v2, v3, v4, v5, v6, v7 := t.Unbox()
|
||||||
|
fmt.Printf("%v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7)
|
||||||
|
// Output: 1 0.1 a true 2 2.2 b
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleNewTuple8() {
|
||||||
|
t := NewTuple8(1, 0.1, "a", true, 2, 2.2, "b", "c")
|
||||||
|
fmt.Printf("%v %v %v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH)
|
||||||
|
// Output: 1 0.1 a true 2 2.2 b c
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleTuple8_Unbox() {
|
||||||
|
t := NewTuple8(1, 0.1, "a", true, 2, 2.2, "b", "c")
|
||||||
|
v1, v2, v3, v4, v5, v6, v7, v8 := t.Unbox()
|
||||||
|
fmt.Printf("%v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8)
|
||||||
|
// Output: 1 0.1 a true 2 2.2 b c
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleNewTuple9() {
|
||||||
|
t := NewTuple9(1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1})
|
||||||
|
fmt.Printf("%v %v %v %v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH, t.FieldI)
|
||||||
|
// Output: 1 0.1 a true 2 2.2 b c map[a:1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleTuple9_Unbox() {
|
||||||
|
t := NewTuple9(1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1})
|
||||||
|
v1, v2, v3, v4, v5, v6, v7, v8, v9 := t.Unbox()
|
||||||
|
fmt.Printf("%v %v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8, v9)
|
||||||
|
// Output: 1 0.1 a true 2 2.2 b c map[a:1]
|
||||||
|
}
|
||||||
|
func ExampleNewTuple10() {
|
||||||
|
type foo struct {
|
||||||
|
A string
|
||||||
|
}
|
||||||
|
t := NewTuple10(1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}, foo{A: "a"})
|
||||||
|
fmt.Printf("%v %v %v %v %v %v %v %v %v %v", t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH, t.FieldI, t.FieldJ)
|
||||||
|
// Output: 1 0.1 a true 2 2.2 b c map[a:1] {a}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleTuple10_Unbox() {
|
||||||
|
type foo struct {
|
||||||
|
A string
|
||||||
|
}
|
||||||
|
t := NewTuple10(1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}, foo{A: "a"})
|
||||||
|
v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 := t.Unbox()
|
||||||
|
fmt.Printf("%v %v %v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)
|
||||||
|
// Output: 1 0.1 a true 2 2.2 b c map[a:1] {a}
|
||||||
|
}
|
||||||
195
tuple/tuple_test.go
Normal file
195
tuple/tuple_test.go
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
// Copyright 2023 dudaodong@gmail.com. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
// Package tuple implements tuple data type and some operations on it.
|
||||||
|
package tuple
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTuples(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
assert := internal.NewAssert(t, "TestTuples")
|
||||||
|
|
||||||
|
type foo struct {
|
||||||
|
A string
|
||||||
|
}
|
||||||
|
|
||||||
|
t2 := NewTuple2[int, float64](1, 0.1)
|
||||||
|
t3 := NewTuple3[int, float64, string](1, 0.1, "a")
|
||||||
|
t4 := NewTuple4[int, float64, string, bool](1, 0.1, "a", true)
|
||||||
|
t5 := NewTuple5[int, float64, string, bool, int64](1, 0.1, "a", true, 2)
|
||||||
|
t6 := NewTuple6[int, float64, string, bool, int64, float32](1, 0.1, "a", true, 2, 2.2)
|
||||||
|
t7 := NewTuple7[int, float64, string, bool, int64, float32, string](1, 0.1, "a", true, 2, 2.2, "b")
|
||||||
|
t8 := NewTuple8[int, float64, string, bool, int64, float32, string, string](1, 0.1, "a", true, 2, 2.2, "b", "c")
|
||||||
|
t9 := NewTuple9[int, float64, string, bool, int64, float32, string, string, map[string]int](1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1})
|
||||||
|
t10 := NewTuple10[int, float64, string, bool, int64, float32, string, string, map[string]int, foo](1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}, foo{A: "a"})
|
||||||
|
|
||||||
|
assert.Equal(t2, Tuple2[int, float64]{FieldA: 1, FieldB: 0.1})
|
||||||
|
assert.Equal(t3, Tuple3[int, float64, string]{FieldA: 1, FieldB: 0.1, FieldC: "a"})
|
||||||
|
assert.Equal(t4, Tuple4[int, float64, string, bool]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true})
|
||||||
|
assert.Equal(t5, Tuple5[int, float64, string, bool, int64]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2})
|
||||||
|
assert.Equal(t6, Tuple6[int, float64, string, bool, int64, float32]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2})
|
||||||
|
assert.Equal(t7, Tuple7[int, float64, string, bool, int64, float32, string]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b"})
|
||||||
|
assert.Equal(t8, Tuple8[int, float64, string, bool, int64, float32, string, string]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b", FieldH: "c"})
|
||||||
|
assert.Equal(t9, Tuple9[int, float64, string, bool, int64, float32, string, string, map[string]int]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b", FieldH: "c", FieldI: map[string]int{"a": 1}})
|
||||||
|
assert.Equal(t10, Tuple10[int, float64, string, bool, int64, float32, string, string, map[string]int, foo]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b", FieldH: "c", FieldI: map[string]int{"a": 1}, FieldJ: foo{A: "a"}})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTuple_Unbox(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
assert := internal.NewAssert(t, "TestTuple_Unbox")
|
||||||
|
|
||||||
|
type foo struct {
|
||||||
|
A string
|
||||||
|
}
|
||||||
|
|
||||||
|
t2 := NewTuple2[int, float64](1, 0.1)
|
||||||
|
v1, v2 := t2.Unbox()
|
||||||
|
assert.Equal(1, v1)
|
||||||
|
assert.Equal(0.1, v2)
|
||||||
|
|
||||||
|
t3 := NewTuple3[int, float64, string](1, 0.1, "a")
|
||||||
|
v1, v2, v3 := t3.Unbox()
|
||||||
|
assert.Equal(1, v1)
|
||||||
|
assert.Equal(0.1, v2)
|
||||||
|
assert.Equal("a", v3)
|
||||||
|
|
||||||
|
t4 := NewTuple4[int, float64, string, bool](1, 0.1, "a", true)
|
||||||
|
v1, v2, v3, v4 := t4.Unbox()
|
||||||
|
assert.Equal(1, v1)
|
||||||
|
assert.Equal(0.1, v2)
|
||||||
|
assert.Equal("a", v3)
|
||||||
|
assert.Equal(true, v4)
|
||||||
|
|
||||||
|
t5 := NewTuple5[int, float64, string, bool, int64](1, 0.1, "a", true, 2)
|
||||||
|
v1, v2, v3, v4, v5 := t5.Unbox()
|
||||||
|
assert.Equal(1, v1)
|
||||||
|
assert.Equal(0.1, v2)
|
||||||
|
assert.Equal("a", v3)
|
||||||
|
assert.Equal(true, v4)
|
||||||
|
assert.Equal(int64(2), v5)
|
||||||
|
|
||||||
|
t6 := NewTuple6[int, float64, string, bool, int64, float32](1, 0.1, "a", true, 2, 2.2)
|
||||||
|
v1, v2, v3, v4, v5, v6 := t6.Unbox()
|
||||||
|
assert.Equal(1, v1)
|
||||||
|
assert.Equal(0.1, v2)
|
||||||
|
assert.Equal("a", v3)
|
||||||
|
assert.Equal(true, v4)
|
||||||
|
assert.Equal(int64(2), v5)
|
||||||
|
assert.Equal(float32(2.2), v6)
|
||||||
|
|
||||||
|
t7 := NewTuple7[int, float64, string, bool, int64, float32, string](1, 0.1, "a", true, 2, 2.2, "b")
|
||||||
|
v1, v2, v3, v4, v5, v6, v7 := t7.Unbox()
|
||||||
|
assert.Equal(1, v1)
|
||||||
|
assert.Equal(0.1, v2)
|
||||||
|
assert.Equal("a", v3)
|
||||||
|
assert.Equal(true, v4)
|
||||||
|
assert.Equal(int64(2), v5)
|
||||||
|
assert.Equal(float32(2.2), v6)
|
||||||
|
assert.Equal("b", v7)
|
||||||
|
|
||||||
|
t8 := NewTuple8[int, float64, string, bool, int64, float32, string, string](1, 0.1, "a", true, 2, 2.2, "b", "c")
|
||||||
|
v1, v2, v3, v4, v5, v6, v7, v8 := t8.Unbox()
|
||||||
|
assert.Equal(1, v1)
|
||||||
|
assert.Equal(0.1, v2)
|
||||||
|
assert.Equal("a", v3)
|
||||||
|
assert.Equal(true, v4)
|
||||||
|
assert.Equal(int64(2), v5)
|
||||||
|
assert.Equal(float32(2.2), v6)
|
||||||
|
assert.Equal("b", v7)
|
||||||
|
assert.Equal("c", v8)
|
||||||
|
|
||||||
|
t9 := NewTuple9[int, float64, string, bool, int64, float32, string, string, map[string]int](1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1})
|
||||||
|
v1, v2, v3, v4, v5, v6, v7, v8, v9 := t9.Unbox()
|
||||||
|
assert.Equal(1, v1)
|
||||||
|
assert.Equal(0.1, v2)
|
||||||
|
assert.Equal("a", v3)
|
||||||
|
assert.Equal(true, v4)
|
||||||
|
assert.Equal(int64(2), v5)
|
||||||
|
assert.Equal(float32(2.2), v6)
|
||||||
|
assert.Equal("b", v7)
|
||||||
|
assert.Equal("c", v8)
|
||||||
|
assert.Equal(map[string]int{"a": 1}, v9)
|
||||||
|
|
||||||
|
t10 := NewTuple10[int, float64, string, bool, int64, float32, string, string, map[string]int, foo](1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}, foo{A: "a"})
|
||||||
|
v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 := t10.Unbox()
|
||||||
|
assert.Equal(1, v1)
|
||||||
|
assert.Equal(0.1, v2)
|
||||||
|
assert.Equal("a", v3)
|
||||||
|
assert.Equal(true, v4)
|
||||||
|
assert.Equal(int64(2), v5)
|
||||||
|
assert.Equal(float32(2.2), v6)
|
||||||
|
assert.Equal("b", v7)
|
||||||
|
assert.Equal("c", v8)
|
||||||
|
assert.Equal(map[string]int{"a": 1}, v9)
|
||||||
|
assert.Equal(foo{A: "a"}, v10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestZip(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
assert := internal.NewAssert(t, "TestZip")
|
||||||
|
|
||||||
|
r2 := Zip2(
|
||||||
|
[]int{1, 2},
|
||||||
|
[]string{"a", "b"},
|
||||||
|
)
|
||||||
|
assert.Equal(r2, []Tuple2[int, string]{
|
||||||
|
{FieldA: 1, FieldB: "a"},
|
||||||
|
{FieldA: 2, FieldB: "b"},
|
||||||
|
})
|
||||||
|
|
||||||
|
r3 := Zip3(
|
||||||
|
[]int{1, 2, 3},
|
||||||
|
[]string{"a", "b", "c"},
|
||||||
|
[]float64{0.1, 0.2, 0.3},
|
||||||
|
)
|
||||||
|
assert.Equal(r3, []Tuple3[int, string, float64]{
|
||||||
|
{FieldA: 1, FieldB: "a", FieldC: 0.1},
|
||||||
|
{FieldA: 2, FieldB: "b", FieldC: 0.2},
|
||||||
|
{FieldA: 3, FieldB: "c", FieldC: 0.3},
|
||||||
|
})
|
||||||
|
|
||||||
|
r4 := Zip4(
|
||||||
|
[]int{1, 2, 3, 4},
|
||||||
|
[]string{"a", "b", "c", "d"},
|
||||||
|
[]float64{0.1, 0.2, 0.3, 0.4},
|
||||||
|
[]bool{true, true, true, true},
|
||||||
|
)
|
||||||
|
assert.Equal(r4, []Tuple4[int, string, float64, bool]{
|
||||||
|
{FieldA: 1, FieldB: "a", FieldC: 0.1, FieldD: true},
|
||||||
|
{FieldA: 2, FieldB: "b", FieldC: 0.2, FieldD: true},
|
||||||
|
{FieldA: 3, FieldB: "c", FieldC: 0.3, FieldD: true},
|
||||||
|
{FieldA: 4, FieldB: "d", FieldC: 0.4, FieldD: true},
|
||||||
|
})
|
||||||
|
|
||||||
|
r5 := Zip5(
|
||||||
|
[]int{1, 2, 3, 4, 5},
|
||||||
|
[]string{"a", "b", "c", "d", "e"},
|
||||||
|
[]float64{0.1, 0.2, 0.3, 0.4, 0.5},
|
||||||
|
[]bool{true, true, true, true, true},
|
||||||
|
[]int{6, 7, 8, 9, 10},
|
||||||
|
)
|
||||||
|
assert.Equal(r5, []Tuple5[int, string, float64, bool, int]{
|
||||||
|
{FieldA: 1, FieldB: "a", FieldC: 0.1, FieldD: true, FieldE: 6},
|
||||||
|
{FieldA: 2, FieldB: "b", FieldC: 0.2, FieldD: true, FieldE: 7},
|
||||||
|
{FieldA: 3, FieldB: "c", FieldC: 0.3, FieldD: true, FieldE: 8},
|
||||||
|
{FieldA: 4, FieldB: "d", FieldC: 0.4, FieldD: true, FieldE: 9},
|
||||||
|
{FieldA: 5, FieldB: "e", FieldC: 0.5, FieldD: true, FieldE: 10},
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnzip(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
assert := internal.NewAssert(t, "TestUnzip")
|
||||||
|
|
||||||
|
r1, r2, r3 := Unzip3([]Tuple3[string, int, float64]{{FieldA: "a", FieldB: 1, FieldC: 0.1}, {FieldA: "b", FieldB: 2, FieldC: 0.2}})
|
||||||
|
|
||||||
|
assert.Equal(r1, []string{"a", "b"})
|
||||||
|
assert.Equal(r2, []int{1, 2})
|
||||||
|
assert.Equal(r3, []float64{0.1, 0.2})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user