Expr.adoc: automatic variables in the interator infix operators"

This commit is contained in:
2026-06-02 11:35:36 +02:00
parent 02ea20cdb5
commit ee7f488ebb
4 changed files with 20 additions and 8 deletions
+9 -1
View File
@@ -1875,13 +1875,21 @@ TIP: Iterators built on custom data-sources can provide additional named operato
There are also some infixed operators that can be used with iterators. They are defined as follows. There are also some infixed operators that can be used with iterators. They are defined as follows.
* <<_cat,cat operator>> * <<_cat,cat operator>>
* <<_diget,digest operator>> * <<_digest,digest operator>>
* <<_filter,filter operator>> * <<_filter,filter operator>>
* <<_groupby,groupby operator>> * <<_groupby,groupby operator>>
* <<_map,map operator>> * <<_map,map operator>>
//* <<_reduce,reduce operator>>: applies a binary expression cumulatively to the elements of the iterator, from left to right, to reduce the iterator to a single value. //* <<_reduce,reduce operator>>: applies a binary expression cumulatively to the elements of the iterator, from left to right, to reduce the iterator to a single value.
//* <<_zip,zip operator>>: takes two or more iterators and returns a list of tuples, where the i-th tuple contains the i-th element from each of the input iterators. //* <<_zip,zip operator>>: takes two or more iterators and returns a list of tuples, where the i-th tuple contains the i-th element from each of the input iterators.
==== Automatic variables in operators
At each iteration, the following automatic variables are available for use in the expression of the [blue]`digest`, [blue]`filter`, [blue]`groupby`, and [blue]`map` operators.
* `$_`: the current element of the iterator.
* `$__`: the index of the current element in the iterator, starting from 0.
* `$_#`: the number of elements already visited in the iterator, starting from 0.
--- ---
==== [blue]`cat` operator ==== [blue]`cat` operator
+2 -2
View File
@@ -45,7 +45,7 @@ func evalDigest(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
for item, err = it.Next(); err == nil; item, err = it.Next() { for item, err = it.Next(); err == nil; item, err = it.Next() {
ctx.SetVar("_", item) ctx.SetVar("_", item)
ctx.SetVar("__", it.Index()) ctx.SetVar("__", it.Index())
ctx.SetVar("_#", it.Count()) ctx.SetVar("#", it.Count())
if rightValue, err = opTerm.Children[1].Compute(ctx); err == nil { if rightValue, err = opTerm.Children[1].Compute(ctx); err == nil {
if rightValue == nil { if rightValue == nil {
break break
@@ -53,7 +53,7 @@ func evalDigest(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
lastValue = rightValue lastValue = rightValue
} }
} }
ctx.DeleteVar("_#") ctx.DeleteVar("#")
ctx.DeleteVar("__") ctx.DeleteVar("__")
ctx.DeleteVar("_") ctx.DeleteVar("_")
if err != nil { if err != nil {
+2 -2
View File
@@ -110,9 +110,9 @@ func (it *filterIterator) Next() (item any, err error) {
for attempt, err = it.itSrc.Next(); err == nil; attempt, err = it.itSrc.Next() { for attempt, err = it.itSrc.Next(); err == nil; attempt, err = it.itSrc.Next() {
ctx.SetVar("_", attempt) ctx.SetVar("_", attempt)
ctx.SetVar("__", it.Index()) ctx.SetVar("__", it.Index())
ctx.SetVar("_#", it.Count()) ctx.SetVar("#", it.Count())
result, err = it.expr.Compute(ctx) result, err = it.expr.Compute(ctx)
ctx.DeleteVar("_#") ctx.DeleteVar("#")
ctx.DeleteVar("__") ctx.DeleteVar("__")
ctx.DeleteVar("_") ctx.DeleteVar("_")
+6 -2
View File
@@ -62,7 +62,7 @@ func evalGroupBy(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
for item, err = it.Next(); err == nil; item, err = it.Next() { for item, err = it.Next(); err == nil; item, err = it.Next() {
ctx.SetVar("_", item) ctx.SetVar("_", item)
ctx.SetVar("__", it.Index()) ctx.SetVar("__", it.Index())
ctx.SetVar("_#", it.Count()) ctx.SetVar("#", it.Count())
var sItemKey string var sItemKey string
@@ -71,7 +71,11 @@ func evalGroupBy(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
sItemKey = strconv.Itoa(int(it.Index())) sItemKey = strconv.Itoa(int(it.Index()))
} else if d.HasKey(sKey) { } else if d.HasKey(sKey) {
if keyValue, exists := d.GetItem(sKey); exists { if keyValue, exists := d.GetItem(sKey); exists {
if s, ok := keyValue.(string); ok {
sItemKey = s
} else {
sItemKey = fmt.Sprintf("%v", keyValue) sItemKey = fmt.Sprintf("%v", keyValue)
}
} else { } else {
sItemKey = "_" sItemKey = "_"
} }
@@ -92,7 +96,7 @@ func evalGroupBy(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
ls.AppendItem(item) ls.AppendItem(item)
values.SetItem(sItemKey, ls) values.SetItem(sItemKey, ls)
ctx.DeleteVar("_#") ctx.DeleteVar("#")
ctx.DeleteVar("__") ctx.DeleteVar("__")
ctx.DeleteVar("_") ctx.DeleteVar("_")
} }