Files
dependabot[bot] 0df009eae0 Bump github.com/gookit/config/v2 from 2.2.3 to 2.2.4
Bumps [github.com/gookit/config/v2](https://github.com/gookit/config) from 2.2.3 to 2.2.4.
- [Release notes](https://github.com/gookit/config/releases)
- [Commits](https://github.com/gookit/config/compare/v2.2.3...v2.2.4)

---
updated-dependencies:
- dependency-name: github.com/gookit/config/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-03 10:26:28 +01:00

62 lines
1.5 KiB
Go

package reflects
import (
"fmt"
"reflect"
)
// MakeSliceByElem create a new slice by the element type.
//
// - elType: the type of the element.
// - returns: the new slice.
//
// Usage:
//
// sl := MakeSliceByElem(reflect.TypeOf(1), 10, 20)
// sl.Index(0).SetInt(10)
//
// // Or use reflect.AppendSlice() merge two slice
// // Or use `for` with `reflect.Append()` add elements
func MakeSliceByElem(elTyp reflect.Type, len, cap int) reflect.Value {
return reflect.MakeSlice(reflect.SliceOf(elTyp), len, cap)
}
// FlatSlice flatten multi-level slice to given depth-level slice.
//
// Example:
//
// FlatSlice([]any{ []any{3, 4}, []any{5, 6} }, 1) // Output: []any{3, 4, 5, 6}
//
// always return reflect.Value of []any. note: maybe flatSl.Cap != flatSl.Len
func FlatSlice(sl reflect.Value, depth int) reflect.Value {
items := make([]reflect.Value, 0, sl.Cap())
slCap := addSliceItem(sl, depth, func(item reflect.Value) {
items = append(items, item)
})
flatSl := reflect.MakeSlice(reflect.SliceOf(anyType), 0, slCap)
flatSl = reflect.Append(flatSl, items...)
return flatSl
}
func addSliceItem(sl reflect.Value, depth int, collector func(item reflect.Value)) (c int) {
for i := 0; i < sl.Len(); i++ {
v := Elem(sl.Index(i))
if depth > 0 {
if v.Kind() != reflect.Slice {
panic(fmt.Sprintf("depth: %d, the value of index %d is not slice", depth, i))
}
c += addSliceItem(v, depth-1, collector)
} else {
collector(v)
}
}
if depth == 0 {
c = sl.Cap()
}
return c
}