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

     1  package set
     2  
     3  import "sort"
     4  
     5  //Int is a set of ints. Remember to initialize with make(Int) or Int{}
     6  type Int map[int]signal
     7  
     8  //Contains shows whether a given key is in the Int.
     9  func (s Int) Contains(key int) bool {
    10  	_, ok := s[key]
    11  	return ok
    12  }
    13  
    14  //Copy copies the set of ints.
    15  func (s Int) Copy() Int {
    16  	copy := make(Int)
    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 ints;
    24  func (s Int) Intersection(ints ...Int) (intersection Int) {
    25  	intersection = s.Copy()
    26  	for key := range s {
    27  		for _, set := range append(ints, 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 Int) XOR(other Int) Int {
    38  	union := s.Union(other)
    39  	xor := make(Int)
    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 Ints are equal; i.e, they contain the same items.
    49  func (s Int) Equal(other Int) 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 int sets.
    62  func (s Int) Union(ints ...Int) (union Int) {
    63  	union = s.Copy()
    64  	for _, set := range ints {
    65  		for key := range set {
    66  			union[key] = yes
    67  		}
    68  	}
    69  	return union
    70  }
    71  
    72  //IUnion modifies the Int in place rather than returning a copy.
    73  func (s Int) IUnion(ints ...Int) {
    74  	for _, set := range ints {
    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 Int) Difference(ints ...Int) (difference Int) {
    83  	difference = s.Copy()
    84  	for _, set := range ints {
    85  		for key := range set {
    86  			delete(difference, key)
    87  		}
    88  	}
    89  	return difference
    90  }
    91  
    92  //FromInts creates a set from ints
    93  func FromInts(ints ...int) Int {
    94  	s := make(Int)
    95  	for _, key := range ints {
    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 Int) Add(keys ...int) {
   103  	for _, key := range keys {
   104  		s[key] = yes
   105  	}
   106  }
   107  
   108  //Delete a key or keys from the set, in-place.
   109  func (s Int) Delete(keys ...int) {
   110  	for _, key := range keys {
   111  		delete(s, key)
   112  	}
   113  }
   114  
   115  //ToSlice returns a slice containing the keys of a set. No order is guaranteed.
   116  func (s Int) ToSlice() []int {
   117  	slice := make([]int, len(s))
   118  	var i = 0
   119  	for k := range s {
   120  		slice[i] = k
   121  		i++
   122  	}
   123  	return slice
   124  }
   125  
   126  //Sorted returns a slice containing the sorted keys of the set in the usual order.
   127  func (s Int) Sorted() []int {
   128  	slice := s.ToSlice()
   129  	sort.Ints(slice)
   130  	return slice
   131  }
   132  
   133  //Map a function f(x) across the set, returning a new set containing f(x) for all x in the set.
   134  func (s Int) Map(f func(int) int) Int {
   135  	mapped := make(Int)
   136  	for k := range s {
   137  		mapped[f(k)] = yes
   138  	}
   139  	return mapped
   140  
   141  }
   142  
   143  //Reduce applies a reducing function across the set. It will return (0, false) for a set with zero entries.
   144  func (s Int) Reduce(f func(int, int) int) (int, bool) {
   145  	if len(s) == 0 {
   146  		return 0, false
   147  	}
   148  	first := true
   149  	var reduced int
   150  	for k := range s {
   151  		if first {
   152  			reduced = k
   153  			first = false
   154  
   155  		} else {
   156  			reduced = f(reduced, k)
   157  		}
   158  	}
   159  	return reduced, true
   160  }
   161  
   162  //Filter applies a filtering function across the set, returning a set containing x where f(x) is true.
   163  func (s Int) Filter(f func(int) bool) Int {
   164  	filtered := make(Int)
   165  	for k := range s {
   166  		if f(k) {
   167  			filtered.Add(k)
   168  		}
   169  	}
   170  	return filtered
   171  }
   172  
   173  //IsSubset returns true if s⊆other; every key in s is also in other
   174  func (s Int) IsSubset(other Int) bool {
   175  	if len(s) > len(other) {
   176  		return false
   177  	}
   178  
   179  	for k := range s {
   180  		if _, ok := other[k]; !ok {
   181  			return false
   182  		}
   183  
   184  	}
   185  	return true
   186  }
   187  
   188  //Remove removes a key from the set, returning the presence of the key.
   189  func (s Int) Remove(key int) bool {
   190  	_, ok := s[key]
   191  	delete(s, key)
   192  	return ok
   193  }
   194  
   195  //Pop an arbitrary element from the set. Returns 0, false if no more elements remain. No order (or lack of order) is guaranteed.
   196  func (s Int) Pop() (k int, more bool) {
   197  	for k := range s {
   198  		delete(s, k)
   199  		return k, true
   200  	}
   201  	return 0, false
   202  }
   203  
   204  //IsDisjoint returns true if s∩other == Ø; that is, s shares no elements with other. Note that the empty set is disjoint with everything.
   205  func (s Int) IsDisjoint(other Int) bool {
   206  	for k := range s {
   207  		if _, ok := other[k]; ok {
   208  			return false
   209  		}
   210  	}
   211  	return true
   212  }
   213  
   214  //IsProperSubset returns true if every s ⊂ other: every key in s is also in other and s != other
   215  func (s Int) IsProperSubset(other Int) bool {
   216  	return len(s) < len(other) && s.IsSubset(other)
   217  }
   218  
   219  //IsSuperset returns true if other ⊆ s; every key in other is also in s
   220  func (s Int) IsSuperset(other Int) bool {
   221  	return other.IsSubset(s)
   222  }
   223  
   224  //IsProperSuperset returns true if other ⊂ s; every key in other is also in s and s != other
   225  func (s Int) IsProperSuperset(other Int) bool {
   226  	return len(s) > len(other) && other.IsSuperset(s)
   227  }