mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-05 21:32:27 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cf59323ff | ||
|
|
afec27fb4e | ||
|
|
3021985df9 | ||
|
|
188d52cd9d | ||
|
|
8c8f991390 | ||
|
|
b7bb7c6ae0 | ||
|
|
2e04a41f34 | ||
|
|
acb7873832 | ||
|
|
8b3cc3266d |
10
README.md
10
README.md
@@ -6,7 +6,7 @@
|
||||
<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://goreportcard.com/report/github.com/duke-git/lancet)
|
||||
[](https://codecov.io/gh/duke-git/lancet)
|
||||
@@ -207,15 +207,18 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
- 函数列表:
|
||||
- Function list:
|
||||
|
||||
```go
|
||||
func ClearFile(path string) error //write empty string to path file
|
||||
func CreateFile(path string) bool // create a file in path
|
||||
func CopyFile(srcFilePath string, dstFilePath string) error //copy src file to dst file
|
||||
func IsExist(path string) bool //checks if a file or directory exists
|
||||
func IsDir(path string) bool //checks if the path is directy or not
|
||||
func ListFileNames(path string) ([]string, error) //return all file names in the path
|
||||
func RemoveFile(path string) error //remove the path file
|
||||
func ReadFileToString(path string) (string, error) //return string of file content
|
||||
func ReadFileByLine(path string)([]string, error) //read file content by line
|
||||
```
|
||||
|
||||
#### 5. formatter is for data format
|
||||
@@ -350,7 +353,9 @@ func Chunk(slice []interface{}, size int) [][]interface{} //creates an slice of
|
||||
func ConvertSlice(originalSlice interface{}, newSliceType reflect.Type) interface{} //convert originalSlice to newSliceType
|
||||
func Difference(slice1, slice2 interface{}) interface{} //creates an slice of whose element not included in the other given slice
|
||||
func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error) //delete the element of slice from start index to end index - 1
|
||||
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 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 IntSlice(slice interface{}) ([]int, error) //convert value to int slice
|
||||
func InterfaceSlice(slice interface{}) []interface{} //convert value to interface{} slice
|
||||
func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //insert the element into slice at index.
|
||||
@@ -358,6 +363,7 @@ func Map(slice, function interface{}) interface{} //map lisce, function signatur
|
||||
func ReverseSlice(slice interface{}) //revere slice
|
||||
func Reduce(slice, function, zero interface{}) interface{} //reduce slice, function signature should be func(index int, value1, value2 interface{}) interface{}
|
||||
func SortByField(slice interface{}, field string, sortType ...string) error //sort struct slice by field
|
||||
func Some(slice, function interface{}) bool //return true if any of the values in the list pass the predicate function, function signature should be func(index int, value interface{}) bool
|
||||
func StringSlice(slice interface{}) []string //convert value to string slice
|
||||
func Unique(slice interface{}) interface{} //remove duplicate elements in slice
|
||||
func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //update the slice element at index.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<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://goreportcard.com/report/github.com/duke-git/lancet)
|
||||
[](https://codecov.io/gh/duke-git/lancet)
|
||||
@@ -23,7 +23,7 @@
|
||||
- 👏 全面、高效、可复用
|
||||
- 💪 100+常用go工具函数,支持string、slice、datetime、net、crypt...
|
||||
- 💅 只依赖go标准库
|
||||
- 🌍 所有导出函数单测试覆盖率100%
|
||||
- 🌍 所有导出函数单元测试覆盖率100%
|
||||
|
||||
### 安装
|
||||
|
||||
@@ -100,7 +100,7 @@ func StructToMap(value interface{}) (map[string]interface{}, error) //struct串
|
||||
|
||||
#### 2. cryptor加解密包
|
||||
|
||||
- 加密函数是支持md5, hmac, aes, des, ras
|
||||
- 加密函数支持md5, hmac, aes, des, ras
|
||||
- 导入包:import "github.com/duke-git/lancet/cryptor"
|
||||
|
||||
```go
|
||||
@@ -211,12 +211,15 @@ func main() {
|
||||
- 函数列表:
|
||||
|
||||
```go
|
||||
func ClearFile(path string) error //清空文件内容
|
||||
func IsExist(path string) bool //判断文件/目录是否存在
|
||||
func CreateFile(path string) bool //创建文件
|
||||
func IsDir(path string) bool //判断是否为目录
|
||||
func RemoveFile(path string) error //删除文件
|
||||
func CopyFile(srcFilePath string, dstFilePath string) error //复制文件
|
||||
func ListFileNames(path string) ([]string, error) //列出目录下所有文件名称
|
||||
func ReadFileToString(path string) (string, error) //读取文件内容为字符串
|
||||
func ReadFileByLine(path string)([]string, error) //按行读取文件内容
|
||||
```
|
||||
|
||||
#### 5. formatter格式化处理包
|
||||
@@ -351,6 +354,8 @@ func Chunk(slice []interface{}, size int) [][]interface{} //均分slice
|
||||
func ConvertSlice(originalSlice interface{}, newSliceType reflect.Type) interface{} //将originalSlice转换为 newSliceType
|
||||
func Difference(slice1, slice2 interface{}) interface{} //返回
|
||||
func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error) //删除切片中start到end位置的值
|
||||
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 Filter(slice, function interface{}) interface{} //过滤slice, 函数签名:func(index int, value interface{}) bool
|
||||
func IntSlice(slice interface{}) ([]int, error) //转成int切片
|
||||
func InterfaceSlice(slice interface{}) []interface{} //转成interface{}切片
|
||||
@@ -358,6 +363,7 @@ func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}
|
||||
func Map(slice, function interface{}) interface{} //遍历切片, 函数签名:func(index int, value interface{}) interface{}
|
||||
func ReverseSlice(slice interface{}) //反转切片
|
||||
func Reduce(slice, function, zero interface{}) interface{} //切片reduce操作, 函数签名:func(index int, value1, value2 interface{}) interface{}
|
||||
func Some(slice, function interface{}) bool //slice中任意一个元素都符合函数条件时返回true, 否则返回false. 函数签名:func(index int, value interface{}) bool
|
||||
func SortByField(slice interface{}, field string, sortType ...string) error //对struct切片进行排序
|
||||
func StringSlice(slice interface{}) []string //转为string切片
|
||||
func Unique(slice interface{}) interface{} //去重切片
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package fileutil
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@@ -75,6 +76,53 @@ func CopyFile(srcFilePath string, dstFilePath string) error {
|
||||
}
|
||||
}
|
||||
|
||||
//ClearFile write empty string to path file
|
||||
func ClearFile(path string) error {
|
||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.WriteString("")
|
||||
return err
|
||||
}
|
||||
|
||||
//ReadFileToString return string of file content
|
||||
func ReadFileToString(path string) (string, error) {
|
||||
bytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
}
|
||||
|
||||
// ReadFileByLine read file line by line
|
||||
func ReadFileByLine(path string) ([]string, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
res := make([]string, 0)
|
||||
buf := bufio.NewReader(f)
|
||||
|
||||
for {
|
||||
line, _, err := buf.ReadLine()
|
||||
l := string(line)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
res = append(res, l)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ListFileNames return all file names in the path
|
||||
func ListFileNames(path string) ([]string, error) {
|
||||
if !IsExist(path) {
|
||||
|
||||
@@ -96,5 +96,43 @@ func TestListFileNames(t *testing.T) {
|
||||
utils.LogFailedTestInfo(t, "ToChar", "./", expected, filesInCurrentPath)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestReadFileToString(t *testing.T) {
|
||||
path := "./text.txt"
|
||||
CreateFile(path)
|
||||
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||
f.WriteString("hello world")
|
||||
|
||||
res, _ := ReadFileToString(path)
|
||||
if res != "hello world" {
|
||||
utils.LogFailedTestInfo(t, "ReadFileToString", path, "hello world", res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClearFile(t *testing.T) {
|
||||
path := "./text.txt"
|
||||
CreateFile(path)
|
||||
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||
f.WriteString("hello world")
|
||||
|
||||
CreateFile(path)
|
||||
|
||||
res, _ := ReadFileToString(path)
|
||||
if res != "" {
|
||||
utils.LogFailedTestInfo(t, "CreateFile", path, "", res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadFileByLine(t *testing.T) {
|
||||
path := "./text.txt"
|
||||
CreateFile(path)
|
||||
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||
f.WriteString("hello\nworld")
|
||||
|
||||
expected := []string{"hello", "world"}
|
||||
res, _ := ReadFileByLine(path)
|
||||
if !reflect.DeepEqual(res, expected) {
|
||||
utils.LogFailedTestInfo(t, "ReadFileByLine", path, expected, res)
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) err
|
||||
case map[string]interface{}:
|
||||
values = url.Values{}
|
||||
for k := range v {
|
||||
values.Set(k, fmt.Sprintf("%s", v[k]))
|
||||
values.Set(k, fmt.Sprintf("%v", v[k]))
|
||||
}
|
||||
case url.Values:
|
||||
values = v
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/*
|
||||
* @Descripttion:
|
||||
* @version: v1.0.0
|
||||
* @Author: dudaodong@kingsoft.com
|
||||
* @Date: 2021-11-29 11:43:28
|
||||
* @LastEditors: dudaodong@kingsoft.com
|
||||
* @LastEditTime: 2021-12-01 18:05:29
|
||||
*/
|
||||
package random
|
||||
|
||||
import (
|
||||
@@ -60,6 +68,4 @@ func TestRandBytes(t *testing.T) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -89,6 +89,50 @@ func Difference(slice1, slice2 interface{}) interface{} {
|
||||
return res.Interface()
|
||||
}
|
||||
|
||||
// Every return true if all of the values in the slice pass the predicate function.
|
||||
// The function signature should be func(index int, value interface{}) bool .
|
||||
func Every(slice, function interface{}) bool {
|
||||
sv := sliceValue(slice)
|
||||
fn := functionValue(function)
|
||||
|
||||
elemType := sv.Type().Elem()
|
||||
if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) {
|
||||
panic("Filter function must be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
|
||||
}
|
||||
|
||||
var indexes []int
|
||||
for i := 0; i < sv.Len(); i++ {
|
||||
flag := fn.Call([]reflect.Value{reflect.ValueOf(i), sv.Index(i)})[0]
|
||||
if flag.Bool() {
|
||||
indexes = append(indexes, i)
|
||||
}
|
||||
}
|
||||
|
||||
return len(indexes) == sv.Len()
|
||||
}
|
||||
|
||||
// Some return true if any of the values in the list pass the predicate function.
|
||||
// The function signature should be func(index int, value interface{}) bool .
|
||||
func Some(slice, function interface{}) bool {
|
||||
sv := sliceValue(slice)
|
||||
fn := functionValue(function)
|
||||
|
||||
elemType := sv.Type().Elem()
|
||||
if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) {
|
||||
panic("Filter function must be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
|
||||
}
|
||||
|
||||
var indexes []int
|
||||
for i := 0; i < sv.Len(); i++ {
|
||||
flag := fn.Call([]reflect.Value{reflect.ValueOf(i), sv.Index(i)})[0]
|
||||
if flag.Bool() {
|
||||
indexes = append(indexes, i)
|
||||
}
|
||||
}
|
||||
|
||||
return len(indexes) > 0
|
||||
}
|
||||
|
||||
// Filter iterates over elements of slice, returning an slice of all elements `signature` returns truthy for.
|
||||
// The function signature should be func(index int, value interface{}) bool .
|
||||
func Filter(slice, function interface{}) interface{} {
|
||||
@@ -115,6 +159,28 @@ func Filter(slice, function interface{}) interface{} {
|
||||
return res.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{} {
|
||||
sv := sliceValue(slice)
|
||||
fn := functionValue(function)
|
||||
|
||||
elemType := sv.Type().Elem()
|
||||
if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) {
|
||||
panic("Filter function must be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
|
||||
}
|
||||
|
||||
var index int
|
||||
for i := 0; i < sv.Len(); i++ {
|
||||
flag := fn.Call([]reflect.Value{reflect.ValueOf(i), sv.Index(i)})[0]
|
||||
if flag.Bool() {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
return sv.Index(index).Interface()
|
||||
}
|
||||
|
||||
// Map creates an slice of values by running each element of `slice` thru `function`.
|
||||
// The function signature should be func(index int, value interface{}) interface{}.
|
||||
func Map(slice, function interface{}) interface{} {
|
||||
|
||||
@@ -96,15 +96,39 @@ func TestConvertSlice(t *testing.T) {
|
||||
//}
|
||||
}
|
||||
|
||||
func TestEvery(t *testing.T) {
|
||||
nums := []int{1, 2, 3, 5}
|
||||
isEven := func(i, num int) bool {
|
||||
return num%2 == 0
|
||||
}
|
||||
res := Every(nums, isEven)
|
||||
if res != false {
|
||||
utils.LogFailedTestInfo(t, "Every", nums, false, res)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestSome(t *testing.T) {
|
||||
nums := []int{1, 2, 3, 5}
|
||||
isEven := func(i, num int) bool {
|
||||
return num%2 == 0
|
||||
}
|
||||
res := Some(nums, isEven)
|
||||
if res != true {
|
||||
utils.LogFailedTestInfo(t, "Some", nums, true, res)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilter(t *testing.T) {
|
||||
s1 := []int{1, 2, 3, 4, 5}
|
||||
nums := []int{1, 2, 3, 4, 5}
|
||||
even := func(i, num int) bool {
|
||||
return num%2 == 0
|
||||
}
|
||||
e1 := []int{2, 4}
|
||||
r1 := Filter(s1, even)
|
||||
r1 := Filter(nums, even)
|
||||
if !reflect.DeepEqual(r1, e1) {
|
||||
utils.LogFailedTestInfo(t, "Filter", s1, e1, r1)
|
||||
utils.LogFailedTestInfo(t, "Filter", nums, e1, r1)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
@@ -137,6 +161,18 @@ func TestFilter(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestFind(t *testing.T) {
|
||||
nums := []int{1, 2, 3, 4, 5}
|
||||
even := func(i, num int) bool {
|
||||
return num%2 == 0
|
||||
}
|
||||
res := Find(nums, even)
|
||||
if res != 2 {
|
||||
utils.LogFailedTestInfo(t, "Find", nums, 2, res)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestMap(t *testing.T) {
|
||||
s1 := []int{1, 2, 3, 4}
|
||||
multiplyTwo := func(i, num int) int {
|
||||
@@ -342,11 +378,6 @@ func TestUpdateByIndex(t *testing.T) {
|
||||
r3 := []string{"a", "b", "1"}
|
||||
updateByIndex(t, t1, 2, "1", r3)
|
||||
|
||||
//failed
|
||||
//t1 = []string{"a","b","c"}
|
||||
//r4 := []string{"a", "b", "1"}
|
||||
//updateByIndex(t, t1, 3, "1", r4)
|
||||
|
||||
}
|
||||
|
||||
func updateByIndex(t *testing.T, test interface{}, index int, value, expected interface{}) {
|
||||
|
||||
Reference in New Issue
Block a user