1package set
2
3type (
4	Set struct {
5		hash map[interface{}]nothing
6	}
7
8	nothing struct{}
9)
10
11// Create a new set
12func New(initial ...interface{}) *Set {
13	s := &Set{make(map[interface{}]nothing)}
14
15	for _, v := range initial {
16		s.Insert(v)
17	}
18
19	return s
20}
21
22// Find the difference between two sets
23func (this *Set) Difference(set *Set) *Set {
24	n := make(map[interface{}]nothing)
25
26	for k, _ := range this.hash {
27		if _, exists := set.hash[k]; !exists {
28			n[k] = nothing{}
29		}
30	}
31
32	return &Set{n}
33}
34
35// Call f for each item in the set
36func (this *Set) Do(f func(interface{})) {
37	for k, _ := range this.hash {
38		f(k)
39	}
40}
41
42// Test to see whether or not the element is in the set
43func (this *Set) Has(element interface{}) bool {
44	_, exists := this.hash[element]
45	return exists
46}
47
48// Add an element to the set
49func (this *Set) Insert(element interface{}) {
50	this.hash[element] = nothing{}
51}
52
53// Find the intersection of two sets
54func (this *Set) Intersection(set *Set) *Set {
55	n := make(map[interface{}]nothing)
56
57	for k, _ := range this.hash {
58		if _, exists := set.hash[k]; exists {
59			n[k] = nothing{}
60		}
61	}
62
63	return &Set{n}
64}
65
66// Return the number of items in the set
67func (this *Set) Len() int {
68	return len(this.hash)
69}
70
71// Test whether or not this set is a proper subset of "set"
72func (this *Set) ProperSubsetOf(set *Set) bool {
73	return this.SubsetOf(set) && this.Len() < set.Len()
74}
75
76// Remove an element from the set
77func (this *Set) Remove(element interface{}) {
78	delete(this.hash, element)
79}
80
81// Test whether or not this set is a subset of "set"
82func (this *Set) SubsetOf(set *Set) bool {
83	if this.Len() > set.Len() {
84		return false
85	}
86	for k, _ := range this.hash {
87		if _, exists := set.hash[k]; !exists {
88			return false
89		}
90	}
91	return true
92}
93
94// Find the union of two sets
95func (this *Set) Union(set *Set) *Set {
96	n := make(map[interface{}]nothing)
97
98	for k, _ := range this.hash {
99		n[k] = nothing{}
100	}
101	for k, _ := range set.hash {
102		n[k] = nothing{}
103	}
104
105	return &Set{n}
106}
107