diff options
Diffstat (limited to 'vendor/gopkg.in/fatih/set.v0/set.go')
-rw-r--r-- | vendor/gopkg.in/fatih/set.v0/set.go | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/vendor/gopkg.in/fatih/set.v0/set.go b/vendor/gopkg.in/fatih/set.v0/set.go new file mode 100644 index 000000000..ac0240ce7 --- /dev/null +++ b/vendor/gopkg.in/fatih/set.v0/set.go @@ -0,0 +1,121 @@ +// Package set provides both threadsafe and non-threadsafe implementations of +// a generic set data structure. In the threadsafe set, safety encompasses all +// operations on one set. Operations on multiple sets are consistent in that +// the elements of each set used was valid at exactly one point in time +// between the start and the end of the operation. +package set + +// Interface is describing a Set. Sets are an unordered, unique list of values. +type Interface interface { + New(items ...interface{}) Interface + Add(items ...interface{}) + Remove(items ...interface{}) + Pop() interface{} + Has(items ...interface{}) bool + Size() int + Clear() + IsEmpty() bool + IsEqual(s Interface) bool + IsSubset(s Interface) bool + IsSuperset(s Interface) bool + Each(func(interface{}) bool) + String() string + List() []interface{} + Copy() Interface + Merge(s Interface) + Separate(s Interface) +} + +// helpful to not write everywhere struct{}{} +var keyExists = struct{}{} + +// Union is the merger of multiple sets. It returns a new set with all the +// elements present in all the sets that are passed. +// +// The dynamic type of the returned set is determined by the first passed set's +// implementation of the New() method. +func Union(set1, set2 Interface, sets ...Interface) Interface { + u := set1.Copy() + set2.Each(func(item interface{}) bool { + u.Add(item) + return true + }) + for _, set := range sets { + set.Each(func(item interface{}) bool { + u.Add(item) + return true + }) + } + + return u +} + +// Difference returns a new set which contains items which are in in the first +// set but not in the others. Unlike the Difference() method you can use this +// function separately with multiple sets. +func Difference(set1, set2 Interface, sets ...Interface) Interface { + s := set1.Copy() + s.Separate(set2) + for _, set := range sets { + s.Separate(set) // seperate is thread safe + } + return s +} + +// Intersection returns a new set which contains items that only exist in all given sets. +func Intersection(set1, set2 Interface, sets ...Interface) Interface { + all := Union(set1, set2, sets...) + result := Union(set1, set2, sets...) + + all.Each(func(item interface{}) bool { + if !set1.Has(item) || !set2.Has(item) { + result.Remove(item) + } + + for _, set := range sets { + if !set.Has(item) { + result.Remove(item) + } + } + return true + }) + return result +} + +// SymmetricDifference returns a new set which s is the difference of items which are in +// one of either, but not in both. +func SymmetricDifference(s Interface, t Interface) Interface { + u := Difference(s, t) + v := Difference(t, s) + return Union(u, v) +} + +// StringSlice is a helper function that returns a slice of strings of s. If +// the set contains mixed types of items only items of type string are returned. +func StringSlice(s Interface) []string { + slice := make([]string, 0) + for _, item := range s.List() { + v, ok := item.(string) + if !ok { + continue + } + + slice = append(slice, v) + } + return slice +} + +// IntSlice is a helper function that returns a slice of ints of s. If +// the set contains mixed types of items only items of type int are returned. +func IntSlice(s Interface) []int { + slice := make([]int, 0) + for _, item := range s.List() { + v, ok := item.(int) + if !ok { + continue + } + + slice = append(slice, v) + } + return slice +} |