123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- package vals
- // Iterator wraps the Iterate method.
- type Iterator interface {
- // Iterate calls the passed function with each value within the receiver.
- // The iteration is aborted if the function returns false.
- Iterate(func(v any) bool)
- }
- type cannotIterate struct{ kind string }
- func (err cannotIterate) Error() string { return "cannot iterate " + err.kind }
- // CanIterate returns whether the value can be iterated. If CanIterate(v) is
- // true, calling Iterate(v, f) will not result in an error.
- func CanIterate(v any) bool {
- switch v.(type) {
- case Iterator, string, List:
- return true
- }
- return false
- }
- // Iterate iterates the supplied value, and calls the supplied function in each
- // of its elements. The function can return false to break the iteration. It is
- // implemented for the builtin type string, the List type, and types satisfying
- // the Iterator interface. For these types, it always returns a nil error. For
- // other types, it doesn't do anything and returns an error.
- func Iterate(v any, f func(any) bool) error {
- switch v := v.(type) {
- case string:
- for _, r := range v {
- b := f(string(r))
- if !b {
- break
- }
- }
- case List:
- for it := v.Iterator(); it.HasElem(); it.Next() {
- if !f(it.Elem()) {
- break
- }
- }
- case Iterator:
- v.Iterate(f)
- default:
- return cannotIterate{Kind(v)}
- }
- return nil
- }
- // Collect collects all elements of an iterable value into a slice.
- func Collect(it any) ([]any, error) {
- var vs []any
- if len := Len(it); len >= 0 {
- vs = make([]any, 0, len)
- }
- err := Iterate(it, func(v any) bool {
- vs = append(vs, v)
- return true
- })
- return vs, err
- }
|