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

@ -10,30 +10,30 @@ import (
)
type dataCursor struct {
ds map[string]Functor
ctx ExprContext
index int
current any
lastErr error
resource any
nextFunc Functor
cleanFunc Functor
resetFunc Functor
// currentFunc Functor
ds map[string]Functor
ctx ExprContext
index int
count int
current any
lastErr error
resource any
nextFunc Functor
cleanFunc Functor
resetFunc Functor
}
func NewDataCursor(ctx ExprContext, ds map[string]Functor, resource any) (dc *dataCursor) {
dc = &dataCursor{
ds: ds,
index: -1,
current: nil,
lastErr: nil,
resource: resource,
ctx: ctx.Clone(),
nextFunc: ds[NextName],
// currentFunc: ds[CurrentName],
cleanFunc: ds[CleanName],
resetFunc: ds[ResetName],
ds: ds,
index: -1,
count: 0,
current: nil,
lastErr: nil,
resource: resource,
ctx: ctx.Clone(),
nextFunc: ds[NextName],
cleanFunc: ds[CleanName],
resetFunc: ds[ResetName],
}
dc.Next()
return
@ -109,6 +109,7 @@ func (dc *dataCursor) Reset() (success bool, err error) {
ctx := cloneContext(dc.ctx)
if _, err = dc.resetFunc.Invoke(ctx, ResetName, []any{dc.resource}); err == nil {
dc.index = -1
dc.count = 0
}
exportObjects(dc.ctx, ctx)
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
var accepted bool
if err = dc.lastErr; err != nil {
return
}
@ -179,15 +179,19 @@ func (dc *dataCursor) Next() (current any, err error) { // must return io.EOF af
for item == nil && dc.lastErr == nil {
ctx := cloneContext(dc.ctx)
dc.index++
if item, dc.lastErr = dc.nextFunc.Invoke(ctx, NextName, []any{dc.resource, dc.index}); dc.lastErr == nil {
if item, dc.lastErr = dc.nextFunc.Invoke(ctx, NextName, []any{dc.resource, dc.index}); dc.lastErr == nil {
if item == nil {
dc.lastErr = io.EOF
} else {
accepted := true
if filter != nil {
if accepted, dc.lastErr = dc.checkFilter(filter, item); dc.lastErr != nil || !accepted {
item = nil
}
}
if accepted {
dc.count++
}
if item != nil && mapper != nil {
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
if dc.lastErr != nil {
dc.index--
dc.Clean()
}
} else {
@ -206,5 +211,10 @@ func (dc *dataCursor) Next() (current any, err error) { // must return io.EOF af
}
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
Current() (item any, err error)
Index() int
Count() int
}
type ExtIterator interface {

View File

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

View File

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

View File

@ -11,7 +11,7 @@ func TestIteratorParser(t *testing.T) {
inputs := []inputType{
/* 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},
/* 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},
/* 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},
@ -27,6 +27,6 @@ func TestIteratorParser(t *testing.T) {
/* 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)
}