github.com/MontFerret/ferret@v0.18.0/pkg/stdlib/arrays/minus.go (about) 1 package arrays 2 3 import ( 4 "context" 5 6 "github.com/MontFerret/ferret/pkg/runtime/core" 7 "github.com/MontFerret/ferret/pkg/runtime/values" 8 "github.com/MontFerret/ferret/pkg/runtime/values/types" 9 ) 10 11 // MINUS return the difference of all arrays specified. 12 // The order of the result array is undefined and should not be relied on. Duplicates will be removed. 13 // @param {Any[], repeated} arrays - An arbitrary number of arrays as multiple arguments (at least 2). 14 // @return {Any[]} - An array of values that occur in the first array, but not in any of the subsequent arrays. 15 func Minus(_ context.Context, args ...core.Value) (core.Value, error) { 16 err := core.ValidateArgs(args, 2, core.MaxArgs) 17 18 if err != nil { 19 return values.None, err 20 } 21 22 intersections := make(map[uint64]core.Value) 23 capacity := values.NewInt(0) 24 25 for idx, i := range args { 26 idx := idx 27 err := core.ValidateType(i, types.Array) 28 29 if err != nil { 30 return values.None, err 31 } 32 33 arr := i.(*values.Array) 34 35 arr.ForEach(func(value core.Value, _ int) bool { 36 h := value.Hash() 37 38 // first array, fill out the map 39 if idx == 0 { 40 capacity = arr.Length() 41 intersections[h] = value 42 43 return true 44 } 45 46 _, exists := intersections[h] 47 48 // if it exists in the first array, remove it 49 if exists { 50 delete(intersections, h) 51 } 52 53 return true 54 }) 55 } 56 57 result := values.NewArray(int(capacity)) 58 59 for _, item := range intersections { 60 result.Push(item) 61 } 62 63 return result, nil 64 }