2023-08-18 08:07:25 +00:00
|
|
|
package set
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"golang.org/x/exp/maps"
|
|
|
|
)
|
|
|
|
|
|
|
|
type hashFunc[T any] func(a T) string
|
|
|
|
|
|
|
|
// Set struct represents set data structure
|
|
|
|
type Set[T any] struct {
|
|
|
|
key hashFunc[T]
|
|
|
|
data map[string]T
|
|
|
|
}
|
|
|
|
|
2024-10-10 11:18:23 +00:00
|
|
|
// Values returns a slice of the set's values
|
|
|
|
func (s *Set[T]) Values() []T {
|
|
|
|
return maps.Values(s.data)
|
|
|
|
}
|
|
|
|
|
2023-08-18 08:07:25 +00:00
|
|
|
// NewSetFromF initialise a new set with initial values and a hash function
|
|
|
|
// to define uniqueness of value
|
|
|
|
func NewSetFromF[T any](values []T, f hashFunc[T]) *Set[T] {
|
|
|
|
s := &Set[T]{
|
|
|
|
key: f,
|
|
|
|
data: make(map[string]T),
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range values {
|
|
|
|
s.Add(v)
|
|
|
|
}
|
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewSetF initialise a new empty and a hash function
|
|
|
|
// to define uniqueness of value
|
|
|
|
func NewSetF[T any](f hashFunc[T]) *Set[T] {
|
|
|
|
return NewSetFromF([]T{}, f)
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewSetFrom initialise a new set with initial values which are comparable
|
|
|
|
func NewSetFrom[T comparable](values []T) *Set[T] {
|
|
|
|
return NewSetFromF(values, func(item T) string {
|
|
|
|
return fmt.Sprintf("%v", item)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewSetFrom initialise a new empty set for comparable values
|
|
|
|
func NewSet[T comparable]() *Set[T] {
|
|
|
|
return NewSetFrom([]T{})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Set[T]) addOne(item T) {
|
|
|
|
s.data[s.key(item)] = item
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add one or multiple items to set
|
|
|
|
func (s *Set[T]) Add(items ...T) {
|
|
|
|
for _, i := range items {
|
|
|
|
s.addOne(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove an item from set. No-op if the item does not exist
|
|
|
|
func (s *Set[T]) Remove(item T) {
|
|
|
|
delete(s.data, s.key(item))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Indicates if the item exists in the set
|
|
|
|
func (s *Set[T]) Has(item T) bool {
|
|
|
|
_, ok := s.data[s.key(item)]
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
2024-10-10 11:18:23 +00:00
|
|
|
// Size returns the number of elements in the set
|
|
|
|
func (s *Set[T]) Size() int {
|
|
|
|
return len(s.data)
|
|
|
|
}
|
|
|
|
|
2023-08-18 08:07:25 +00:00
|
|
|
// Returns an iterable slice of values from set
|
|
|
|
func (s *Set[T]) Iter() []T {
|
|
|
|
return maps.Values(s.data)
|
|
|
|
}
|