github.com/seeker-insurance/kit@v0.0.13/set/string.go (about)

     1  package set
     2  
     3  import "sort"
     4  
     5  //String is a set of strings. Remember to initialize with make or String{}
     6  type String map[string]signal
     7  
     8  //Contains returns true if the given key is in the set.
     9  func (s String) Contains(key string) bool {
    10  	_, ok := s[key]
    11  	return ok
    12  }
    13  
    14  //Copy copies the set of strings.
    15  func (s String) Copy() String {
    16  	copy := make(String)
    17  	for k := range s {
    18  		copy[k] = yes
    19  	}
    20  	return copy
    21  }
    22  
    23  //Intersection returns a new set containing the intersection of the strings;
    24  func (s String) Intersection(strings ...String) (intersection String) {
    25  	intersection = s.Copy()
    26  	for key := range s {
    27  		for _, set := range append(strings, s) {
    28  			if !set.Contains(key) {
    29  				delete(intersection, key)
    30  			}
    31  		}
    32  	}
    33  	return intersection
    34  }
    35  
    36  //XOR returns the keys in one set but not the other.
    37  func (s String) XOR(other String) String {
    38  	union := s.Union(other)
    39  	xor := make(String)
    40  	for k := range union {
    41  		if (s.Contains(k) && !other.Contains(k)) || (other.Contains(k) && !s.Contains(k)) {
    42  			xor[k] = yes
    43  		}
    44  	}
    45  	return xor
    46  }
    47  
    48  //Equal shows whether two Strings are equal; i.e, they contain the same items.
    49  func (s String) Equal(other String) bool {
    50  	if len(s) != len(other) {
    51  		return false
    52  	}
    53  	for key := range s {
    54  		if !other.Contains(key) {
    55  			return false
    56  		}
    57  	}
    58  	return true
    59  }
    60  
    61  //Union returns a new set containing the union of the string sets.
    62  func (s String) Union(strings ...String) (union String) {
    63  	union = s.Copy()
    64  	for _, set := range strings {
    65  		for key := range set {
    66  			union[key] = yes
    67  		}
    68  	}
    69  	return union
    70  }
    71  
    72  //IUnion modifies the StringSet in place rather than returning a copy.
    73  func (s String) IUnion(strings ...String) {
    74  	for _, set := range strings {
    75  		for key := range set {
    76  			s[key] = yes
    77  		}
    78  	}
    79  }
    80  
    81  //Difference returns the items in the reciever but not any other arguments
    82  func (s String) Difference(strings ...String) (difference String) {
    83  	difference = s.Copy()
    84  	for _, set := range strings {
    85  		for key := range set {
    86  			delete(difference, key)
    87  		}
    88  	}
    89  	return difference
    90  }
    91  
    92  //FromStrings creates a set from strings
    93  func FromStrings(strings ...string) String {
    94  	s := make(String)
    95  	for _, key := range strings {
    96  		s[key] = yes
    97  	}
    98  	return s
    99  }
   100  
   101  //Add a key or key(s) to the set, in-place. Don't call on a nil set.
   102  func (s String) Add(keys ...string) {
   103  	for _, key := range keys {
   104  		s[key] = yes
   105  	}
   106  }
   107  
   108  //ToSlice returns a slice containing the keys of a set. No order is guaranteed.
   109  func (s String) ToSlice() []string {
   110  	slice := make([]string, len(s))
   111  	var i = 0
   112  	for k := range s {
   113  		slice[i] = k
   114  		i++
   115  	}
   116  	return slice
   117  }
   118  
   119  //Sorted returns a slice containing the keys of the set in lexigraphic order.
   120  func (s String) Sorted() []string {
   121  	slice := s.ToSlice()
   122  	sort.Strings(slice)
   123  	return slice
   124  }
   125  
   126  //Map a function f(x) across the set, returning a new set containing f(x) for all x in the set.
   127  func (s String) Map(f func(string) string) String {
   128  	mapped := make(String)
   129  	for k := range s {
   130  		mapped[f(k)] = yes
   131  	}
   132  	return mapped
   133  
   134  }
   135  
   136  //Reduce applies a reducing function across the set. It will return (0, false) for a set with zero entries.
   137  func (s String) Reduce(f func(string, string) string) (string, bool) {
   138  	if len(s) == 0 {
   139  		return "", false
   140  	}
   141  	first := true
   142  	var reduced string
   143  	for k := range s {
   144  		if first {
   145  			reduced = k
   146  			first = false
   147  
   148  		} else {
   149  			reduced = f(reduced, k)
   150  		}
   151  	}
   152  	return reduced, true
   153  }
   154  
   155  //Filter applies a filtering function across the set, returning a set containing x where f(x) is true.
   156  func (s String) Filter(f func(string) bool) String {
   157  	filtered := make(String)
   158  	for k := range s {
   159  		if f(k) {
   160  			filtered.Add(k)
   161  		}
   162  	}
   163  	return filtered
   164  }
   165  
   166  //IsSubset returns true if every key in s is also in other
   167  func (s String) IsSubset(other String) bool {
   168  	if len(s) > len(other) {
   169  		return false
   170  	}
   171  
   172  	for k := range s {
   173  		if _, ok := other[k]; !ok {
   174  			return false
   175  		}
   176  
   177  	}
   178  	return true
   179  }
   180  
   181  //Remove removes a key from the set, returning the presence of the key.
   182  func (s String) Remove(key string) bool {
   183  	_, ok := s[key]
   184  	delete(s, key)
   185  	return ok
   186  }
   187  
   188  //Pop an arbitrary element from the set. Returns "", false if no more elements remain. No order, or lack of order, is guaranteed.
   189  func (s String) Pop() (k string, more bool) {
   190  	for k := range s {
   191  		//iterate
   192  		delete(s, k)
   193  		return k, true
   194  	}
   195  	return "", false
   196  }
   197  
   198  //IsDisjoint returns true if s shared no elements with other. Note that the empty set is disjoint with everything.
   199  func (s String) IsDisjoint(other String) bool {
   200  	for k := range s {
   201  		if _, ok := other[k]; ok {
   202  			return false
   203  		}
   204  	}
   205  	return true
   206  }
   207  
   208  //IsProperSubset returns true if every key in s is also in other and s != other
   209  func (s String) IsProperSubset(other String) bool {
   210  	return len(s) < len(other) && s.IsSubset(other)
   211  }
   212  
   213  //IsSuperset returns true if every key in other is also in s
   214  func (s String) IsSuperset(other String) bool {
   215  	return other.IsSubset(s)
   216  }
   217  
   218  //IsProperSuperset returns true if every key in other is also in s and s != other
   219  func (s String) IsProperSuperset(other String) bool {
   220  	return len(s) > len(other) && other.IsSuperset(s)
   221  }