Make count() predicate optional

This commit is contained in:
Anton Medvedev
2024-04-13 23:38:35 +02:00
parent d8d1d9ebf4
commit c5dfe3a811
5 changed files with 42 additions and 5 deletions
+4
View File
@@ -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()
+5 -1
View File
@@ -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)
})
+28 -3
View File
@@ -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}
@@ -673,7 +683,7 @@ 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.
@@ -681,6 +691,21 @@ Returns the sum of all numbers in the array.
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.
+4
View File
@@ -905,6 +905,10 @@ func TestExpr(t *testing.T) {
`count(1..30, {# % 3 == 0})`,
10,
},
{
`count([true, true, false])`,
2,
},
{
`"a" < "b"`,
true,
+1 -1
View File
@@ -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}},