set

package
v0.18.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 8, 2026 License: BSD-3-Clause Imports: 3 Imported by: 0

Documentation

Overview

Package set provides a generic Set data structure for storing unique elements.

Set is a collection that contains no duplicate elements. It models the mathematical set abstraction and provides operations for testing membership, computing unions, intersections, and differences.

Basic Usage

Create and use a set:

s := set.New[string]()
s.Add("apple")
s.Add("banana")
s.Add("apple") // Duplicate, not added

fmt.Println(s.Size())         // 2
fmt.Println(s.Contains("apple")) // true

Create from a slice:

numbers := []int{1, 2, 3, 2, 1}
s := set.FromSlice(numbers)
fmt.Println(s.Size()) // 3 (duplicates removed)

Adding and Removing

s := set.New[int]()

added := s.Add(1)        // true (new element)
added = s.Add(1)         // false (duplicate)

count := s.AddAll(2, 3, 4, 3) // Adds 3 new elements
fmt.Println(count)       // 3

removed := s.Remove(2)   // true
removed = s.Remove(99)   // false (not present)

Membership Testing

s := set.New[string]()
s.Add("hello")

if s.Contains("hello") {
    fmt.Println("Found!")
}

if s.IsEmpty() {
    fmt.Println("Set is empty")
}

size := s.Size()

Set Operations

**Union** - All elements from both sets:

s1 := set.FromSlice([]int{1, 2, 3})
s2 := set.FromSlice([]int{3, 4, 5})
union := s1.Union(s2)
fmt.Println(union.ToSlice()) // [1, 2, 3, 4, 5]

**Intersection** - Elements in both sets:

intersection := s1.Intersection(s2)
fmt.Println(intersection.ToSlice()) // [3]

**Difference** - Elements in first set but not second:

diff := s1.Difference(s2)
fmt.Println(diff.ToSlice()) // [1, 2]

**Symmetric Difference** - Elements in either set but not both:

symDiff := s1.SymmetricDifference(s2)
fmt.Println(symDiff.ToSlice()) // [1, 2, 4, 5]

Subset and Superset

s1 := set.FromSlice([]int{1, 2})
s2 := set.FromSlice([]int{1, 2, 3, 4})

if s1.IsSubset(s2) {
    fmt.Println("s1 is a subset of s2")
}

if s2.IsSuperset(s1) {
    fmt.Println("s2 is a superset of s1")
}

Equality

s1 := set.FromSlice([]int{1, 2, 3})
s2 := set.FromSlice([]int{3, 2, 1})

if s1.Equal(s2) {
    fmt.Println("Sets are equal") // Order doesn't matter
}

Iteration

s := set.FromSlice([]string{"a", "b", "c"})

s.Range(func(item string) bool {
    fmt.Println(item)
    return true // Continue iteration
})

slice := s.ToSlice() // Convert to slice

Copying Sets

original := set.FromSlice([]int{1, 2, 3})
copy := original.Clone()

copy.Add(4)
fmt.Println(original.Size()) // 3 (unchanged)
fmt.Println(copy.Size())     // 4

You can also copy by assignment since Set uses value semantics:

s1 := set.New[int]()
s1.Add(1)
s2 := s1 // Both reference the same underlying map
s2.Add(2)
fmt.Println(s1.Size()) // 2 (same map)

Use Cases

**Removing Duplicates:**

data := []int{1, 2, 2, 3, 3, 3, 4}
unique := set.FromSlice(data).ToSlice()

**Tracking Seen Items:**

seen := set.New[string]()
for _, item := range items {
    if seen.Contains(item) {
        fmt.Println("Duplicate:", item)
        continue
    }
    seen.Add(item)
    process(item)
}

**Set Algebra:**

admins := set.FromSlice([]string{"alice", "bob"})
users := set.FromSlice([]string{"bob", "charlie"})

allPeople := admins.Union(users)
bothRoles := admins.Intersection(users)
adminOnly := admins.Difference(users)

**Tag Filtering:**

required := set.FromSlice([]string{"go", "backend"})
articleTags := set.FromSlice([]string{"go", "backend", "tutorial"})

if required.IsSubset(articleTags) {
    fmt.Println("Article matches all required tags")
}

Performance

**Time Complexity:**

  • Add: O(1) average
  • Remove: O(1) average
  • Contains: O(1) average
  • Size/IsEmpty: O(1)
  • Union/Intersection/Difference: O(n+m)
  • IsSubset/IsSuperset: O(n)
  • Equal: O(n)

**Space Complexity:**

  • O(n) where n is the number of elements
  • Uses map[T]struct{} for zero-byte values

Value Semantics

Set uses value semantics (not pointer receivers). This is safe and efficient because:

  • The underlying map is a reference type
  • Copying a Set copies only the map header (~24 bytes), not the data
  • Multiple Set values can share the same underlying map data

For independent sets, use Clone():

s1 := set.New[int]()
s2 := s1.Clone() // Independent copy

Comparison with map[T]struct{}

// Manual set with map
m := make(map[string]struct{})
m["item"] = struct{}{}
_, exists := m["item"]

// Set package
s := set.New[string]()
s.Add("item")
exists := s.Contains("item")

Set provides:

  • Cleaner API
  • Set operations (union, intersection, etc.)
  • Convenience methods
  • Clear intent in code

Thread Safety

Set is not thread-safe. For concurrent access, use external synchronization:

var mu sync.RWMutex
s := set.New[int]()

mu.Lock()
s.Add(1)
mu.Unlock()

mu.RLock()
exists := s.Contains(1)
mu.RUnlock()

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Set

type Set[T comparable] struct {
	// contains filtered or unexported fields
}

Set is a collection of unique comparable elements. It is safe to copy Set values as the underlying map is a reference type.

func FromSlice

func FromSlice[T comparable](slice []T) Set[T]

FromSlice creates a new Set containing all unique elements from the given slice.

func New

func New[T comparable]() Set[T]

New creates and returns a new empty Set.

func (*Set[T]) Add

func (s *Set[T]) Add(item T) bool

Add inserts an element into the set. Returns true if the element was added (wasn't already present), false otherwise.

func (*Set[T]) AddAll

func (s *Set[T]) AddAll(items ...T) int

AddAll inserts multiple elements into the set. Returns the count of elements that were actually added (excludes duplicates).

func (Set[T]) AsMap

func (s Set[T]) AsMap() map[T]struct{}

AsMap returns the underlying map representation of the Set. The returned map has keys of type T and values of empty struct{}. Useful for interoperability with code that expects map[T]struct{}.

WARNING: This returns a reference to the internal map, NOT a copy. Modifying the returned map will affect the Set. Use Clone() if you need an independent copy.

func (*Set[T]) Clear

func (s *Set[T]) Clear()

Clear removes all elements from the set.

func (*Set[T]) Clone

func (s *Set[T]) Clone() Set[T]

Clone creates a deep copy of the Set with an independent internal map. Modifications to the clone will not affect the original Set and vice versa.

func (*Set[T]) Contains

func (s *Set[T]) Contains(item T) bool

Contains checks if an element exists in the set.

func (*Set[T]) Difference

func (s *Set[T]) Difference(other Set[T]) Set[T]

Difference returns a new set containing elements in this set but not in the other set.

func (*Set[T]) Equal

func (s *Set[T]) Equal(other Set[T]) bool

Equal returns true if both sets contain exactly the same elements.

func (*Set[T]) Intersection

func (s *Set[T]) Intersection(other Set[T]) Set[T]

Intersection returns a new set containing only elements present in both sets.

func (*Set[T]) IsEmpty

func (s *Set[T]) IsEmpty() bool

IsEmpty returns true if the set contains no elements.

func (*Set[T]) IsSubset

func (s *Set[T]) IsSubset(other Set[T]) bool

IsSubset returns true if all elements of this set are in the other set.

func (*Set[T]) IsSuperset

func (s *Set[T]) IsSuperset(other Set[T]) bool

IsSuperset returns true if this set contains all elements of the other set.

func (*Set[T]) Range

func (s *Set[T]) Range(fn func(T) bool)

Range calls the given function for each element in the set. If the function returns false, iteration stops.

func (*Set[T]) Remove

func (s *Set[T]) Remove(item T) bool

Remove deletes an element from the set. Returns true if the element was removed (was present), false otherwise.

func (Set[T]) Seq

func (s Set[T]) Seq() iter.Seq[T]

Seq returns an iter.Seq that yields all elements in the set. This enables use with Go 1.23 for-range loops.

func (*Set[T]) Size

func (s *Set[T]) Size() int

Size returns the number of elements in the set.

func (*Set[T]) String added in v0.16.1

func (s *Set[T]) String() string

String returns a string representation of the Set.

func (*Set[T]) SymmetricDifference

func (s *Set[T]) SymmetricDifference(other Set[T]) Set[T]

SymmetricDifference returns a new set containing elements in either set but not in both.

func (*Set[T]) ToSlice

func (s *Set[T]) ToSlice() []T

ToSlice returns a slice containing all elements in the set. The order of elements is not guaranteed.

func (*Set[T]) Union

func (s *Set[T]) Union(other Set[T]) Set[T]

Union returns a new set containing all elements from both sets.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL