Iterator: new function Count()

This commit is contained in:
Celestino Amoroso 2024-07-21 16:34:52 +02:00
parent c461fd138e
commit d572f3a129
5 changed files with 48 additions and 32 deletions

View File

@ -13,25 +13,25 @@ type dataCursor struct {
ds map[string]Functor ds map[string]Functor
ctx ExprContext ctx ExprContext
index int index int
count int
current any current any
lastErr error lastErr error
resource any resource any
nextFunc Functor nextFunc Functor
cleanFunc Functor cleanFunc Functor
resetFunc Functor resetFunc Functor
// currentFunc Functor
} }
func NewDataCursor(ctx ExprContext, ds map[string]Functor, resource any) (dc *dataCursor) { func NewDataCursor(ctx ExprContext, ds map[string]Functor, resource any) (dc *dataCursor) {
dc = &dataCursor{ dc = &dataCursor{
ds: ds, ds: ds,
index: -1, index: -1,
count: 0,
current: nil, current: nil,
lastErr: nil, lastErr: nil,
resource: resource, resource: resource,
ctx: ctx.Clone(), ctx: ctx.Clone(),
nextFunc: ds[NextName], nextFunc: ds[NextName],
// currentFunc: ds[CurrentName],
cleanFunc: ds[CleanName], cleanFunc: ds[CleanName],
resetFunc: ds[ResetName], resetFunc: ds[ResetName],
} }
@ -109,6 +109,7 @@ func (dc *dataCursor) Reset() (success bool, err error) {
ctx := cloneContext(dc.ctx) ctx := cloneContext(dc.ctx)
if _, err = dc.resetFunc.Invoke(ctx, ResetName, []any{dc.resource}); err == nil { if _, err = dc.resetFunc.Invoke(ctx, ResetName, []any{dc.resource}); err == nil {
dc.index = -1 dc.index = -1
dc.count = 0
} }
exportObjects(dc.ctx, ctx) exportObjects(dc.ctx, ctx)
dc.Next() dc.Next()
@ -167,7 +168,6 @@ func (dc *dataCursor) mapItem(mapper Functor, item any) (mappedItem any, err err
} }
func (dc *dataCursor) Next() (current any, err error) { // must return io.EOF after the last item func (dc *dataCursor) Next() (current any, err error) { // must return io.EOF after the last item
var accepted bool
if err = dc.lastErr; err != nil { if err = dc.lastErr; err != nil {
return return
} }
@ -183,11 +183,15 @@ func (dc *dataCursor) Next() (current any, err error) { // must return io.EOF af
if item == nil { if item == nil {
dc.lastErr = io.EOF dc.lastErr = io.EOF
} else { } else {
accepted := true
if filter != nil { if filter != nil {
if accepted, dc.lastErr = dc.checkFilter(filter, item); dc.lastErr != nil || !accepted { if accepted, dc.lastErr = dc.checkFilter(filter, item); dc.lastErr != nil || !accepted {
item = nil item = nil
} }
} }
if accepted {
dc.count++
}
if item != nil && mapper != nil { if item != nil && mapper != nil {
item, dc.lastErr = dc.mapItem(mapper, item) item, dc.lastErr = dc.mapItem(mapper, item)
} }
@ -197,6 +201,7 @@ func (dc *dataCursor) Next() (current any, err error) { // must return io.EOF af
} }
dc.current = item dc.current = item
if dc.lastErr != nil { if dc.lastErr != nil {
dc.index--
dc.Clean() dc.Clean()
} }
} else { } else {
@ -206,5 +211,10 @@ func (dc *dataCursor) Next() (current any, err error) { // must return io.EOF af
} }
func (dc *dataCursor) Index() int { func (dc *dataCursor) Index() int {
return dc.index-1 return dc.index - 1
}
func (dc *dataCursor) Count() int {
return dc.count
} }

View File

@ -28,6 +28,7 @@ type Iterator interface {
Next() (item any, err error) // must return io.EOF after the last item Next() (item any, err error) // must return io.EOF after the last item
Current() (item any, err error) Current() (item any, err error)
Index() int Index() int
Count() int
} }
type ExtIterator interface { type ExtIterator interface {

View File

@ -143,7 +143,12 @@ func (it *ListIterator) Index() int {
return it.index return it.index
} }
func (it *ListIterator) Count() int {
return it.count
}
func (it *ListIterator) Reset() (bool, error) { func (it *ListIterator) Reset() (bool, error) {
it.index = it.start - it.step it.index = it.start - it.step
it.count = 0
return true, nil return true, nil
} }

View File

@ -30,16 +30,16 @@ func evalLength(ctx ExprContext, opTerm *term) (v any, err error) {
s, _ := childValue.(string) s, _ := childValue.(string)
v = int64(len(s)) v = int64(len(s))
} else if IsDict(childValue) { } else if IsDict(childValue) {
// m, _ := childValue.(map[any]any)
m, _ := childValue.(*DictType) m, _ := childValue.(*DictType)
v = int64(len(*m)) v = int64(len(*m))
} else if it, ok := childValue.(Iterator); ok { } else if it, ok := childValue.(Iterator); ok {
if extIt, ok := childValue.(ExtIterator); ok && extIt.HasOperation(CountName) { v = int64(it.Count())
count, _ := extIt.CallOperation(CountName, nil) // if extIt, ok := childValue.(ExtIterator); ok && extIt.HasOperation(CountName) {
v, _ = ToGoInt(count, "") // count, _ := extIt.CallOperation(CountName, nil)
} else { // v, _ = ToGoInt(count, "")
v = int64(it.Index() + 1) // } else {
} // v = int64(it.Index() + 1)
// }
} else { } else {
err = opTerm.errIncompatibleType(childValue) err = opTerm.errIncompatibleType(childValue)
} }

View File

@ -11,7 +11,7 @@ func TestIteratorParser(t *testing.T) {
inputs := []inputType{ inputs := []inputType{
/* 1 */ {`include "test-resources/iterator.expr"; it=$(ds,3); ^it`, int64(0), nil}, /* 1 */ {`include "test-resources/iterator.expr"; it=$(ds,3); ^it`, int64(0), nil},
/* 2 */ {`include "test-resources/iterator.expr"; it=$(ds,3); it++; it++`, int64(1), nil}, /* 2 */ {`include "test-resources/iterator.expr"; it=$(ds,3); it++; it++`, int64(1), nil},
/* 3 */ {`include "test-resources/iterator.expr"; it=$(ds,3); it++; it++; #it`, int64(2), nil}, /* 3 */ {`include "test-resources/iterator.expr"; it=$(ds,3); it++; it++; #it`, int64(3), nil},
/* 4 */ {`include "test-resources/iterator.expr"; it=$(ds,3); it++; it++; it.reset; ^it`, int64(0), nil}, /* 4 */ {`include "test-resources/iterator.expr"; it=$(ds,3); it++; it++; it.reset; ^it`, int64(0), nil},
/* 5 */ {`builtin "math.arith"; include "test-resources/iterator.expr"; it=$(ds,3); add(it)`, int64(6), nil}, /* 5 */ {`builtin "math.arith"; include "test-resources/iterator.expr"; it=$(ds,3); add(it)`, int64(6), nil},
/* 6 */ {`builtin "math.arith"; include "test-resources/iterator.expr"; it=$(ds,3); mul(it)`, int64(0), nil}, /* 6 */ {`builtin "math.arith"; include "test-resources/iterator.expr"; it=$(ds,3); mul(it)`, int64(0), nil},
@ -27,6 +27,6 @@ func TestIteratorParser(t *testing.T) {
/* 16 */ {`include "test-resources/filter.expr"; it=$(ds,10); it++`, int64(2), nil}, /* 16 */ {`include "test-resources/filter.expr"; it=$(ds,10); it++`, int64(2), nil},
} }
//runTestSuiteSpec(t, section, inputs, 4) //runTestSuiteSpec(t, section, inputs, 3)
runTestSuite(t, section, inputs) runTestSuite(t, section, inputs)
} }