Skip to content

Instantly share code, notes, and snippets.

@samlecuyer
Created July 10, 2012 02:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samlecuyer/3080669 to your computer and use it in GitHub Desktop.
Save samlecuyer/3080669 to your computer and use it in GitHub Desktop.
lazy iterables in go
package main
import (
"fmt"
"math/rand"
)
type DataSource interface {
Next() Element
}
type Element interface {
DataSource
Val() uint32
}
type LazyList struct {
ds DataSource
val uint32
next Element
}
func (l *LazyList) Val() uint32 {
return l.val
}
func (l *LazyList) Next() Element {
if l.next == nil {
l.next = l.ds.Next()
}
return l.next
}
func NewLazyList(ds DataSource) DataSource {
return &LazyList{ds, 0, nil}
}
type Predicate func(Element) bool
type LazyFilter struct {
ds DataSource
val uint32
next Element
pred Predicate
}
func (l *LazyFilter) Val() uint32 {
return l.val
}
func (l *LazyFilter) Next() Element {
if l.next == nil {
r := l.ds.Next()
for r != nil {
if l.pred(r) {
l.next = &LazyFilter{r, r.Val(), nil, l.pred}
break
}
r = r.Next()
}
}
return l.next
}
func NewLazyFilter(ds DataSource, pred Predicate) Element {
return &LazyFilter{ds, 0, nil, pred}
}
func main() {
incr := Incrementor(0)
even := NewLazyFilter(incr, func(e Element) bool {
return (e.Val() % 3) == 0
})
deca := NewLazyFilter(even, func(e Element) bool {
return (e.Val() % 10) == 0
})
rang := NewLazyFilter(deca, func(e Element) bool {
return e.Val() < 200000000 && e.Val() > 2200000
})
feed := NewLazyList(rang)
cnt := 0
for elem := feed.Next(); cnt <= 40; elem = elem.Next() {
fmt.Println(elem.Val())
cnt++
}
}
type Increment uint32
func (i Increment) Val() uint32 { return uint32(i) }
func (i Increment) Next() Element { return Increment(rand.Uint32()) }
func Incrementor(val uint32) DataSource { return Increment(val) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment