1// Copyright (c) 2015, Emir Pasic. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package hashset implements a set backed by a hash table.
6//
7// Structure is not thread safe.
8//
9// References: http://en.wikipedia.org/wiki/Set_%28abstract_data_type%29
10package hashset
11
12import (
13	"fmt"
14	"github.com/emirpasic/gods/sets"
15	"strings"
16)
17
18func assertSetImplementation() {
19	var _ sets.Set = (*Set)(nil)
20}
21
22// Set holds elements in go's native map
23type Set struct {
24	items map[interface{}]struct{}
25}
26
27var itemExists = struct{}{}
28
29// New instantiates a new empty set and adds the passed values, if any, to the set
30func New(values ...interface{}) *Set {
31	set := &Set{items: make(map[interface{}]struct{})}
32	if len(values) > 0 {
33		set.Add(values...)
34	}
35	return set
36}
37
38// Add adds the items (one or more) to the set.
39func (set *Set) Add(items ...interface{}) {
40	for _, item := range items {
41		set.items[item] = itemExists
42	}
43}
44
45// Remove removes the items (one or more) from the set.
46func (set *Set) Remove(items ...interface{}) {
47	for _, item := range items {
48		delete(set.items, item)
49	}
50}
51
52// Contains check if items (one or more) are present in the set.
53// All items have to be present in the set for the method to return true.
54// Returns true if no arguments are passed at all, i.e. set is always superset of empty set.
55func (set *Set) Contains(items ...interface{}) bool {
56	for _, item := range items {
57		if _, contains := set.items[item]; !contains {
58			return false
59		}
60	}
61	return true
62}
63
64// Empty returns true if set does not contain any elements.
65func (set *Set) Empty() bool {
66	return set.Size() == 0
67}
68
69// Size returns number of elements within the set.
70func (set *Set) Size() int {
71	return len(set.items)
72}
73
74// Clear clears all values in the set.
75func (set *Set) Clear() {
76	set.items = make(map[interface{}]struct{})
77}
78
79// Values returns all items in the set.
80func (set *Set) Values() []interface{} {
81	values := make([]interface{}, set.Size())
82	count := 0
83	for item := range set.items {
84		values[count] = item
85		count++
86	}
87	return values
88}
89
90// String returns a string representation of container
91func (set *Set) String() string {
92	str := "HashSet\n"
93	items := []string{}
94	for k := range set.items {
95		items = append(items, fmt.Sprintf("%v", k))
96	}
97	str += strings.Join(items, ", ")
98	return str
99}
100