mirror of
https://github.com/hanzoai/expr.git
synced 2026-09-24 16:58:58 +00:00
Add len(filter()) optimization
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
package optimizer
|
||||
|
||||
import (
|
||||
. "github.com/antonmedv/expr/ast"
|
||||
)
|
||||
|
||||
type filterLen struct{}
|
||||
|
||||
func (*filterLen) Visit(node *Node) {
|
||||
if ln, ok := (*node).(*BuiltinNode); ok &&
|
||||
ln.Name == "len" &&
|
||||
len(ln.Arguments) == 1 {
|
||||
if filter, ok := ln.Arguments[0].(*BuiltinNode); ok &&
|
||||
filter.Name == "filter" &&
|
||||
len(filter.Arguments) == 2 {
|
||||
Patch(node, &BuiltinNode{
|
||||
Name: "count",
|
||||
Arguments: filter.Arguments,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,5 +33,6 @@ func Optimize(node *Node, config *conf.Config) error {
|
||||
}
|
||||
Walk(node, &inRange{})
|
||||
Walk(node, &constRange{})
|
||||
Walk(node, &filterLen{})
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -138,3 +138,30 @@ func TestOptimize_const_expr(t *testing.T) {
|
||||
|
||||
assert.Equal(t, ast.Dump(expected), ast.Dump(tree.Node))
|
||||
}
|
||||
|
||||
func TestOptimize_filter_len(t *testing.T) {
|
||||
tree, err := parser.Parse(`len(filter(users, .Name == "Bob"))`)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = optimizer.Optimize(&tree.Node, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := &ast.BuiltinNode{
|
||||
Name: "count",
|
||||
Arguments: []ast.Node{
|
||||
&ast.IdentifierNode{Value: "users"},
|
||||
&ast.ClosureNode{
|
||||
Node: &ast.BinaryNode{
|
||||
Operator: "==",
|
||||
Left: &ast.MemberNode{
|
||||
Node: &ast.PointerNode{},
|
||||
Property: &ast.StringNode{Value: "Name"},
|
||||
},
|
||||
Right: &ast.StringNode{Value: "Bob"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.Equal(t, ast.Dump(expected), ast.Dump(tree.Node))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user