aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/cli/internal/util/set.go
diff options
context:
space:
mode:
author简律纯 <hsiangnianian@outlook.com>2023-04-28 01:36:44 +0800
committer简律纯 <hsiangnianian@outlook.com>2023-04-28 01:36:44 +0800
commitdd84b9d64fb98746a230cd24233ff50a562c39c9 (patch)
treeb583261ef00b3afe72ec4d6dacb31e57779a6faf /cli/internal/util/set.go
parent0b46fcd72ac34382387b2bcf9095233efbcc52f4 (diff)
downloadHydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.tar.gz
HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.zip
Diffstat (limited to 'cli/internal/util/set.go')
-rw-r--r--cli/internal/util/set.go147
1 files changed, 147 insertions, 0 deletions
diff --git a/cli/internal/util/set.go b/cli/internal/util/set.go
new file mode 100644
index 0000000..b6c5f86
--- /dev/null
+++ b/cli/internal/util/set.go
@@ -0,0 +1,147 @@
+package util
+
+// Set is a set data structure.
+type Set map[interface{}]interface{}
+
+// SetFromStrings creates a Set containing the strings from the given slice
+func SetFromStrings(sl []string) Set {
+ set := make(Set, len(sl))
+ for _, item := range sl {
+ set.Add(item)
+ }
+ return set
+}
+
+// Hashable is the interface used by set to get the hash code of a value.
+// If this isn't given, then the value of the item being added to the set
+// itself is used as the comparison value.
+type Hashable interface {
+ Hashcode() interface{}
+}
+
+// hashcode returns the hashcode used for set elements.
+func hashcode(v interface{}) interface{} {
+ if h, ok := v.(Hashable); ok {
+ return h.Hashcode()
+ }
+
+ return v
+}
+
+// Add adds an item to the set
+func (s Set) Add(v interface{}) {
+ s[hashcode(v)] = v
+}
+
+// Delete removes an item from the set.
+func (s Set) Delete(v interface{}) {
+ delete(s, hashcode(v))
+}
+
+// Includes returns true/false of whether a value is in the set.
+func (s Set) Includes(v interface{}) bool {
+ _, ok := s[hashcode(v)]
+ return ok
+}
+
+// Intersection computes the set intersection with other.
+func (s Set) Intersection(other Set) Set {
+ result := make(Set)
+ if s == nil || other == nil {
+ return result
+ }
+ // Iteration over a smaller set has better performance.
+ if other.Len() < s.Len() {
+ s, other = other, s
+ }
+ for _, v := range s {
+ if other.Includes(v) {
+ result.Add(v)
+ }
+ }
+ return result
+}
+
+// Difference returns a set with the elements that s has but
+// other doesn't.
+func (s Set) Difference(other Set) Set {
+ result := make(Set)
+ for k, v := range s {
+ var ok bool
+ if other != nil {
+ _, ok = other[k]
+ }
+ if !ok {
+ result.Add(v)
+ }
+ }
+
+ return result
+}
+
+// Some tests whether at least one element in the array passes the test implemented by the provided function.
+// It returns a Boolean value.
+func (s Set) Some(cb func(interface{}) bool) bool {
+ for _, v := range s {
+ if cb(v) {
+ return true
+ }
+ }
+ return false
+}
+
+// Filter returns a set that contains the elements from the receiver
+// where the given callback returns true.
+func (s Set) Filter(cb func(interface{}) bool) Set {
+ result := make(Set)
+
+ for _, v := range s {
+ if cb(v) {
+ result.Add(v)
+ }
+ }
+
+ return result
+}
+
+// Len is the number of items in the set.
+func (s Set) Len() int {
+ return len(s)
+}
+
+// List returns the list of set elements.
+func (s Set) List() []interface{} {
+ if s == nil {
+ return nil
+ }
+
+ r := make([]interface{}, 0, len(s))
+ for _, v := range s {
+ r = append(r, v)
+ }
+
+ return r
+}
+
+// UnsafeListOfStrings dangerously casts list to a string
+func (s Set) UnsafeListOfStrings() []string {
+ if s == nil {
+ return nil
+ }
+
+ r := make([]string, 0, len(s))
+ for _, v := range s {
+ r = append(r, v.(string))
+ }
+
+ return r
+}
+
+// Copy returns a shallow copy of the set.
+func (s Set) Copy() Set {
+ c := make(Set)
+ for k, v := range s {
+ c[k] = v
+ }
+ return c
+}