1 Star 0 Fork 0

蔡风华 / baseutils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
extend.go 10.46 KB
一键复制 编辑 原始数据 按行查看 历史
package extendutil
import (
"bytes"
"fmt"
"math"
"os"
"os/exec"
"path/filepath"
"reflect"
"regexp"
"strings"
"unicode/utf8"
"gitee.com/cfh008/runutils"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
type Comparable interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
float32 | ~float64 | ~complex64 | ~complex128 |
string
}
type IntegerComparable interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
type PositiveNegativeNumeral interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 | float32 | ~float64
}
func JoinBytes(sep []byte, pBytes ...[]byte) []byte {
return bytes.Join(pBytes, sep)
}
func Reverse(slice interface{}) {
s := reflect.ValueOf(slice)
// if s is a pointer of slice
if s.Kind() == reflect.Ptr {
s = s.Elem()
}
swp := reflect.Swapper(s.Interface())
for i, j := 0, s.Len()-1; i < j; i, j = i+1, j-1 {
swp(i, j)
}
}
func ToInt(value interface{}) (int, bool) {
var v int
var ok bool
switch ret := value.(type) {
case int:
v = ret
ok = true
case float64:
v = int(ret)
ok = true
default:
ok = false
}
return v, ok
}
func ToString(value interface{}) (string, bool) {
var v string
var ok bool
switch ret := value.(type) {
case string:
v = ret
ok = true
default:
ok = false
}
return v, ok
}
func MergeMap[T Comparable](src map[T]interface{}, others ...map[T]interface{}) map[T]interface{} {
rtn := make(map[T]interface{})
for k, v := range src {
rtn[k] = v
}
for _, item := range others {
for k, v := range item {
rtn[k] = v
}
}
return rtn
}
func MergeStringMap(src map[string]interface{}, others ...map[string]interface{}) map[string]interface{} {
rtn := make(map[string]interface{})
for k, v := range src {
rtn[k] = v
}
for _, item := range others {
for k, v := range item {
rtn[k] = v
}
}
return rtn
}
func ExtractFirstCaptureData(src []byte, toFind string) (ret []byte, ok bool) {
argReg := regexp.MustCompile(toFind)
toProcess := src
rtnIndexs := argReg.FindSubmatchIndex(toProcess)
if rtnIndexs == nil {
ok = false
return
}
groupIndex := 1
ret = GetCaptureBytes(toProcess, rtnIndexs, groupIndex)
ok = true
return
}
func GetGroupIndexPair(index int) (groupBegin, groupEnd int) {
groupBegin = 2 * index
groupEnd = 2*index + 1
return
}
func GetCaptureBytes(data []byte, submatchIndexs []int, index int) (result []byte) {
groupBegin, groupEnd := GetGroupIndexPair(index)
begin := submatchIndexs[groupBegin]
end := submatchIndexs[groupEnd]
return data[begin:end]
}
func InterfaceIsNil(i interface{}) bool {
ret := i == nil
if !ret { //需要进一步做判断
vi := reflect.ValueOf(i)
kind := reflect.ValueOf(i).Kind()
if kind == reflect.Slice ||
kind == reflect.Map ||
kind == reflect.Chan ||
kind == reflect.Interface ||
kind == reflect.Func ||
kind == reflect.Ptr {
return vi.IsNil()
}
}
return ret
}
func Min[T IntegerComparable](a, b T) T {
if a < b {
return a
}
return b
}
func Max[T IntegerComparable](a, b T) T {
if a > b {
return a
}
return b
}
func Abs[T PositiveNegativeNumeral](a T) T {
if a >= 0 {
return a
}
return -a
}
func GetUniqueValueArray[T Comparable](valueArray []T) []T {
defer func() {
if r := recover(); r != nil {
panicInfo := fmt.Sprintf("%v panic info: %v", runutils.RunFuncName(), r)
panic(panicInfo)
}
}()
appendedMap := make(map[T]bool)
result := make([]T, 0, 64)
for _, value := range valueArray {
_, ok := appendedMap[value]
if !ok {
result = append(result, value)
appendedMap[value] = true
}
}
return result
}
func GetUniqueValueArrayExcludingACertain[T Comparable](valueArray []T, certain T) []T {
defer func() {
if r := recover(); r != nil {
panicInfo := fmt.Sprintf("%v panic info: %v", runutils.RunFuncName(), r)
panic(panicInfo)
}
}()
midArray := GetUniqueValueArray(valueArray)
keyMap := make(map[T]bool)
for _, item := range midArray {
keyMap[item] = true
}
keyMap[certain] = false
result := make([]T, 0, 64)
for _, value := range midArray {
if keyMap[value] {
result = append(result, value)
}
}
return result
}
func AppendWithUniqueItem[T Comparable](srcArray []T, items ...T) (result []T) {
for _, item := range items {
isUnique := true
for _, oriItem := range srcArray {
if oriItem == item {
isUnique = false
break
}
}
if isUnique {
srcArray = append(srcArray, item)
}
}
result = srcArray
return
}
// 检测给定数据项是否在指定Slice中
func IsInSlice[T Comparable](srcArray []T, item T) bool {
isInSlice := false
for _, oriItem := range srcArray {
if oriItem == item {
isInSlice = true
break
}
}
return isInSlice
}
func Equal[T Comparable](a []T, b []T) bool {
// If one is nil, the other must also be nil.
if (a == nil) != (b == nil) {
return false
}
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
func GetFirstCharOfString(src string) (result string, size int) {
charRune, size := utf8.DecodeRuneInString(src)
if charRune != utf8.RuneError {
result = string(charRune)
} else {
size = 0
}
return
}
func GetCharOfStringWithIndex(src string, index int) (result string, size int) {
var i int
var item string
var charSize int
offset := 0
for i = 0; i <= index; i++ {
item, charSize = GetFirstCharOfString(src[offset:])
if charSize > 0 {
size = charSize
offset += charSize
} else {
size = 0
break
}
}
if i >= index && size > 0 {
result = item
}
return
}
type chNumberLevel struct {
Val int
/*
中文数字节位分权
大权位: 万,亿……
小权位; 十,百,千
*/
IsPower bool
}
// 权位对应表
var chPowerNumMap = map[string]*chNumberLevel{
"亿": {
int(math.Pow10(8)),
true,
},
"万": {
int(math.Pow10(4)),
true,
},
"千": {
int(math.Pow10(3)),
false,
},
"百": {
int(math.Pow10(2)),
false,
},
"十": {
int(math.Pow10(1)),
false,
},
}
// 数值对应表
var ChToArNumberMap = map[string]int{
"零": 0,
"一": 1,
"二": 2,
"三": 3,
"四": 4,
"五": 5,
"六": 6,
"七": 7,
"八": 8,
"九": 9,
}
// chPowerNumber 获取权位的信息
func chPowerNumber(inputStr string) (int, bool) {
if powerNum, exist := chPowerNumMap[inputStr]; exist {
return powerNum.Val, powerNum.IsPower
}
return 0, false
}
// ConvertChNumberToArNumber 中文数字转阿拉伯数字
func ConvertChNumberToArNumber(inputStrNum string) (ansNum int) {
chNum := []rune(inputStrNum)
var (
CurNumber int
SumNumber int
)
for index := 0; index < len(chNum); index++ {
// 将中文转为阿拉伯数字
var getNum = ChToArNumberMap[string(chNum[index])]
// 如果转换失败 getNum = -1
if getNum > 0 {
// 处理九九八专用
if CurNumber != 0 {
CurNumber *= int(math.Pow10(1))
CurNumber += getNum
} else {
CurNumber = getNum
}
// 如果队列结束,则终止循环,并将临时数据添加到ansNum
if index == len(chNum)-1 {
SumNumber += CurNumber
ansNum += SumNumber
break
}
} else {
// getNum 等于 -1 或 0 进入这里
// 没有零对应的权,所以这一步所得出的大概率是上面提到的权位信息
powerNum, isPower := chPowerNumber(string(chNum[index]))
// 如果是大权位,则准备下一个权区间
if isPower {
SumNumber = (SumNumber + CurNumber) * powerNum
ansNum, SumNumber = ansNum+SumNumber, 0
} else {
// 如果是小权位,则将当前数字添加到临时数和中
if CurNumber != 0 {
SumNumber += CurNumber * powerNum
} else {
SumNumber += powerNum
}
}
CurNumber = 0
// 如果队列结束,则终止循环,并将临时数据添加到ansNum
if index == len(chNum)-1 {
ansNum += SumNumber
break
}
}
}
return
}
func MapToStruct(m map[string]interface{}, s interface{}) error {
val := reflect.ValueOf(s).Elem()
for k, v := range m {
// 将key的首字母大写以匹配结构体中的字段
caser := cases.Title(language.English, cases.NoLower)
fieldName := caser.String(k)
fieldVal := val.FieldByName(fieldName)
// 确保结构体有这个字段,并且传入的值类型与结构体字段类型相匹配
if fieldVal.IsValid() && fieldVal.CanSet() {
vVal := reflect.ValueOf(v)
targetVal := vVal
// 检查结构体字段的类型,并进行适当的类型转换
switch fieldVal.Kind() {
case reflect.Int:
switch v := v.(type) {
case float64:
// Go默认将JSON数字解码为float64,因此我们需要将其转换为int
targetVal = reflect.ValueOf(int(v))
case int64:
targetVal = reflect.ValueOf(int(v))
case int:
targetVal = reflect.ValueOf(v)
default:
return fmt.Errorf("cannot set field %s: type mismatch with map type %v and struct type %v", fieldName, vVal.Type(), fieldVal.Type())
}
case reflect.Int64:
switch v := v.(type) {
case float64:
// Go默认将JSON数字解码为float64,因此我们需要将其转换为int
targetVal = reflect.ValueOf(int64(v))
case int:
targetVal = reflect.ValueOf(int64(v))
case int64:
targetVal = reflect.ValueOf(v)
default:
return fmt.Errorf("cannot set field %s: type mismatch ", fieldName)
}
case reflect.Float64:
switch v := v.(type) {
case int:
// 如果原始类型是int,我们可以安全地将其转换为float64
targetVal = reflect.ValueOf(float64(v))
case int64:
targetVal = reflect.ValueOf(float64(v))
case float64:
targetVal = reflect.ValueOf(v)
default:
return fmt.Errorf("cannot set field %s: type mismatch", fieldName)
}
// 有需要再添加其他类型的case处理...
default:
if !vVal.Type().AssignableTo(fieldVal.Type()) {
return fmt.Errorf("field %v provided value type %v didn't match obj field type %v", k, vVal.Type(), fieldVal.Type())
}
}
fieldVal.Set(targetVal)
} else {
return fmt.Errorf("no such field: %s in obj", k)
}
}
return nil
}
func GetExecParentDir() (result string, err error) {
file, doErr := exec.LookPath(os.Args[0])
if doErr != nil {
err = fmt.Errorf("exec.LookPath(%v) failed with %v", os.Args[0], doErr)
return
}
app, doErr := filepath.Abs(file)
if doErr != nil {
err = fmt.Errorf("filepath.Abs(%v) failed with %v", file, doErr)
return
}
sep := string(filepath.Separator)
i := strings.LastIndex(app, sep)
if i < 0 {
err = fmt.Errorf("strings.LastIndex(%v, %v) got %v", app, sep, i)
return
}
result = app[0:i]
return
}
Go
1
https://gitee.com/cfh008/baseutils.git
git@gitee.com:cfh008/baseutils.git
cfh008
baseutils
baseutils
v0.3.1

搜索帮助