Files
phishingclub/backend/vendor/github.com/enetx/g/set.go
T

375 lines
8.3 KiB
Go

package g
import "fmt"
// Set is a generic alias for a set implemented using a map.
type Set[T comparable] map[T]Unit
// NewSet creates a new Set of the specified size or an empty Set if no size is provided.
func NewSet[T comparable](size ...Int) Set[T] {
if len(size) > 0 {
return make(Set[T], size[0])
}
return make(Set[T])
}
// SetOf creates a new generic set containing the provided elements.
func SetOf[T comparable](values ...T) Set[T] {
set := make(Set[T], len(values))
for _, v := range values {
set[v] = Unit{}
}
return set
}
// Transform applies a transformation function to the Set and returns the result.
func (s Set[T]) Transform[U any](fn func(Set[T]) U) U { return fn(s) }
// Iter returns an iterator (Seq[T]) for the Set, allowing for sequential iteration
// over its elements. It is commonly used in combination with higher-order functions,
// such as 'ForEach' or 'Map', to perform operations on each element of the Set.
//
// Returns:
//
// A Seq[T], which can be used for sequential iteration over the elements of the Set.
//
// Example usage:
//
// g.SetOf(1, 2, 3).Iter().ForEach(func(val int) {
// fmt.Println(val) // Replace this with the function logic you need.
// })
//
// The 'Iter' method provides a convenient way to traverse the elements of a Set
// in a functional style, enabling operations like mapping or filtering.
func (s Set[T]) Iter() Seq[T] {
return func(yield func(T) bool) {
for v := range s {
if !yield(v) {
return
}
}
}
}
// Insert adds the provided elements to the set.
func (s Set[T]) Insert(values ...T) {
for _, v := range values {
s[v] = Unit{}
}
}
// Remove removes the specified value from the Set and returns true if it was present.
func (s Set[T]) Remove(v T) bool {
if _, ok := s[v]; ok {
delete(s, v)
return true
}
return false
}
// Len returns the number of values in the Set.
func (s Set[T]) Len() Int { return Int(len(s)) }
// Contains checks if the Set contains the specified value.
func (s Set[T]) Contains(v T) bool {
_, ok := s[v]
return ok
}
// ContainsAny checks if the Set contains any of the provided values, matching
// the variadic shape of Slice.ContainsAny and String.ContainsAny.
func (s Set[T]) ContainsAny(values ...T) bool {
for _, v := range values {
if _, ok := s[v]; ok {
return true
}
}
return false
}
// ContainsAll checks if the Set contains all of the provided values, matching
// the variadic shape of Slice.ContainsAll and String.ContainsAll.
func (s Set[T]) ContainsAll(values ...T) bool {
for _, v := range values {
if _, ok := s[v]; !ok {
return false
}
}
return true
}
// Clone creates a new Set that is a copy of the original Set.
func (s Set[T]) Clone() Set[T] {
if s.IsEmpty() {
return NewSet[T]()
}
clone := make(Set[T], len(s))
for k := range s {
clone[k] = Unit{}
}
return clone
}
// Intersection returns the intersection of the current set and another set, i.e., elements
// present in both sets.
//
// Parameters:
//
// - other Set[T]: The other set to calculate the intersection with.
//
// Returns:
//
// - Set[T]: A new Set containing the intersection of the two sets.
//
// Example usage:
//
// s1 := g.SetOf(1, 2, 3, 4, 5)
// s2 := g.SetOf(4, 5, 6, 7, 8)
// intersection := s1.Intersection(s2)
//
// The resulting intersection will be: [4, 5].
func (s Set[T]) Intersection(other Set[T]) Set[T] {
small, big := s, other
if len(big) < len(small) {
small, big = big, small
}
result := make(Set[T], len(small))
for v := range small {
if big.Contains(v) {
result[v] = Unit{}
}
}
return result
}
// Difference returns the difference between the current set and another set,
// i.e., elements present in the current set but not in the other set.
//
// Parameters:
//
// - other Set[T]: The other set to calculate the difference with.
//
// Returns:
//
// - Set[T]: A new Set containing the difference between the two sets.
//
// Example usage:
//
// s1 := g.SetOf(1, 2, 3, 4, 5)
// s2 := g.SetOf(4, 5, 6, 7, 8)
// diff := s1.Difference(s2)
//
// The resulting diff will be: [1, 2, 3].
func (s Set[T]) Difference(other Set[T]) Set[T] {
result := make(Set[T], len(s))
for v := range s {
if !other.Contains(v) {
result[v] = Unit{}
}
}
return result
}
// Union returns a new set containing the unique elements of the current set and the provided
// other set.
//
// Parameters:
//
// - other Set[T]: The other set to create the union with.
//
// Returns:
//
// - Set[T]: A new Set containing the unique elements of the current set and the provided
// other set.
//
// Example usage:
//
// s1 := g.SetOf(1, 2, 3)
// s2 := g.SetOf(3, 4, 5)
// union := s1.Union(s2)
//
// The resulting union set will be: [1, 2, 3, 4, 5].
func (s Set[T]) Union(other Set[T]) Set[T] {
result := make(Set[T], len(s)+len(other))
for v := range s {
result[v] = Unit{}
}
for v := range other {
result[v] = Unit{}
}
return result
}
// SymmetricDifference returns the symmetric difference between the current set and another
// set, i.e., elements present in either the current set or the other set but not in both.
//
// Parameters:
//
// - other Set[T]: The other set to calculate the symmetric difference with.
//
// Returns:
//
// - Set[T]: A new Set containing the symmetric difference between the two sets.
//
// Example usage:
//
// s1 := g.SetOf(1, 2, 3, 4, 5)
// s2 := g.SetOf(4, 5, 6, 7, 8)
// symDiff := s1.SymmetricDifference(s2)
//
// The resulting symDiff will be: [1, 2, 3, 6, 7, 8].
func (s Set[T]) SymmetricDifference(other Set[T]) Set[T] {
result := make(Set[T])
for v := range s {
if !other.Contains(v) {
result[v] = Unit{}
}
}
for v := range other {
if !s.Contains(v) {
result[v] = Unit{}
}
}
return result
}
// Subset checks if the current set 's' is a subset of the provided 'other' set.
// A set 's' is a subset of 'other' if all elements of 's' are also elements of 'other'.
//
// Parameters:
//
// - other Set[T]: The other set to compare with.
//
// Returns:
//
// - bool: true if 's' is a subset of 'other', false otherwise.
//
// Example usage:
//
// s1 := g.SetOf(1, 2, 3)
// s2 := g.SetOf(1, 2, 3, 4, 5)
// isSubset := s1.Subset(s2) // Returns true
func (s Set[T]) Subset(other Set[T]) bool {
if len(s) > len(other) {
return false
}
for v := range s {
if _, ok := other[v]; !ok {
return false
}
}
return true
}
// Superset checks if the current set 's' is a superset of the provided 'other' set.
// A set 's' is a superset of 'other' if all elements of 'other' are also elements of 's'.
//
// Parameters:
//
// - other Set[T]: The other set to compare with.
//
// Returns:
//
// - bool: true if 's' is a superset of 'other', false otherwise.
//
// Example usage:
//
// s1 := g.SetOf(1, 2, 3, 4, 5)
// s2 := g.SetOf(1, 2, 3)
// isSuperset := s1.Superset(s2) // Returns true
func (s Set[T]) Superset(other Set[T]) bool { return other.Subset(s) }
// Eq checks if two Sets are equal.
func (s Set[T]) Eq(other Set[T]) bool {
if len(s) != len(other) {
return false
}
for v := range other {
if _, ok := s[v]; !ok {
return false
}
}
return true
}
// Ne checks if two Sets are not equal.
func (s Set[T]) Ne(other Set[T]) bool { return !s.Eq(other) }
// Clear removes all values from the Set.
func (s Set[T]) Clear() { clear(s) }
// IsEmpty checks if the Set is empty.
func (s Set[T]) IsEmpty() bool { return len(s) == 0 }
// String returns a string representation of the Set.
func (s Set[T]) String() string {
if s.IsEmpty() {
return "Set{}"
}
var b Builder
b.Grow(Int(len(s)) * 8)
b.WriteString("Set{")
first := true
for v := range s {
if !first {
b.WriteString(", ")
}
first = false
fmt.Fprint(&b, v)
}
b.WriteString("}")
return b.String().Std()
}
// Disjoint reports whether the set has no elements in common with other.
// It is the complement of ContainsAny.
func (s Set[T]) Disjoint(other Set[T]) bool {
small, big := s, other
if len(big) < len(small) {
small, big = big, small
}
for v := range small {
if _, ok := big[v]; ok {
return false
}
}
return true
}
// Print writes the elements of the Set to the standard output (console)
// and returns the Set unchanged.
func (s Set[T]) Print() Set[T] { fmt.Print(s); return s }
// Println writes the elements of the Set to the standard output (console) with a newline
// and returns the Set unchanged.
func (s Set[T]) Println() Set[T] { fmt.Println(s); return s }