v8.run/go/exp@v0.0.26-0.20230226010534-afcdbd3f782d/util/maps/set.go (about)

     1  package maps
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"strings"
     7  )
     8  
     9  type Set[T comparable] map[T]struct{}
    10  
    11  func NewSet[T comparable](values ...T) Set[T] {
    12  	s := make(Set[T])
    13  	for _, v := range values {
    14  		s[v] = struct{}{}
    15  	}
    16  	return s
    17  }
    18  
    19  func (s Set[T]) Contains(v T) bool {
    20  	_, ok := s[v]
    21  	return ok
    22  }
    23  
    24  func (s Set[T]) Insert(v T) {
    25  	s[v] = struct{}{}
    26  }
    27  
    28  func (s Set[T]) Remove(v T) {
    29  	delete(s, v)
    30  }
    31  
    32  func (s Set[T]) Size() int {
    33  	return len(s)
    34  }
    35  
    36  func (s Set[T]) Values() []T {
    37  	keys := make([]T, 0, len(s))
    38  	for v := range s {
    39  		keys = append(keys, v)
    40  	}
    41  
    42  	var zero T
    43  	switch any(&zero).(type) {
    44  	case *string:
    45  		sort.Strings(*any(&keys).(*[]string))
    46  	case *int:
    47  		sort.Ints(*any(&keys).(*[]int))
    48  	case *float64:
    49  		sort.Float64s(*any(&keys).(*[]float64))
    50  	case *uint:
    51  		sort.Sort(sortableSlice[uint](*any(&keys).(*[]uint)))
    52  	case *uint8:
    53  		sort.Sort(sortableSlice[uint8](*any(&keys).(*[]uint8)))
    54  	case *uint16:
    55  		sort.Sort(sortableSlice[uint16](*any(&keys).(*[]uint16)))
    56  	case *uint32:
    57  		sort.Sort(sortableSlice[uint32](*any(&keys).(*[]uint32)))
    58  	case *uint64:
    59  		sort.Sort(sortableSlice[uint64](*any(&keys).(*[]uint64)))
    60  	case *uintptr:
    61  		sort.Sort(sortableSlice[uintptr](*any(&keys).(*[]uintptr)))
    62  	case *int8:
    63  		sort.Sort(sortableSlice[int8](*any(&keys).(*[]int8)))
    64  	case *int16:
    65  		sort.Sort(sortableSlice[int16](*any(&keys).(*[]int16)))
    66  	case *int32:
    67  		sort.Sort(sortableSlice[int32](*any(&keys).(*[]int32)))
    68  	case *int64:
    69  		sort.Sort(sortableSlice[int64](*any(&keys).(*[]int64)))
    70  	case *float32:
    71  		sort.Sort(sortableSlice[float32](*any(&keys).(*[]float32)))
    72  	}
    73  
    74  	return keys
    75  }
    76  
    77  func (s Set[T]) String() string {
    78  	var sb strings.Builder
    79  	sb.WriteString("{")
    80  	var i int
    81  	for k := range s {
    82  		if i > 0 {
    83  			sb.WriteString(", ")
    84  		}
    85  
    86  		fmt.Fprint(&sb, k)
    87  		i++
    88  	}
    89  	sb.WriteString("}")
    90  
    91  	return sb.String()
    92  }
    93  
    94  func (s Set[T]) Union(other Set[T]) Set[T] {
    95  	result := make(Set[T])
    96  	for k := range s {
    97  		result[k] = struct{}{}
    98  	}
    99  	for k := range other {
   100  		result[k] = struct{}{}
   101  	}
   102  	return result
   103  }
   104  
   105  func (s Set[T]) Intersection(other Set[T]) Set[T] {
   106  	result := make(Set[T])
   107  	for k := range s {
   108  		if other.Contains(k) {
   109  			result[k] = struct{}{}
   110  		}
   111  	}
   112  	return result
   113  }
   114  
   115  func (s Set[T]) Subtract(other Set[T]) Set[T] {
   116  	result := make(Set[T])
   117  	for k := range s {
   118  		if !other.Contains(k) {
   119  			result[k] = struct{}{}
   120  		}
   121  	}
   122  	return result
   123  }
   124  
   125  func (s Set[T]) SymmetricDifference(other Set[T]) Set[T] {
   126  	result := make(Set[T])
   127  	for k := range s {
   128  		if !other.Contains(k) {
   129  			result[k] = struct{}{}
   130  		}
   131  	}
   132  	for k := range other {
   133  		if !s.Contains(k) {
   134  			result[k] = struct{}{}
   135  		}
   136  	}
   137  	return result
   138  }
   139  
   140  func (s Set[T]) IsSubsetOf(other Set[T]) bool {
   141  	for k := range s {
   142  		if !other.Contains(k) {
   143  			return false
   144  		}
   145  	}
   146  	return true
   147  }
   148  
   149  func (s Set[T]) IsSupersetOf(other Set[T]) bool {
   150  	return other.IsSubsetOf(s)
   151  }
   152  
   153  func (s Set[T]) Equals(other Set[T]) bool {
   154  	if s.Size() != other.Size() {
   155  		return false
   156  	}
   157  	return s.IsSubsetOf(other) && other.IsSubsetOf(s)
   158  }