Files
phishingclub/backend/vendor/github.com/enetx/g/set.go
T
Ronni Skansing 07c8adaf76 update vendor deps
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
2025-11-06 23:31:08 +01:00

361 lines
8.4 KiB
Go

package g
import (
"fmt"
)
// 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] {
return make(Set[T], Slice[Int](size).Get(0).UnwrapOrDefault())
}
// TransformSet applies the given function to each element of a Set and returns a new Set
// containing the transformed values.
//
// Parameters:
//
// - s: The input Set.
// - fn: The function to apply to each element of the input Set.
//
// Returns:
//
// A new Set containing the results of applying the function to each element of the input Set.
func TransformSet[T, U comparable](s Set[T], fn func(T) U) Set[U] {
if len(s) == 0 {
return NewSet[U]()
}
result := make(Set[U], len(s))
for v := range s {
result[fn(v)] = struct{}{}
}
return result
}
// 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] = struct{}{}
}
return set
}
// Transform applies a transformation function to the Set and returns the result.
func (s Set[T]) Transform(fn func(Set[T]) Set[T]) Set[T] { return fn(s) }
// Iter returns an iterator (SeqSet[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 'SetMap', to perform operations on each element of the Set.
//
// Returns:
//
// A SeqSet[T], which can be used for sequential iteration over the elements of the Set.
//
// Example usage:
//
// iter := g.SetOf(1, 2, 3).Iter()
// iter.ForEach(func(val T) {
// 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() SeqSet[T] { return seqSet(s) }
func (s Set[T]) Iter() SeqSet[T] {
return func(yield func(T) bool) {
for v := range s {
if !yield(v) {
return
}
}
}
}
// func (s Set[T]) Iter() SeqSet[T] { return seqSet(s) }
// Insert adds the provided elements to the set.
func (s Set[T]) Insert(values ...T) {
for _, v := range values {
s[v] = struct{}{}
}
}
// Remove removes the specified values from the Set.
func (s Set[T]) Remove(values ...T) {
for _, v := range values {
delete(s, v)
}
}
// 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 element from another Set.
func (s Set[T]) ContainsAny(other Set[T]) bool {
if s.Empty() || other.Empty() {
return false
}
if len(s) <= len(other) {
for v := range s {
if _, ok := other[v]; ok {
return true
}
}
} else {
for v := range other {
if _, ok := s[v]; ok {
return true
}
}
}
return false
}
// ContainsAll checks if the Set contains all elements from another Set.
func (s Set[T]) ContainsAll(other Set[T]) bool {
if len(s) < len(other) {
return false
}
for v := range other {
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.Empty() {
return NewSet[T]()
}
clone := make(Set[T], len(s))
for k := range s {
clone[k] = struct{}{}
}
return clone
}
// ToSlice returns a new Slice with the same elements as the Set[T].
func (s Set[T]) ToSlice() Slice[T] {
if s.Empty() {
return NewSlice[T]()
}
sl := make(Slice[T], 0, len(s))
for v := range s {
sl = append(sl, v)
}
return sl
}
// 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]) SeqSet[T] {
if len(s) <= len(other) {
return intersection(s.Iter(), other)
}
return intersection(other.Iter(), s)
}
// 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]) SeqSet[T] { return difference(s.Iter(), other) }
// 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]) SeqSet[T] {
if len(s) > len(other) {
return s.Iter().Chain(other.Difference(s))
}
return other.Iter().Chain(s.Difference(other))
}
// 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]) SeqSet[T] {
return s.Difference(other).Chain(other.Difference(s))
}
// 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 { return other.ContainsAll(s) }
// 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 s.ContainsAll(other) }
// 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() {
for k := range s {
delete(s, k)
}
}
// Empty checks if the Set is empty.
func (s Set[T]) Empty() bool { return len(s) == 0 }
// NotEmpty checks if the Set is not empty.
func (s Set[T]) NotEmpty() bool { return !s.Empty() }
// String returns a string representation of the Set.
func (s Set[T]) String() string {
if s.Empty() {
return "Set{}"
}
var b Builder
b.WriteString("Set{")
first := true
for v := range s {
if !first {
b.WriteString(", ")
}
first = false
b.WriteString(Format("{}", v))
}
b.WriteString("}")
return b.String().Std()
}
// 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 }