diff --git a/pkg/expr/func_arr.go b/pkg/expr/func_arr.go index b49f935b7..1a07ab4f9 100644 --- a/pkg/expr/func_arr.go +++ b/pkg/expr/func_arr.go @@ -16,6 +16,7 @@ func ArrayFunctions() []gval.Language { gval.Function("count", count), gval.Function("has", has), gval.Function("hasAll", hasAll), + gval.Function("find", find), } } @@ -101,6 +102,18 @@ func count(arr interface{}, v ...interface{}) (count int, err error) { typeErr := fmt.Errorf("unexpected type: %T, expecting slice", arr) arr = UntypedValue(arr) + if stv, is := arr.([]TypedValue); is { + for _, vv := range v { + if occ, err := find(stv, vv); err != nil { + return 0, err + } else if occ != -1 { + count++ + } + } + + return count, nil + } + var ( occ int c = reflect.ValueOf(arr) @@ -183,7 +196,7 @@ func find(arr interface{}, v interface{}) (p int, err error) { for p = 0; p < reflect.ValueOf(arr).Len(); p++ { c := reflect.ValueOf(arr) - if c.Index(p).Interface() == v { + if UntypedValue(c.Index(p).Interface()) == v { return } } diff --git a/pkg/expr/func_arr_test.go b/pkg/expr/func_arr_test.go index 07906df20..dd8fe0371 100644 --- a/pkg/expr/func_arr_test.go +++ b/pkg/expr/func_arr_test.go @@ -188,6 +188,11 @@ func Test_find(t *testing.T) { arr interface{} val interface{} }{ + { + arr: must(CastToArray([]string{"123", "456"})), + val: "456", + expect: 1, + }, { arr: []string{"1", "2", "3"}, val: "3", @@ -239,6 +244,11 @@ func Test_count(t *testing.T) { arr interface{} val []interface{} }{ + { + arr: must(CastToArray([]string{"123"})), + val: []interface{}{"123", "567"}, + expect: 1, + }, { arr: []string{"1", "2", "3"}, val: []interface{}{"0", "3"}, @@ -465,3 +475,10 @@ func Test_slice(t *testing.T) { }) } } + +func must(v []TypedValue, err error) []TypedValue { + if err != nil { + panic(err) + } + return v +}