spans?
parent
f4afff43cd
commit
ff53acaa2e
@ -0,0 +1,52 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func Ate[T any](a Able[T]) (T, Ator[T]) {
|
||||||
|
var v T
|
||||||
|
return v, a.Iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Min[T constraints.Ordered](it Ator[T]) T {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func Max[T constraints.Ordered](it Ator[T]) T {
|
||||||
|
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
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package iter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"constraints"
|
||||||
|
)
|
||||||
|
|
||||||
|
type span[T constraints.Integer] struct {
|
||||||
|
next T
|
||||||
|
final T
|
||||||
|
step T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *span[T]) Next(n *T) bool {
|
||||||
|
if s.next >= s.final {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
*n = s.next
|
||||||
|
s.next += s.step
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Span creates a span of integers between start and end
|
||||||
|
func Span[T constraints.Integer](start, end T) Ator[T] {
|
||||||
|
return &span[T]{next: start, final: end, step: 1}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step is the same as span, but allows for step sizes greater than 1
|
||||||
|
func Step[T constraints.Integer](start, end, step T) Ator[T] {
|
||||||
|
return &span[T]{next: start, final: end, step: step}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package iter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSpan(t *testing.T) {
|
||||||
|
var n int
|
||||||
|
s := Span(1, 10)
|
||||||
|
|
||||||
|
s.Next(&n)
|
||||||
|
if n != 1 {
|
||||||
|
t.Errorf("expected n to be 1 but is %d instead", n)
|
||||||
|
}
|
||||||
|
for s.Next(&n) {
|
||||||
|
}
|
||||||
|
if n != 9 {
|
||||||
|
t.Errorf("expected n to be 9 but is %d instead", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
beer := Max(Span(1, 100))
|
||||||
|
if beer != 99 {
|
||||||
|
t.Errorf("expected 99 beers but saw %d instead", beer)
|
||||||
|
}
|
||||||
|
|
||||||
|
old := Min(Span(30, 40))
|
||||||
|
if old != 30 {
|
||||||
|
t.Errorf("expected 30 to be old but saw %d instead", old)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStep(t *testing.T) {
|
||||||
|
s := Step(1, 10, 3)
|
||||||
|
for n := 0; s.Next(&n); {
|
||||||
|
t.Log(n)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue