dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

hashset.go (4004B)


      1 package hashset
      2 
      3 import "errors"
      4 
      5 type HashSet[V comparable] struct {
      6 	items map[V]struct{}
      7 }
      8 
      9 func New[V comparable]() *HashSet[V] {
     10 	h := new(HashSet[V])
     11 	h.items = make(map[V]struct{})
     12 	return h
     13 }
     14 
     15 func (h *HashSet[V]) Set(v V) {
     16 	h.items[v] = struct{}{}
     17 }
     18 
     19 // Insert adds a value to the set.
     20 // If the set did not have this value present, true is returned.
     21 // If the set did have this value present, false is returned.
     22 func (h *HashSet[V]) Insert(v V) bool {
     23 	if h.Contains(v) {
     24 		return false
     25 	}
     26 	h.items[v] = struct{}{}
     27 	return true
     28 }
     29 
     30 // Contains returns true if the set contains a value.
     31 func (h *HashSet[V]) Contains(v V) bool {
     32 	_, found := h.items[v]
     33 	return found
     34 }
     35 
     36 // Len returns the number of elements in the set.
     37 func (h *HashSet[V]) Len() int {
     38 	return len(h.items)
     39 }
     40 
     41 func (h *HashSet[V]) Empty() bool {
     42 	return len(h.items) == 0
     43 }
     44 
     45 // Clear clears the set, removing all values.
     46 func (h *HashSet[V]) Clear() {
     47 	h.items = make(map[V]struct{})
     48 }
     49 
     50 // Difference visits the values representing the difference, i.e., the values that are in self but not in other.
     51 func (h *HashSet[V]) Difference(other *HashSet[V]) *HashSet[V] {
     52 	n := New[V]()
     53 	for k, v := range h.items {
     54 		if !other.Contains(k) {
     55 			n.items[k] = v
     56 		}
     57 	}
     58 	return n
     59 }
     60 
     61 // SymmetricDifference visits the values representing the symmetric difference, i.e., the values that are in self or in other but not in both.
     62 func (h *HashSet[V]) SymmetricDifference(other *HashSet[V]) *HashSet[V] {
     63 	n := New[V]()
     64 	for k, v := range h.items {
     65 		if !other.Contains(k) {
     66 			n.items[k] = v
     67 		}
     68 	}
     69 	for k, v := range other.items {
     70 		if !h.Contains(k) {
     71 			n.items[k] = v
     72 		}
     73 	}
     74 	return n
     75 }
     76 
     77 // Intersection visits the values representing the intersection, i.e., the values that are both in self and other.
     78 func (h *HashSet[V]) Intersection(other *HashSet[V]) *HashSet[V] {
     79 	n := New[V]()
     80 	for k, v := range h.items {
     81 		if other.Contains(k) {
     82 			n.items[k] = v
     83 		}
     84 	}
     85 	return n
     86 }
     87 
     88 // Union visits the values representing the union, i.e., all the values in self or other, without duplicates.
     89 func (h *HashSet[V]) Union(other *HashSet[V]) *HashSet[V] {
     90 	n := New[V]()
     91 	for k, v := range h.items {
     92 		n.items[k] = v
     93 	}
     94 	for k, v := range other.items {
     95 		n.items[k] = v
     96 	}
     97 	return n
     98 }
     99 
    100 // Get returns a reference to the value in the set, if any, that is equal to the given value.
    101 func (h *HashSet[V]) Get(v V) (out V, err error) {
    102 	if !h.Contains(v) {
    103 		return out, errors.New("item not found")
    104 	}
    105 	return v, nil
    106 }
    107 
    108 // IsSubset returns true if the set is a subset of another, i.e., other contains at least all the values in self.
    109 func (h *HashSet[V]) IsSubset(other *HashSet[V]) bool {
    110 	for k := range h.items {
    111 		if !other.Contains(k) {
    112 			return false
    113 		}
    114 	}
    115 	return true
    116 }
    117 
    118 // IsSuperset returns true if the set is a superset of another, i.e., self contains at least all the values in other.
    119 func (h *HashSet[V]) IsSuperset(other *HashSet[V]) bool {
    120 	for k := range other.items {
    121 		if !h.Contains(k) {
    122 			return false
    123 		}
    124 	}
    125 	return true
    126 }
    127 
    128 // Replace adds a value to the set, replacing the existing value, if any, that is equal to the given one. Returns the replaced value.
    129 func (h *HashSet[V]) Replace(v V) (V, bool) {
    130 	var zero V
    131 	if h.Contains(v) {
    132 		return v, true
    133 	}
    134 	h.items[v] = struct{}{}
    135 	return zero, false
    136 }
    137 
    138 // Remove a value from the set. Returns whether the value was present in the set.
    139 func (h *HashSet[V]) Remove(v V) bool {
    140 	if !h.Contains(v) {
    141 		return false
    142 	}
    143 	delete(h.items, v)
    144 	return true
    145 }
    146 
    147 func (h *HashSet[V]) Delete(v V) {
    148 	delete(h.items, v)
    149 }
    150 
    151 // Take removes and returns the value in the set, if any, that is equal to the given one.
    152 func (h *HashSet[V]) Take(v V) (out V, err error) {
    153 	if !h.Contains(v) {
    154 		return out, errors.New("item not found")
    155 	}
    156 	delete(h.items, v)
    157 	return v, nil
    158 }
    159 
    160 func (h *HashSet[V]) Each(clb func(V)) {
    161 	for k := range h.items {
    162 		clb(k)
    163 	}
    164 }
    165 
    166 func (h *HashSet[V]) ToArray() []V {
    167 	out := make([]V, len(h.items))
    168 	i := 0
    169 	for k := range h.items {
    170 		out[i] = k
    171 		i++
    172 	}
    173 	return out
    174 }