github.com/MontFerret/ferret@v0.18.0/pkg/runtime/collections/unique.go (about) 1 package collections 2 3 import ( 4 "context" 5 6 "github.com/MontFerret/ferret/pkg/runtime/core" 7 ) 8 9 type ( 10 UniqueIterator struct { 11 values Iterator 12 hashes map[uint64]bool 13 hashKey string 14 } 15 ) 16 17 func NewUniqueIterator(values Iterator, hashKey string) (*UniqueIterator, error) { 18 if values == nil { 19 return nil, core.Error(core.ErrMissedArgument, "source") 20 } 21 22 return &UniqueIterator{ 23 values: values, 24 hashes: make(map[uint64]bool), 25 hashKey: hashKey, 26 }, nil 27 } 28 29 func (iterator *UniqueIterator) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) { 30 for { 31 nextScope, err := iterator.values.Next(ctx, scope.Fork()) 32 33 if err != nil { 34 return nil, err 35 } 36 37 v, err := nextScope.GetVariable(iterator.hashKey) 38 39 if err != nil { 40 return nil, err 41 } 42 43 h := v.Hash() 44 45 _, exists := iterator.hashes[h] 46 47 if exists { 48 continue 49 } 50 51 iterator.hashes[h] = true 52 53 return nextScope, nil 54 } 55 }