github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/sliceutils/sliceutils.go (about)

     1  package sliceutils
     2  
     3  import (
     4  	"github.com/pkg/errors"
     5  	"reflect"
     6  )
     7  
     8  // StringSlice2InterfaceSlice converts string slice to interface slice
     9  func StringSlice2InterfaceSlice(strSlice []string) []interface{} {
    10  	ret := make([]interface{}, len(strSlice))
    11  	for i, v := range strSlice {
    12  		ret[i] = v
    13  	}
    14  	return ret
    15  }
    16  
    17  // InterfaceSlice2StringSlice converts interface slice to string slice
    18  func InterfaceSlice2StringSlice(strSlice []interface{}) []string {
    19  	ret := make([]string, len(strSlice))
    20  	for i, v := range strSlice {
    21  		ret[i] = v.(string)
    22  	}
    23  	return ret
    24  }
    25  
    26  // Contains asserts src contains test
    27  func Contains(src []interface{}, test interface{}) bool {
    28  	for _, item := range src {
    29  		if item == test {
    30  			return true
    31  		}
    32  	}
    33  	return false
    34  }
    35  
    36  // ContainsDeep asserts src contains test using reflect.DeepEqual
    37  func ContainsDeep(src []interface{}, test interface{}) bool {
    38  	for _, item := range src {
    39  		if reflect.DeepEqual(item, test) {
    40  			return true
    41  		}
    42  	}
    43  	return false
    44  }
    45  
    46  // StringContains asserts src contains test
    47  func StringContains(src []string, test string) bool {
    48  	for _, item := range src {
    49  		if item == test {
    50  			return true
    51  		}
    52  	}
    53  	return false
    54  }
    55  
    56  // StringFilter filters string slice by callback function fn
    57  // If fn returns true, the item will be appended to result
    58  func StringFilter(src []string, fn func(item string) bool) []string {
    59  	var ret []string
    60  	for _, item := range src {
    61  		if fn(item) {
    62  			ret = append(ret, item)
    63  		}
    64  	}
    65  	return ret
    66  }
    67  
    68  // IndexOf returns index of element in string slice data
    69  func IndexOf(element string, data []string) int {
    70  	for k, v := range data {
    71  		if element == v {
    72  			return k
    73  		}
    74  	}
    75  	return -1 //not found.
    76  }
    77  
    78  // IndexOfAny returns index of element in slice data
    79  func IndexOfAny(target interface{}, anySlice interface{}) (int, error) {
    80  	if reflect.TypeOf(anySlice).Kind() != reflect.Slice {
    81  		return -1, errors.New("not slice")
    82  	}
    83  	data := reflect.ValueOf(anySlice)
    84  	for i := 0; i < data.Len(); i++ {
    85  		elem := data.Index(i)
    86  		if elem.Interface() == target {
    87  			return i, nil
    88  		}
    89  	}
    90  	return -1, nil //not found.
    91  }
    92  
    93  // IsEmpty assert src is an empty slice
    94  func IsEmpty(src interface{}) bool {
    95  	if slice, ok := TakeSliceArg(src); ok {
    96  		return slice == nil || len(slice) == 0
    97  	}
    98  	panic("not slice")
    99  }
   100  
   101  // TakeSliceArg https://ahmet.im/blog/golang-take-slices-of-any-type-as-input-parameter/
   102  func TakeSliceArg(arg interface{}) (out []interface{}, ok bool) {
   103  	slice, success := takeArg(arg, reflect.Slice)
   104  	if !success {
   105  		ok = false
   106  		return
   107  	}
   108  	c := slice.Len()
   109  	out = make([]interface{}, c)
   110  	for i := 0; i < c; i++ {
   111  		out[i] = slice.Index(i).Interface()
   112  	}
   113  	return out, true
   114  }
   115  
   116  func takeArg(arg interface{}, kind reflect.Kind) (val reflect.Value, ok bool) {
   117  	val = reflect.ValueOf(arg)
   118  	if val.Kind() == kind {
   119  		ok = true
   120  	}
   121  	return
   122  }
   123  
   124  // ConvertAny2Interface converts interface src to interface slice
   125  func ConvertAny2Interface(src interface{}) ([]interface{}, error) {
   126  	data := reflect.ValueOf(src)
   127  	if data.Type().Kind() == reflect.Ptr {
   128  		data = data.Elem()
   129  	}
   130  	if data.Type().Kind() != reflect.Slice {
   131  		return nil, errors.New("Src not slice")
   132  	}
   133  	ret := make([]interface{}, data.Len())
   134  	for i := 0; i < data.Len(); i++ {
   135  		ret[i] = data.Index(i).Interface()
   136  	}
   137  	return ret, nil
   138  }