mirror of
https://github.com/duke-git/lancet.git
synced 2026-03-01 00:35:28 +08:00
feat: add FlattenDeep func
This commit is contained in:
@@ -190,6 +190,30 @@ func Find(slice, function interface{}) interface{} {
|
|||||||
return sv.Index(index).Interface()
|
return sv.Index(index).Interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FlattenDeep flattens slice recursive
|
||||||
|
func FlattenDeep(slice interface{}) interface{} {
|
||||||
|
sv := sliceValue(slice)
|
||||||
|
st := sliceElemType(sv.Type())
|
||||||
|
tmp := reflect.MakeSlice(reflect.SliceOf(st), 0, 0)
|
||||||
|
res := flattenRecursive(sv, tmp)
|
||||||
|
return res.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenRecursive(value reflect.Value, result reflect.Value) reflect.Value {
|
||||||
|
for i := 0; i < value.Len(); i++ {
|
||||||
|
item := value.Index(i)
|
||||||
|
kind := item.Kind()
|
||||||
|
|
||||||
|
if kind == reflect.Slice {
|
||||||
|
result = flattenRecursive(item, result)
|
||||||
|
} else {
|
||||||
|
result = reflect.Append(result, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// Map creates an slice of values by running each element of `slice` thru `function`.
|
// 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{}.
|
// The function signature should be func(index int, value interface{}) interface{}.
|
||||||
func Map(slice, function interface{}) interface{} {
|
func Map(slice, function interface{}) interface{} {
|
||||||
@@ -521,9 +545,9 @@ func Intersection(slices ...interface{}) interface{} {
|
|||||||
|
|
||||||
// ReverseSlice return slice of element order is reversed to the given slice
|
// ReverseSlice return slice of element order is reversed to the given slice
|
||||||
func ReverseSlice(slice interface{}) {
|
func ReverseSlice(slice interface{}) {
|
||||||
v := sliceValue(slice)
|
sv := sliceValue(slice)
|
||||||
swp := reflect.Swapper(v.Interface())
|
swp := reflect.Swapper(sv.Interface())
|
||||||
for i, j := 0, v.Len()-1; i < j; i, j = i+1, j-1 {
|
for i, j := 0, sv.Len()-1; i < j; i, j = i+1, j-1 {
|
||||||
swp(i, j)
|
swp(i, j)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -532,8 +556,8 @@ func ReverseSlice(slice interface{}) {
|
|||||||
// Slice element should be struct, field type should be int, uint, string, or bool
|
// Slice element should be struct, field type should be int, uint, string, or bool
|
||||||
// default sortType is ascending (asc), if descending order, set sortType to desc
|
// default sortType is ascending (asc), if descending order, set sortType to desc
|
||||||
func SortByField(slice interface{}, field string, sortType ...string) error {
|
func SortByField(slice interface{}, field string, sortType ...string) error {
|
||||||
v := sliceValue(slice)
|
sv := sliceValue(slice)
|
||||||
t := v.Type().Elem()
|
t := sv.Type().Elem()
|
||||||
|
|
||||||
if t.Kind() == reflect.Ptr {
|
if t.Kind() == reflect.Ptr {
|
||||||
t = t.Elem()
|
t = t.Elem()
|
||||||
@@ -566,8 +590,8 @@ func SortByField(slice interface{}, field string, sortType ...string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(slice, func(i, j int) bool {
|
sort.Slice(slice, func(i, j int) bool {
|
||||||
a := v.Index(i)
|
a := sv.Index(i)
|
||||||
b := v.Index(j)
|
b := sv.Index(j)
|
||||||
if t.Kind() == reflect.Ptr {
|
if t.Kind() == reflect.Ptr {
|
||||||
a = a.Elem()
|
a = a.Elem()
|
||||||
b = b.Elem()
|
b = b.Elem()
|
||||||
|
|||||||
@@ -173,6 +173,17 @@ func TestFind(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFlattenDeep(t *testing.T) {
|
||||||
|
input := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
|
||||||
|
expected := []string{"a", "b", "c", "d"}
|
||||||
|
|
||||||
|
res := FlattenDeep(input)
|
||||||
|
if !reflect.DeepEqual(res, expected) {
|
||||||
|
internal.LogFailedTestInfo(t, "FlattenDeep", input, expected, res)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMap(t *testing.T) {
|
func TestMap(t *testing.T) {
|
||||||
s1 := []int{1, 2, 3, 4}
|
s1 := []int{1, 2, 3, 4}
|
||||||
multiplyTwo := func(i, num int) int {
|
multiplyTwo := func(i, num int) int {
|
||||||
|
|||||||
@@ -52,3 +52,14 @@ func checkSliceCallbackFuncSignature(fn reflect.Value, types ...reflect.Type) bo
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sliceElemType get slice element type
|
||||||
|
func sliceElemType(reflectType reflect.Type) reflect.Type {
|
||||||
|
for {
|
||||||
|
if reflectType.Kind() != reflect.Slice {
|
||||||
|
return reflectType
|
||||||
|
}
|
||||||
|
|
||||||
|
reflectType = reflectType.Elem()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user