Documentation
¶
Overview ¶
Package set implements a generic programmatic Set data container.
Index ¶
- Variables
- type Config
- type Set
- func (set *Set[K, H, T]) Clone() *Set[K, H, T]
- func (set *Set[K, H, T]) Contains(key K) bool
- func (set *Set[K, H, T]) Copy(dst *Set[K, H, T], cond func(T) bool) *Set[K, H, T]
- func (set *Set[K, H, T]) ForEach(fn func(T) bool)
- func (set *Set[K, H, T]) Get(key K) (T, error)
- func (set *Set[K, H, T]) Pop(key K) (T, error)
- func (set *Set[K, H, T]) Push(value T) (T, error)
- func (set *Set[K, H, T]) Reset() error
- func (set *Set[K, H, T]) Values() []T
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrExist is returned by Set.Push when a matching entry is // already present. ErrExist = core.ErrExists // ErrNotExist is returned by Set.Pop and Set.Get when a matching entry // is not present. ErrNotExist = core.ErrNotExists )
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config[K, H comparable, T any] struct { // Hash computes the bucket identifier for the given K type Hash func(k K) (H, error) // ItemKey computes the K value from the T instance ItemKey func(v T) (K, error) // ItemMatch confirms the T instance matches the K value ItemMatch func(k K, v T) bool }
Config defines the callbacks used by a Set.
func (Config[K, H, T]) Equal ¶ added in v0.1.4
Equal determines if two Config instances use exactly the same callback functions by comparing their memory addresses using reflection. This is used to optimize Set operations like Copy() when configs are identical.
Equal isn't cheap but it saves Copy() from performing unnecessary rehashing.
func (Config[K, H, T]) Init ¶
Init initializes a Set that wasn't created using Config.New.
func (Config[K, H, T]) New ¶
New creates a Set based on the Config optionally receiving items. duplicates won't cause errors, just make sure to Set.Get the actually stored instances before assuming uniqueness.
Example ¶
package main
import (
"fmt"
"darvaza.org/x/container/set"
)
// User represents a user with ID and name
type User struct {
ID int
Name string
}
func main() {
// Create a configuration for a set of users
cfg := set.Config[int, int, User]{
ItemKey: func(u User) (int, error) { return u.ID, nil },
Hash: func(id int) (int, error) { return id % 10, nil },
ItemMatch: func(k int, u User) bool { return k == u.ID },
}
// Create a new set with initial users
users, err := cfg.New(
User{ID: 1, Name: "Alice"},
User{ID: 2, Name: "Bob"},
)
if err != nil {
panic(err)
}
// Check if user exists
fmt.Println("Contains user 1:", users.Contains(1))
fmt.Println("Contains user 3:", users.Contains(3))
}
Output: Contains user 1: true Contains user 3: false
type Set ¶
type Set[K, H comparable, T any] struct { // contains filtered or unexported fields }
Set implements a simple set using generics.
func (*Set[K, H, T]) Clone ¶
Clone creates a new Set containing the same values.
Example ¶
package main
import (
"fmt"
"darvaza.org/x/container/set"
)
func main() {
cfg := set.Config[string, string, string]{
ItemKey: func(s string) (string, error) { return s, nil },
Hash: func(s string) (string, error) { return s, nil },
ItemMatch: func(k, v string) bool { return k == v },
}
original, _ := cfg.New("red", "green", "blue")
clone := original.Clone()
// Modify original
_, _ = original.Push("yellow")
fmt.Println("Original has yellow:", original.Contains("yellow"))
fmt.Println("Clone has yellow:", clone.Contains("yellow"))
}
Output: Original has yellow: true Clone has yellow: false
func (*Set[K, H, T]) Contains ¶ added in v0.1.2
Contains tells if there is a matching item in the Set. It returns false if: - the Set is nil or uninitialized - the key is invalid according to the Set's configuration - no matching item exists.
func (*Set[K, H, T]) Copy ¶
Copy copies the values in the Set to another, optionally using a condition function.
If no destination is provided, one will be created. If an uninitialized destination is provided, it will be initialized using the source's Config and values copied in bulk.
Example ¶
package main
import (
"fmt"
"darvaza.org/core"
"darvaza.org/x/container/set"
)
// User represents a user with ID and name
type User struct {
ID int
Name string
}
func main() {
cfg := set.Config[int, int, User]{
ItemKey: func(u User) (int, error) { return u.ID, nil },
Hash: func(id int) (int, error) { return id % 10, nil },
ItemMatch: func(k int, u User) bool { return k == u.ID },
}
users, _ := cfg.New(
User{ID: 1, Name: "Alice"},
User{ID: 2, Name: "Bob"},
User{ID: 3, Name: "Charlie"},
User{ID: 4, Name: "Diana"},
)
// Copy only users with even IDs
evenUsers := users.Copy(nil, func(u User) bool {
return u.ID%2 == 0
})
// Collect and sort for consistent output
var names []string
evenUsers.ForEach(func(u User) bool {
names = append(names, u.Name)
return true
})
core.SliceSortOrdered(names)
fmt.Print("Even users:")
for _, name := range names {
fmt.Printf(" %s", name)
}
fmt.Println()
}
Output: Even users: Bob Diana
func (*Set[K, H, T]) ForEach ¶
ForEach calls a function for each value in the Set until it returns false.
Example ¶
package main
import (
"fmt"
"darvaza.org/core"
"darvaza.org/x/container/set"
)
func main() {
cfg := set.Config[int, int, int]{
ItemKey: func(n int) (int, error) { return n, nil },
Hash: func(n int) (int, error) { return n % 10, nil },
ItemMatch: func(k, v int) bool { return k == v },
}
numbers, _ := cfg.New(1, 2, 3, 4, 5)
// Sum all numbers
sum := 0
numbers.ForEach(func(n int) bool {
sum += n
return true // continue iteration
})
fmt.Println("Sum:", sum)
// Find all even numbers
var evens []int
numbers.ForEach(func(n int) bool {
if n%2 == 0 {
evens = append(evens, n)
}
return true
})
// Sort for consistent output
core.SliceSortOrdered(evens)
fmt.Printf("Even numbers: %v\n", evens)
}
Output: Sum: 15 Even numbers: [2 4]
func (*Set[K, H, T]) Get ¶
Get returns the item matching the key
Example ¶
package main
import (
"fmt"
"darvaza.org/x/container/set"
)
// User represents a user with ID and name
type User struct {
ID int
Name string
}
func main() {
cfg := set.Config[int, int, User]{
ItemKey: func(u User) (int, error) { return u.ID, nil },
Hash: func(id int) (int, error) { return id % 10, nil },
ItemMatch: func(k int, u User) bool { return k == u.ID },
}
users, _ := cfg.New(
User{ID: 1, Name: "Alice"},
User{ID: 2, Name: "Bob"},
)
// Get existing user
if user, err := users.Get(1); err == nil {
fmt.Printf("User 1: %s\n", user.Name)
}
// Try to get non-existent user
if _, err := users.Get(3); err != nil {
fmt.Printf("User 3: %v\n", err)
}
}
Output: User 1: Alice User 3: does not exist
func (*Set[K, H, T]) Push ¶
Push adds entries to the set unless it already exist. It returns the value with matching key stored in the Set so it can be treated as a global reference.
Example ¶
package main
import (
"fmt"
"darvaza.org/x/container/set"
)
func main() {
cfg := set.Config[string, string, string]{
ItemKey: func(s string) (string, error) { return s, nil },
Hash: func(s string) (string, error) { return s, nil },
ItemMatch: func(k, v string) bool { return k == v },
}
tags, _ := cfg.New()
// Add tags
stored, err := tags.Push("golang")
fmt.Printf("Added golang: %q (err: %v)\n", stored, err)
stored, err = tags.Push("testing")
fmt.Printf("Added testing: %q (err: %v)\n", stored, err)
// Try to add duplicate
_, err = tags.Push("golang")
fmt.Println("Adding duplicate golang:", err)
}
Output: Added golang: "golang" (err: <nil>) Added testing: "testing" (err: <nil>) Adding duplicate golang: already exists
func (*Set[K, H, T]) Values ¶
func (set *Set[K, H, T]) Values() []T
Values returns all values in the Set.
Example ¶
package main
import (
"fmt"
"darvaza.org/x/container/set"
)
func main() {
cfg := set.Config[string, string, string]{
ItemKey: func(s string) (string, error) { return s, nil },
Hash: func(s string) (string, error) { return s, nil },
ItemMatch: func(k, v string) bool { return k == v },
}
fruits, _ := cfg.New("apple", "banana", "cherry")
// Get all values
allFruits := fruits.Values()
fmt.Printf("Total fruits: %d\n", len(allFruits))
// Note: order is not guaranteed
found := make(map[string]bool)
for _, fruit := range allFruits {
found[fruit] = true
}
// Check specific fruits
for _, fruit := range []string{"apple", "banana", "cherry"} {
fmt.Printf("Has %s: %v\n", fruit, found[fruit])
}
}
Output: Total fruits: 3 Has apple: true Has banana: true Has cherry: true