Skip to content

Commit

Permalink
✨ feat: arr - add new func for quick convert slice type
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Jan 28, 2023
1 parent 97a2863 commit 75d8d89
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 46 deletions.
147 changes: 103 additions & 44 deletions arrutil/convert.go
Expand Up @@ -7,14 +7,15 @@ import (
"strings"

"github.com/gookit/goutil/mathutil"
"github.com/gookit/goutil/reflects"
"github.com/gookit/goutil/strutil"
)

// ErrInvalidType error
var ErrInvalidType = errors.New("the input param type is invalid")

/*************************************************************
* helper func for strings
* Join func for slice
*************************************************************/

// JoinStrings alias of strings.Join
Expand All @@ -27,32 +28,21 @@ func StringsJoin(sep string, ss ...string) string {
return strings.Join(ss, sep)
}

// StringsToInts string slice to int slice
func StringsToInts(ss []string) (ints []int, err error) {
for _, str := range ss {
iVal, err := strconv.Atoi(str)
if err != nil {
return nil, err
}

ints = append(ints, iVal)
// JoinSlice join []any slice to string.
func JoinSlice(sep string, arr ...any) string {
if arr == nil {
return ""
}
return
}

// MustToStrings convert array or slice to []string
func MustToStrings(arr any) []string {
ret, _ := ToStrings(arr)
return ret
}

// StringsToSlice convert []string to []any
func StringsToSlice(ss []string) []any {
args := make([]any, len(ss))
for i, s := range ss {
args[i] = s
var sb strings.Builder
for i, v := range arr {
if i > 0 {
sb.WriteString(sep)
}
sb.WriteString(strutil.QuietString(v))
}
return args

return sb.String()
}

/*************************************************************
Expand Down Expand Up @@ -88,14 +78,66 @@ func MustToInt64s(arr any) []int64 {
func SliceToInt64s(arr []any) []int64 {
i64s := make([]int64, len(arr))
for i, v := range arr {
i64s[i] = mathutil.MustInt64(v)
i64s[i] = mathutil.QuietInt64(v)
}
return i64s
}

// StringsAsInts convert and ignore error
func StringsAsInts(ss []string) []int {
ints, _ := StringsTryInts(ss)
return ints
}

// StringsToInts string slice to int slice
func StringsToInts(ss []string) (ints []int, err error) {
return StringsTryInts(ss)
}

// StringsTryInts string slice to int slice
func StringsTryInts(ss []string) (ints []int, err error) {
for _, str := range ss {
iVal, err := strconv.Atoi(str)
if err != nil {
return nil, err
}

ints = append(ints, iVal)
}
return
}

// MustToStrings convert array or slice to []string
func MustToStrings(arr any) []string {
ret, err := ToStrings(arr)
if err != nil {
panic(err)
}
return ret
}

// AnyToStrings convert array or slice to []string
func AnyToStrings(arr any) []string {
ret, _ := ToStrings(arr)
return ret
}

// StringsToSlice convert []string to []any
func StringsToSlice(ss []string) []any {
args := make([]any, len(ss))
for i, s := range ss {
args[i] = s
}
return args
}

// ToStrings convert any(allow: array,slice) to []string
func ToStrings(arr any) (ret []string, err error) {
rv := reflect.ValueOf(arr)
if rv.Kind() == reflect.String {
return []string{rv.String()}, nil
}

if rv.Kind() != reflect.Slice && rv.Kind() != reflect.Array {
err = ErrInvalidType
return
Expand All @@ -114,13 +156,47 @@ func ToStrings(arr any) (ret []string, err error) {

// SliceToStrings convert []any to []string
func SliceToStrings(arr []any) []string {
return QuietStrings(arr)
}

// QuietStrings convert []any to []string
func QuietStrings(arr []any) []string {
ss := make([]string, len(arr))
for i, v := range arr {
ss[i] = strutil.MustString(v)
ss[i] = strutil.QuietString(v)
}
return ss
}

// ConvType convert type of slice elements to new type slice, by the given newElemTyp type.
//
// Supports conversion between []string, []intX, []uintX, []floatX.
//
// Usage:
//
// ints, _ := arrutil.ConvType([]string{"12", "23"}, 1) // []int{12, 23}
func ConvType[T any, R any](arr []T, newElemTyp R) ([]R, error) {
newArr := make([]R, len(arr))
elemTyp := reflect.TypeOf(newElemTyp)

for i, elem := range arr {
var anyElem any = elem
// type is same.
if _, ok := anyElem.(R); ok {
newArr[i] = anyElem.(R)
continue
}

// need conv type.
rfVal, err := reflects.ValueByType(elem, elemTyp)
if err != nil {
return nil, err
}
newArr[i] = rfVal.Interface().(R)
}
return newArr, nil
}

// AnyToString simple and quickly convert any array, slice to string
func AnyToString(arr any) string {
return NewFormatter(arr).Format()
Expand All @@ -143,26 +219,9 @@ func ToString(arr []any) string {
if i > 0 {
sb.WriteByte(',')
}
sb.WriteString(strutil.MustString(v))
sb.WriteString(strutil.QuietString(v))
}

sb.WriteByte(']')
return sb.String()
}

// JoinSlice join []any slice to string.
func JoinSlice(sep string, arr ...any) string {
if arr == nil {
return ""
}

var sb strings.Builder
for i, v := range arr {
if i > 0 {
sb.WriteString(sep)
}
sb.WriteString(strutil.MustString(v))
}

return sb.String()
}
33 changes: 31 additions & 2 deletions arrutil/convert_test.go
Expand Up @@ -47,8 +47,9 @@ func TestToStrings(t *testing.T) {
as := arrutil.StringsToSlice([]string{"1", "2"})
is.Eq(`[]interface {}{"1", "2"}`, fmt.Sprintf("%#v", as))

_, err = arrutil.ToStrings("b")
is.Err(err)
ss, err = arrutil.ToStrings("b")
is.Nil(err)
is.Eq(`[]string{"b"}`, fmt.Sprintf("%#v", ss))

_, err = arrutil.ToStrings([]any{[]int{1}, nil})
is.Err(err)
Expand Down Expand Up @@ -89,6 +90,34 @@ func TestStringsToInts(t *testing.T) {

_, err = arrutil.StringsToInts([]string{"a", "b"})
is.Err(err)

ints = arrutil.StringsAsInts([]string{"1", "2"})
is.Eq("[]int{1, 2}", fmt.Sprintf("%#v", ints))
is.Nil(arrutil.StringsAsInts([]string{"abc"}))
}

func TestConvType(t *testing.T) {
is := assert.New(t)

// []string => []int
arr, err := arrutil.ConvType([]string{"1", "2"}, 1)
is.Nil(err)
is.Eq("[]int{1, 2}", fmt.Sprintf("%#v", arr))

// []int => []string
arr1, err := arrutil.ConvType([]int{1, 2}, "1")
is.Nil(err)
is.Eq(`[]string{"1", "2"}`, fmt.Sprintf("%#v", arr1))

// not need conv
arr2, err := arrutil.ConvType([]string{"1", "2"}, "1")
is.Nil(err)
is.Eq(`[]string{"1", "2"}`, fmt.Sprintf("%#v", arr2))

// conv error
arr3, err := arrutil.ConvType([]string{"ab", "cd"}, 1)
is.Err(err)
is.Nil(arr3)
}

func TestJoinSlice(t *testing.T) {
Expand Down

0 comments on commit 75d8d89

Please sign in to comment.