github.com/expr-lang/expr@v1.16.9/optimizer/filter_last.go (about)

     1  package optimizer
     2  
     3  import (
     4  	. "github.com/expr-lang/expr/ast"
     5  )
     6  
     7  type filterLast struct{}
     8  
     9  func (*filterLast) Visit(node *Node) {
    10  	if member, ok := (*node).(*MemberNode); ok && member.Property != nil && !member.Optional {
    11  		if prop, ok := member.Property.(*IntegerNode); ok && prop.Value == -1 {
    12  			if filter, ok := member.Node.(*BuiltinNode); ok &&
    13  				filter.Name == "filter" &&
    14  				len(filter.Arguments) == 2 {
    15  				Patch(node, &BuiltinNode{
    16  					Name:      "findLast",
    17  					Arguments: filter.Arguments,
    18  					Throws:    true, // to match the behavior of filter()[-1]
    19  					Map:       filter.Map,
    20  				})
    21  			}
    22  		}
    23  	}
    24  	if first, ok := (*node).(*BuiltinNode); ok &&
    25  		first.Name == "last" &&
    26  		len(first.Arguments) == 1 {
    27  		if filter, ok := first.Arguments[0].(*BuiltinNode); ok &&
    28  			filter.Name == "filter" &&
    29  			len(filter.Arguments) == 2 {
    30  			Patch(node, &BuiltinNode{
    31  				Name:      "findLast",
    32  				Arguments: filter.Arguments,
    33  				Throws:    false, // as last() will return nil if not found
    34  				Map:       filter.Map,
    35  			})
    36  		}
    37  	}
    38  }