Skip to content

Commit

Permalink
Make count() predicate optional
Browse files Browse the repository at this point in the history
  • Loading branch information
antonmedv committed Apr 13, 2024
1 parent d236dcd commit 725b702
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 5 deletions.
4 changes: 4 additions & 0 deletions checker/checker.go
Expand Up @@ -653,6 +653,10 @@ func (v *checker) BuiltinNode(node *ast.BuiltinNode) (reflect.Type, info) {
return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection)
}

if len(node.Arguments) == 1 {
return integerType, info{}
}

v.begin(collection)
closure, _ := v.visit(node.Arguments[1])
v.end()
Expand Down
6 changes: 5 additions & 1 deletion compiler/compiler.go
Expand Up @@ -800,7 +800,11 @@ func (c *compiler) BuiltinNode(node *ast.BuiltinNode) {
c.compile(node.Arguments[0])
c.emit(OpBegin)
c.emitLoop(func() {
c.compile(node.Arguments[1])
if len(node.Arguments) == 2 {
c.compile(node.Arguments[1])
} else {
c.emit(OpPointer)
}
c.emitCond(func() {
c.emit(OpIncrementCount)
})
Expand Down
31 changes: 28 additions & 3 deletions docs/language-definition.md
Expand Up @@ -628,14 +628,24 @@ Groups the elements of an array by the result of the [predicate](#predicate).
groupBy(users, .Age)
```

### count(array, predicate) {#count}
### count(array[, predicate]) {#count}

Returns the number of elements what satisfies the [predicate](#predicate).

```expr
count(users, .Age > 18)
```

Equivalent to:

```expr
len(filter(array, predicate))
len(filter(users, .Age > 18))
```

If the predicate is not given, returns the number of `true` elements in the array.

```expr
count([true, false, true]) == 2
```

### concat(array1, array2[, ...]) {#concat}
Expand Down Expand Up @@ -673,14 +683,29 @@ reduce(1..9, #acc + #)
reduce(1..9, #acc + #, 0)
```

### sum(array) {#sum}
### sum(array[, predicate]) {#sum}

Returns the sum of all numbers in the array.

```expr
sum([1, 2, 3]) == 6
```

If the optional `predicate` argument is given, it is a predicate that is applied on each element
of the array before summing.

```expr
sum(accounts, .Balance)
```

Equivalent to:

```expr
reduce(accounts, #acc + .Balance, 0)
// or
sum(map(accounts, .Balance))
```

### mean(array) {#mean}

Returns the average of all numbers in the array.
Expand Down
4 changes: 4 additions & 0 deletions expr_test.go
Expand Up @@ -905,6 +905,10 @@ func TestExpr(t *testing.T) {
`count(1..30, {# % 3 == 0})`,
10,
},
{
`count([true, true, false])`,
2,
},
{
`"a" < "b"`,
true,
Expand Down
2 changes: 1 addition & 1 deletion parser/parser.go
Expand Up @@ -33,7 +33,7 @@ var predicates = map[string]struct {
"one": {[]arg{expr, closure}},
"filter": {[]arg{expr, closure}},
"map": {[]arg{expr, closure}},
"count": {[]arg{expr, closure}},
"count": {[]arg{expr, closure | optional}},
"sum": {[]arg{expr, closure | optional}},
"find": {[]arg{expr, closure}},
"findIndex": {[]arg{expr, closure}},
Expand Down

0 comments on commit 725b702

Please sign in to comment.