mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-09 07:02:29 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fd8a18677 | ||
|
|
3de906d7c9 | ||
|
|
56fc12c660 | ||
|
|
7a9b0847f9 | ||
|
|
9266d99249 | ||
|
|
f15131f032 | ||
|
|
b4a49fccfd |
@@ -6,7 +6,7 @@
|
|||||||
<div align="center" style="text-align: center;">
|
<div align="center" style="text-align: center;">
|
||||||
|
|
||||||

|

|
||||||
[](https://github.com/duke-git/lancet/releases)
|
[](https://github.com/duke-git/lancet/releases)
|
||||||
[](https://pkg.go.dev/github.com/duke-git/lancet)
|
[](https://pkg.go.dev/github.com/duke-git/lancet)
|
||||||
[](https://goreportcard.com/report/github.com/duke-git/lancet)
|
[](https://goreportcard.com/report/github.com/duke-git/lancet)
|
||||||
[](https://codecov.io/gh/duke-git/lancet)
|
[](https://codecov.io/gh/duke-git/lancet)
|
||||||
@@ -21,7 +21,7 @@ English | [简体中文](./README_zh-CN.md)
|
|||||||
### Feature
|
### Feature
|
||||||
|
|
||||||
- 👏 Comprehensive, efficient and reusable.
|
- 👏 Comprehensive, efficient and reusable.
|
||||||
- 💪 100+ common go util functions, support string, slice, datetime, net, crypt...
|
- 💪 140+ common go util functions, support string, slice, datetime, net, crypt...
|
||||||
- 💅 Only depend on the go standard library.
|
- 💅 Only depend on the go standard library.
|
||||||
- 🌍 Unit test for exery exported function.
|
- 🌍 Unit test for exery exported function.
|
||||||
|
|
||||||
@@ -395,7 +395,7 @@ func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error
|
|||||||
func Drop(slice interface{}, n int) interface{} //creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0
|
func Drop(slice interface{}, n int) interface{} //creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0
|
||||||
func Every(slice, function interface{}) bool //return true if all of the values in the slice pass the predicate function, function signature should be func(index int, value interface{}) bool
|
func Every(slice, function interface{}) bool //return true if all of the values in the slice pass the predicate function, function signature should be func(index int, value interface{}) bool
|
||||||
func Filter(slice, function interface{}) interface{} //filter slice, function signature should be func(index int, value interface{}) bool
|
func Filter(slice, function interface{}) interface{} //filter slice, function signature should be func(index int, value interface{}) bool
|
||||||
func Find(slice, function interface{}) interface{} //iterates over elements of slice, returning the first one that passes a truth test on function.function signature should be func(index int, value interface{}) bool .
|
func Find(slice, function interface{}) (interface{}, bool) //iterates over elements of slice, returning the first one that passes a truth test on function.function signature should be func(index int, value interface{}) bool .
|
||||||
func FlattenDeep(slice interface{}) interface{} //flattens slice recursive
|
func FlattenDeep(slice interface{}) interface{} //flattens slice recursive
|
||||||
func IntSlice(slice interface{}) ([]int, error) //convert value to int slice
|
func IntSlice(slice interface{}) ([]int, error) //convert value to int slice
|
||||||
func InterfaceSlice(slice interface{}) []interface{} //convert value to interface{} slice
|
func InterfaceSlice(slice interface{}) []interface{} //convert value to interface{} slice
|
||||||
@@ -412,6 +412,7 @@ func Unique(slice interface{}) interface{} //remove duplicate elements in slice
|
|||||||
func Union(slices ...interface{}) interface{} //Union creates a slice of unique values, in order, from all given slices. using == for equality comparisons.
|
func Union(slices ...interface{}) interface{} //Union creates a slice of unique values, in order, from all given slices. using == for equality comparisons.
|
||||||
func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //update the slice element at index.
|
func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //update the slice element at index.
|
||||||
func Without(slice interface{}, values ...interface{}) interface{} //creates a slice excluding all given values
|
func Without(slice interface{}, values ...interface{}) interface{} //creates a slice excluding all given values
|
||||||
|
func GroupBy(slice, function interface{}) (interface{}, interface{}) // groups slice into two categories
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 10. strutil is for processing string
|
#### 10. strutil is for processing string
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<div align="center" style="text-align: center;">
|
<div align="center" style="text-align: center;">
|
||||||
|
|
||||||

|

|
||||||
[](https://github.com/duke-git/lancet/releases)
|
[](https://github.com/duke-git/lancet/releases)
|
||||||
[](https://pkg.go.dev/github.com/duke-git/lancet)
|
[](https://pkg.go.dev/github.com/duke-git/lancet)
|
||||||
[](https://goreportcard.com/report/github.com/duke-git/lancet)
|
[](https://goreportcard.com/report/github.com/duke-git/lancet)
|
||||||
[](https://codecov.io/gh/duke-git/lancet)
|
[](https://codecov.io/gh/duke-git/lancet)
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
### 特性
|
### 特性
|
||||||
|
|
||||||
- 👏 全面、高效、可复用
|
- 👏 全面、高效、可复用
|
||||||
- 💪 100+常用go工具函数,支持string、slice、datetime、net、crypt...
|
- 💪 140+常用go工具函数,支持string、slice、datetime、net、crypt...
|
||||||
- 💅 只依赖go标准库
|
- 💅 只依赖go标准库
|
||||||
- 🌍 所有导出函数单元测试覆盖率100%
|
- 🌍 所有导出函数单元测试覆盖率100%
|
||||||
|
|
||||||
@@ -395,7 +395,7 @@ func Difference(slice1, slice2 interface{}) interface{} //返回
|
|||||||
func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error) //删除切片中start到end位置的值
|
func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error) //删除切片中start到end位置的值
|
||||||
func Drop(slice interface{}, n int) interface{} //创建一个新切片,当n大于0时删除原切片前n个元素,当n小于0时删除原切片后n个元素
|
func Drop(slice interface{}, n int) interface{} //创建一个新切片,当n大于0时删除原切片前n个元素,当n小于0时删除原切片后n个元素
|
||||||
func Every(slice, function interface{}) bool //slice中所有元素都符合函数条件时返回true, 否则返回false. 函数签名:func(index int, value interface{}) bool
|
func Every(slice, function interface{}) bool //slice中所有元素都符合函数条件时返回true, 否则返回false. 函数签名:func(index int, value interface{}) bool
|
||||||
func Find(slice, function interface{}) interface{} //查找slice中第一个符合条件的元素,函数签名:func(index int, value interface{}) bool
|
func Find(slice, function interface{}) (interface{}, bool)//查找slice中第一个符合条件的元素,函数签名:func(index int, value interface{}) bool
|
||||||
func Filter(slice, function interface{}) interface{} //过滤slice, 函数签名:func(index int, value interface{}) bool
|
func Filter(slice, function interface{}) interface{} //过滤slice, 函数签名:func(index int, value interface{}) bool
|
||||||
func FlattenDeep(slice interface{}) interface{} //将slice递归为一维切片。
|
func FlattenDeep(slice interface{}) interface{} //将slice递归为一维切片。
|
||||||
func IntSlice(slice interface{}) ([]int, error) //转成int切片
|
func IntSlice(slice interface{}) ([]int, error) //转成int切片
|
||||||
@@ -413,6 +413,7 @@ func Unique(slice interface{}) interface{} //去重切片
|
|||||||
func Union(slices ...interface{}) interface{} //slice并集, 去重
|
func Union(slices ...interface{}) interface{} //slice并集, 去重
|
||||||
func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //在切片中index位置更新value
|
func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //在切片中index位置更新value
|
||||||
func Without(slice interface{}, values ...interface{}) interface{} //slice去除values
|
func Without(slice interface{}, values ...interface{}) interface{} //slice去除values
|
||||||
|
func GroupBy(slice, function interface{}) (interface{}, interface{}) //根据函数function的逻辑分slice为两组slice
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 10. strutil字符串处理包
|
#### 10. strutil字符串处理包
|
||||||
|
|||||||
@@ -45,44 +45,34 @@ func ToChar(s string) []string {
|
|||||||
|
|
||||||
// ToString convert value to string
|
// ToString convert value to string
|
||||||
func ToString(value interface{}) string {
|
func ToString(value interface{}) string {
|
||||||
var res string
|
res := ""
|
||||||
if value == nil {
|
if value == nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
switch v := value.(type) {
|
|
||||||
case float64:
|
v := reflect.ValueOf(value)
|
||||||
res = strconv.FormatFloat(v, 'f', -1, 64)
|
|
||||||
case float32:
|
switch value.(type) {
|
||||||
res = strconv.FormatFloat(float64(v), 'f', -1, 64)
|
case float32, float64:
|
||||||
case int:
|
res = strconv.FormatFloat(v.Float(), 'f', -1, 64)
|
||||||
res = strconv.Itoa(v)
|
return res
|
||||||
case uint:
|
case int, int8, int16, int32, int64:
|
||||||
res = strconv.Itoa(int(v))
|
res = strconv.FormatInt(v.Int(), 10)
|
||||||
case int8:
|
return res
|
||||||
res = strconv.Itoa(int(v))
|
case uint, uint8, uint16, uint32, uint64:
|
||||||
case uint8:
|
res = strconv.FormatUint(v.Uint(), 10)
|
||||||
res = strconv.Itoa(int(v))
|
return res
|
||||||
case int16:
|
|
||||||
res = strconv.Itoa(int(v))
|
|
||||||
case uint16:
|
|
||||||
res = strconv.Itoa(int(v))
|
|
||||||
case int32:
|
|
||||||
res = strconv.Itoa(int(v))
|
|
||||||
case uint32:
|
|
||||||
res = strconv.Itoa(int(v))
|
|
||||||
case int64:
|
|
||||||
res = strconv.FormatInt(v, 10)
|
|
||||||
case uint64:
|
|
||||||
res = strconv.FormatUint(v, 10)
|
|
||||||
case string:
|
case string:
|
||||||
res = value.(string)
|
res = v.String()
|
||||||
|
return res
|
||||||
case []byte:
|
case []byte:
|
||||||
res = string(value.([]byte))
|
res = string(v.Bytes())
|
||||||
|
return res
|
||||||
default:
|
default:
|
||||||
newValue, _ := json.Marshal(value)
|
newValue, _ := json.Marshal(value)
|
||||||
res = string(newValue)
|
res = string(newValue)
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToJson convert value to a valid json string
|
// ToJson convert value to a valid json string
|
||||||
|
|||||||
@@ -108,14 +108,19 @@ func TestToString(t *testing.T) {
|
|||||||
aStruct := TestStruct{Name: "TestStruct"}
|
aStruct := TestStruct{Name: "TestStruct"}
|
||||||
|
|
||||||
cases := []interface{}{
|
cases := []interface{}{
|
||||||
|
"", nil,
|
||||||
int(0), int8(1), int16(-1), int32(123), int64(123),
|
int(0), int8(1), int16(-1), int32(123), int64(123),
|
||||||
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||||
float64(12.3), float32(12.3),
|
float64(12.3), float32(12.3),
|
||||||
true, false,
|
true, false,
|
||||||
[]int{1, 2, 3}, aMap, aStruct, []byte{104, 101, 108, 108, 111}}
|
[]int{1, 2, 3}, aMap, aStruct, []byte{104, 101, 108, 108, 111}}
|
||||||
|
|
||||||
expected := []string{"0", "1", "-1", "123", "123", "123", "123", "123",
|
expected := []string{
|
||||||
"123", "123", "12.3", "12.300000190734863", "true", "false",
|
"", "",
|
||||||
|
"0", "1", "-1",
|
||||||
|
"123", "123", "123", "123", "123", "123", "123",
|
||||||
|
"12.3", "12.300000190734863",
|
||||||
|
"true", "false",
|
||||||
"[1,2,3]", "{\"a\":1,\"b\":2,\"c\":3}", "{\"Name\":\"TestStruct\"}", "hello"}
|
"[1,2,3]", "{\"a\":1,\"b\":2,\"c\":3}", "{\"Name\":\"TestStruct\"}", "hello"}
|
||||||
|
|
||||||
for i := 0; i < len(cases); i++ {
|
for i := 0; i < len(cases); i++ {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
// After creates a function that invokes func once it's called n or more times
|
// After creates a function that invokes func once it's called n or more times
|
||||||
func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
|
func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
|
||||||
// Catch programming error while constructing the closure
|
// Catch programming error while constructing the closure
|
||||||
MustBeFunction(fn)
|
mustBeFunction(fn)
|
||||||
return func(args ...interface{}) []reflect.Value {
|
return func(args ...interface{}) []reflect.Value {
|
||||||
n--
|
n--
|
||||||
if n < 1 {
|
if n < 1 {
|
||||||
@@ -25,7 +25,7 @@ func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
|
|||||||
// Before creates a function that invokes func once it's called less than n times
|
// Before creates a function that invokes func once it's called less than n times
|
||||||
func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
|
func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
|
||||||
// Catch programming error while constructing the closure
|
// Catch programming error while constructing the closure
|
||||||
MustBeFunction(fn)
|
mustBeFunction(fn)
|
||||||
var res []reflect.Value
|
var res []reflect.Value
|
||||||
return func(args ...interface{}) []reflect.Value {
|
return func(args ...interface{}) []reflect.Value {
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
@@ -73,7 +73,7 @@ func Delay(delay time.Duration, fn interface{}, args ...interface{}) {
|
|||||||
// Schedule invoke function every duration time, util close the returned bool chan
|
// Schedule invoke function every duration time, util close the returned bool chan
|
||||||
func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool {
|
func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool {
|
||||||
// Catch programming error while constructing the closure
|
// Catch programming error while constructing the closure
|
||||||
MustBeFunction(fn)
|
mustBeFunction(fn)
|
||||||
quit := make(chan bool)
|
quit := make(chan bool)
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ func functionValue(function interface{}) reflect.Value {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func MustBeFunction(function interface{}) {
|
func mustBeFunction(function interface{}) {
|
||||||
v := reflect.ValueOf(function)
|
v := reflect.ValueOf(function)
|
||||||
if v.Kind() != reflect.Func {
|
if v.Kind() != reflect.Func {
|
||||||
panic(fmt.Sprintf("Invalid function type, value of type %T", function))
|
panic(fmt.Sprintf("Invalid function type, value of type %T", function))
|
||||||
|
|||||||
@@ -25,9 +25,8 @@ func (w *Watcher) Stop() {
|
|||||||
func (w *Watcher) GetElapsedTime() time.Duration {
|
func (w *Watcher) GetElapsedTime() time.Duration {
|
||||||
if w.excuting {
|
if w.excuting {
|
||||||
return time.Duration(time.Now().UnixNano() - w.startTime)
|
return time.Duration(time.Now().UnixNano() - w.startTime)
|
||||||
} else {
|
|
||||||
return time.Duration(w.stopTime - w.startTime)
|
|
||||||
}
|
}
|
||||||
|
return time.Duration(w.stopTime - w.startTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the watch timer.
|
// Reset the watch timer.
|
||||||
|
|||||||
@@ -22,27 +22,27 @@ import (
|
|||||||
|
|
||||||
//HttpGet send get http request
|
//HttpGet send get http request
|
||||||
func HttpGet(url string, params ...interface{}) (*http.Response, error) {
|
func HttpGet(url string, params ...interface{}) (*http.Response, error) {
|
||||||
return request(http.MethodGet, url, params...)
|
return doHttpRequest(http.MethodGet, url, params...)
|
||||||
}
|
}
|
||||||
|
|
||||||
//HttpPost send post http request
|
//HttpPost send post http request
|
||||||
func HttpPost(url string, params ...interface{}) (*http.Response, error) {
|
func HttpPost(url string, params ...interface{}) (*http.Response, error) {
|
||||||
return request(http.MethodPost, url, params...)
|
return doHttpRequest(http.MethodPost, url, params...)
|
||||||
}
|
}
|
||||||
|
|
||||||
//HttpPut send put http request
|
//HttpPut send put http request
|
||||||
func HttpPut(url string, params ...interface{}) (*http.Response, error) {
|
func HttpPut(url string, params ...interface{}) (*http.Response, error) {
|
||||||
return request(http.MethodPut, url, params...)
|
return doHttpRequest(http.MethodPut, url, params...)
|
||||||
}
|
}
|
||||||
|
|
||||||
//HttpDelete send delete http request
|
//HttpDelete send delete http request
|
||||||
func HttpDelete(url string, params ...interface{}) (*http.Response, error) {
|
func HttpDelete(url string, params ...interface{}) (*http.Response, error) {
|
||||||
return request(http.MethodDelete, url, params...)
|
return doHttpRequest(http.MethodDelete, url, params...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HttpPatch send patch http request
|
// HttpPatch send patch http request
|
||||||
func HttpPatch(url string, params ...interface{}) (*http.Response, error) {
|
func HttpPatch(url string, params ...interface{}) (*http.Response, error) {
|
||||||
return request(http.MethodPatch, url, params...)
|
return doHttpRequest(http.MethodPatch, url, params...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseHttpResponse decode http response to specified interface
|
// ParseHttpResponse decode http response to specified interface
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func request(method, reqUrl string, params ...interface{}) (*http.Response, error) {
|
func doHttpRequest(method, reqUrl string, params ...interface{}) (*http.Response, error) {
|
||||||
if len(reqUrl) == 0 {
|
if len(reqUrl) == 0 {
|
||||||
return nil, errors.New("url should be specified")
|
return nil, errors.New("url should be specified")
|
||||||
}
|
}
|
||||||
@@ -24,53 +24,29 @@ func request(method, reqUrl string, params ...interface{}) (*http.Response, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
|
err := setUrl(req, reqUrl)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
switch len(params) {
|
switch len(params) {
|
||||||
case 0:
|
|
||||||
err := setUrl(req, reqUrl)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
case 1:
|
case 1:
|
||||||
err := setUrl(req, reqUrl)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = setHeader(req, params[0])
|
err = setHeader(req, params[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
err := setHeader(req, params[0])
|
err := setHeaderAndQueryParam(req, reqUrl, params[0], params[1])
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = setQueryParam(req, reqUrl, params[1])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
err := setHeader(req, params[0])
|
err := setHeaderAndQueryAndBody(req, reqUrl, params[0], params[1], params[2])
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = setQueryParam(req, reqUrl, params[1])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = setBodyByte(req, params[2])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
err := setHeader(req, params[0])
|
err := setHeaderAndQueryAndBody(req, reqUrl, params[0], params[1], params[2])
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = setQueryParam(req, reqUrl, params[1])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = setBodyByte(req, params[2])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -78,13 +54,40 @@ func request(method, reqUrl string, params ...interface{}) (*http.Response, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, e := client.Do(req)
|
resp, e := client.Do(req)
|
||||||
return resp, e
|
return resp, e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam interface{}) error {
|
||||||
|
err := setHeader(req, header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = setQueryParam(req, reqUrl, queryParam)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryParam, body interface{}) error {
|
||||||
|
err := setHeader(req, header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = setQueryParam(req, reqUrl, queryParam)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = setBodyByte(req, body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func setHeader(req *http.Request, header interface{}) error {
|
func setHeader(req *http.Request, header interface{}) error {
|
||||||
if header != nil {
|
if header != nil {
|
||||||
switch v := header.(type) {
|
switch v := header.(type) {
|
||||||
@@ -109,6 +112,7 @@ func setHeader(req *http.Request, header interface{}) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setUrl(req *http.Request, reqUrl string) error {
|
func setUrl(req *http.Request, reqUrl string) error {
|
||||||
u, err := url.Parse(reqUrl)
|
u, err := url.Parse(reqUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -117,6 +121,7 @@ func setUrl(req *http.Request, reqUrl string) error {
|
|||||||
req.URL = u
|
req.URL = u
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) error {
|
func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) error {
|
||||||
var values url.Values
|
var values url.Values
|
||||||
if queryParam != nil {
|
if queryParam != nil {
|
||||||
|
|||||||
@@ -169,9 +169,9 @@ func Filter(slice, function interface{}) interface{} {
|
|||||||
return res.Interface()
|
return res.Interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find iterates over elements of slice, returning the first one that passes a truth test on function.
|
// GroupBy iterate over elements of the slice, each element will be group by criteria, returns two slices
|
||||||
// The function signature should be func(index int, value interface{}) bool .
|
// The function signature should be func(index int, value interface{}) bool .
|
||||||
func Find(slice, function interface{}) interface{} {
|
func GroupBy(slice, function interface{}) (interface{}, interface{}) {
|
||||||
sv := sliceValue(slice)
|
sv := sliceValue(slice)
|
||||||
fn := functionValue(function)
|
fn := functionValue(function)
|
||||||
|
|
||||||
@@ -180,7 +180,33 @@ func Find(slice, function interface{}) interface{} {
|
|||||||
panic("function param should be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
|
panic("function param should be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
|
||||||
}
|
}
|
||||||
|
|
||||||
var index int
|
groupB := reflect.MakeSlice(sv.Type(), 0, 0)
|
||||||
|
groupA := reflect.MakeSlice(sv.Type(), 0, 0)
|
||||||
|
|
||||||
|
for i := 0; i < sv.Len(); i++ {
|
||||||
|
flag := fn.Call([]reflect.Value{reflect.ValueOf(i), sv.Index(i)})[0]
|
||||||
|
if flag.Bool() {
|
||||||
|
groupA = reflect.Append(groupA, sv.Index(i))
|
||||||
|
} else {
|
||||||
|
groupB = reflect.Append(groupB, sv.Index(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return groupA.Interface(), groupB.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find iterates over elements of slice, returning the first one that passes a truth test on function.
|
||||||
|
// The function signature should be func(index int, value interface{}) bool .
|
||||||
|
func Find(slice, function interface{}) (interface{}, bool) {
|
||||||
|
sv := sliceValue(slice)
|
||||||
|
fn := functionValue(function)
|
||||||
|
|
||||||
|
elemType := sv.Type().Elem()
|
||||||
|
if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) {
|
||||||
|
panic("function param should be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
|
||||||
|
}
|
||||||
|
|
||||||
|
index := -1
|
||||||
for i := 0; i < sv.Len(); i++ {
|
for i := 0; i < sv.Len(); i++ {
|
||||||
flag := fn.Call([]reflect.Value{reflect.ValueOf(i), sv.Index(i)})[0]
|
flag := fn.Call([]reflect.Value{reflect.ValueOf(i), sv.Index(i)})[0]
|
||||||
if flag.Bool() {
|
if flag.Bool() {
|
||||||
@@ -188,7 +214,13 @@ func Find(slice, function interface{}) interface{} {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sv.Index(index).Interface()
|
|
||||||
|
if index == -1 {
|
||||||
|
var none interface{}
|
||||||
|
return none, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return sv.Index(index).Interface(), true
|
||||||
}
|
}
|
||||||
|
|
||||||
// FlattenDeep flattens slice recursive
|
// FlattenDeep flattens slice recursive
|
||||||
@@ -378,15 +410,15 @@ func Drop(slice interface{}, n int) interface{} {
|
|||||||
res.Index(i).Set(sv.Index(i + n))
|
res.Index(i).Set(sv.Index(i + n))
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.Interface()
|
|
||||||
} else {
|
|
||||||
res := reflect.MakeSlice(sv.Type(), svLen+n, svLen+n)
|
|
||||||
for i := 0; i < res.Len(); i++ {
|
|
||||||
res.Index(i).Set(sv.Index(i))
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.Interface()
|
return res.Interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res := reflect.MakeSlice(sv.Type(), svLen+n, svLen+n)
|
||||||
|
for i := 0; i < res.Len(); i++ {
|
||||||
|
res.Index(i).Set(sv.Index(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.Interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsertByIndex insert the element into slice at index.
|
// InsertByIndex insert the element into slice at index.
|
||||||
|
|||||||
@@ -161,18 +161,57 @@ func TestFilter(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGroupBy(t *testing.T) {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
|
evenFunc := func(i, num int) bool {
|
||||||
|
return (num % 2) == 0
|
||||||
|
}
|
||||||
|
expectedEven := []int{2, 4, 6}
|
||||||
|
even, odd := GroupBy(nums, evenFunc)
|
||||||
|
|
||||||
|
t.Log("odd", odd)
|
||||||
|
|
||||||
|
t.Log("even", even)
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(IntSlice(even), expectedEven) {
|
||||||
|
internal.LogFailedTestInfo(t, "GroupBy even", nums, expectedEven, even)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOdd := []int{1, 3, 5}
|
||||||
|
if !reflect.DeepEqual(IntSlice(odd), expectedOdd) {
|
||||||
|
internal.LogFailedTestInfo(t, "GroupBy odd", nums, expectedOdd, odd)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestFind(t *testing.T) {
|
func TestFind(t *testing.T) {
|
||||||
nums := []int{1, 2, 3, 4, 5}
|
nums := []int{1, 2, 3, 4, 5}
|
||||||
even := func(i, num int) bool {
|
even := func(i, num int) bool {
|
||||||
return num%2 == 0
|
return num%2 == 0
|
||||||
}
|
}
|
||||||
res := Find(nums, even)
|
res, ok := Find(nums, even)
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("found nothing")
|
||||||
|
}
|
||||||
|
|
||||||
if res != 2 {
|
if res != 2 {
|
||||||
internal.LogFailedTestInfo(t, "Find", nums, 2, res)
|
internal.LogFailedTestInfo(t, "Find", nums, 2, res)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFindFoundNothing(t *testing.T) {
|
||||||
|
nums := []int{1, 1, 1, 1, 1, 1}
|
||||||
|
findFunc := func(i, num int) bool {
|
||||||
|
return num > 1
|
||||||
|
}
|
||||||
|
_, ok := Find(nums, findFunc)
|
||||||
|
if ok {
|
||||||
|
t.Fatal("found something")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestFlattenDeep(t *testing.T) {
|
func TestFlattenDeep(t *testing.T) {
|
||||||
input := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
|
input := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
|
||||||
expected := []string{"a", "b", "c", "d"}
|
expected := []string{"a", "b", "c", "d"}
|
||||||
|
|||||||
Reference in New Issue
Block a user