I wrote an iterator for easier access to some paged DB results but what's a good way to reduce the duplication?
foo_iterator.go
type FooIterator struct {
hasNext bool
app *App
batchSize int
}
func NewFooIterator(app *App, batchSize int) *FooIterator {
return &FooIterator{
hasNext: true,
app: app,
batchSize: batchSize,
}
}
func (it *FooIterator) HasNext() bool {
return it.hasNext
}
func (it *FooIterator) Next() []*model.Foo {
offset := 0
batch := it.app.GetAllFoosInPages(offset, it.batchSize)
if len(batch) < it.batchSize {
it.hasNext = false
}
offset += it.batchSize
return batch
}
bar_iterator.go
type BarIterator struct {
hasNext bool
app *App
batchSize int
}
func NewBarIterator(app *App, batchSize int) *BarIterator {
return &BarIterator{
hasNext: true,
app: app,
batchSize: batchSize,
}
}
func (it *BarIterator) HasNext() bool {
return it.hasNext
}
func (it *BarIterator) Next() []*model.Bar {
offset := 0
batch := it.app.GetAllBarsInPages(offset, it.batchSize)
if len(batch) < bi.batchSize {
it.hasNext = false
}
offset += it.batchSize
return batch
}
Usage
fooIterator := NewFooIterator(a, 100)
for fooIterator.HasNext() {
fooBatch := rolesIterator.Next()
// Do stuff
}
They're both so similar there must be some good way to share code but everything I have tried seems awkward.