You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
2.8 KiB
Go

package iter
import "constraints"
// Able is anything that is iter.Able
type Able[T any] interface {
Iter() Ator[T]
}
// Ator is an iter.Ator
type Ator[T any] interface {
// Next assigns the value pointed at by *T to the next value in the
// iteration. Next should return true if a value was set. An Ator that
// returns false should continue to return false; once iteration is
// complete it should be complete forever.
Next(*T) bool
// An iterator must also be iterable. That is, a valid iterator must be
// able to create a new iterator beginning at the same position of that
// iterator, such that calling Iter() on an Iterator returns a new
// Iterator, and that both can be iterated without affecting one another.
Able[T]
}
// Start starts the iteration for an Iterable. This is a convenience function
// to facilitate iterating in a for loop. E.g., given an Iterable value l, such
// as a list, the following would iterate over the entire iterable:
//
// for v, it := iter.Start(l); it.Next(&v); {
// // utilize v here
// }
//
// Without such a construct, a developer would have to do something similar instead:
//
// for v, it := 0, l.Iter(); it.Next(&v); {
//
// }
//
// Doing that would require that the developer type out the zero-value for that
// type, when that value could just as easily be inferred.
func Start[T any](a Able[T]) (T, Ator[T]) {
var v T
return v, a.Iter()
}
// Min gets the minimum value in the iterable collection src. Src must be a
// collection of ordered values. Min requires that src's definition of
// iteration is finite.
func Min[T constraints.Ordered](src Able[T]) T {
it := src.Iter()
var v T
if !it.Next(&v) {
var zero T
return zero
}
min := v
for it.Next(&v) {
if v < min {
min = v
}
}
return min
}
// Max gets the maximum value in the iterable collection src. Src must be a
// collection of ordered values. Max requires that src's definition of
// iteration is finite.
func Max[T constraints.Ordered](src Able[T]) T {
it := src.Iter()
var v T
if !it.Next(&v) {
var zero T
return zero
}
max := v
for it.Next(&v) {
if v > max {
max = v
}
}
return max
}
// Discarded Iterator types:
//
// This was my first attempt. I like to have a method that returns a bool so
// you can use it succinctly in a for loop, but I didn't love having to call
// both done and next
//
// type Ator[T any] interface {
// Done() bool
// Next() T
// }
//
// I was never optimistic about this. In practice, using this in a for loop is
// just annoying so I stopped doing it. But also there's another thing I find
// annoying: it's a copy every time. You're not really iterating over the
// values, you're iterating over copies of the values, it seemed like a lot of
// unecessary copying.
//
// type Ator[T any] interface {
// Next() (T, bool)
// }