Skip to content

Commit

Permalink
feat: add set implementation using generic (#656)
Browse files Browse the repository at this point in the history
* feat: add set implementation using generic

* some refact

* use gofmt

---------

Co-authored-by: Rak Laptudirm <[email protected]>
  • Loading branch information
nikhrom and raklaptudirm authored Oct 2, 2023
1 parent 58bb31e commit 30392a3
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 55 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.

---

##### package set implements a Set using a golang map. This implies that only the types that are accepted as valid map keys can be used as set elements. For instance, do not try to Add a slice, or the program will panic.
##### package set implements a Set using generics and a golang map with comparable interface key. This implies that only the types that are accepted as valid map keys can be used as set elements

---
##### Functions:
Expand Down
78 changes: 39 additions & 39 deletions structure/set/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
package set

// New gives new set.
func New(items ...any) Set {
st := set{
elements: make(map[any]bool),
func New[T comparable](items ...T) Set[T] {
st := set[T]{
elements: make(map[T]bool),
}
for _, item := range items {
st.Add(item)
Expand All @@ -15,73 +15,73 @@ func New(items ...any) Set {
}

// Set is an interface of possible methods on 'set'.
type Set interface {
type Set[T comparable] interface {
// Add: adds new element to the set
Add(item any)
Add(item T)
// Delete: deletes the passed element from the set if present
Delete(item any)
Delete(item T)
// Len: gives the length of the set (total no. of elements in set)
Len() int
// GetItems: gives the array( []any ) of elements of the set.
GetItems() []any
// GetItems: gives the array( []T ) of elements of the set.
GetItems() []T
// In: checks whether item is present in set or not.
In(item any) bool
In(item T) bool
// IsSubsetOf: checks whether set is subset of set2 or not.
IsSubsetOf(set2 Set) bool
IsSubsetOf(set2 Set[T]) bool
// IsProperSubsetOf: checks whether set is proper subset of set2 or not.
// ex: [1,2,3] proper subset of [1,2,3,4] -> true
IsProperSubsetOf(set2 Set) bool
IsProperSubsetOf(set2 Set[T]) bool
// IsSupersetOf: checks whether set is superset of set2 or not.
IsSupersetOf(set2 Set) bool
IsSupersetOf(set2 Set[T]) bool
// IsProperSupersetOf: checks whether set is proper superset of set2 or not.
// ex: [1,2,3,4] proper superset of [1,2,3] -> true
IsProperSupersetOf(set2 Set) bool
IsProperSupersetOf(set2 Set[T]) bool
// Union: gives new union set of both sets.
// ex: [1,2,3] union [3,4,5] -> [1,2,3,4,5]
Union(set2 Set) Set
Union(set2 Set[T]) Set[T]
// Intersection: gives new intersection set of both sets.
// ex: [1,2,3] Intersection [3,4,5] -> [3]
Intersection(set2 Set) Set
Intersection(set2 Set[T]) Set[T]
// Difference: gives new difference set of both sets.
// ex: [1,2,3] Difference [3,4,5] -> [1,2]
Difference(set2 Set) Set
Difference(set2 Set[T]) Set[T]
// SymmetricDifference: gives new symmetric difference set of both sets.
// ex: [1,2,3] SymmetricDifference [3,4,5] -> [1,2,4,5]
SymmetricDifference(set2 Set) Set
SymmetricDifference(set2 Set[T]) Set[T]
}

type set struct {
elements map[any]bool
type set[T comparable] struct {
elements map[T]bool
}

func (st *set) Add(value any) {
func (st *set[T]) Add(value T) {
st.elements[value] = true
}

func (st *set) Delete(value any) {
func (st *set[T]) Delete(value T) {
delete(st.elements, value)
}

func (st *set) GetItems() []any {
keys := make([]any, 0, len(st.elements))
func (st *set[T]) GetItems() []T {
keys := make([]T, 0, len(st.elements))
for k := range st.elements {
keys = append(keys, k)
}
return keys
}

func (st *set) Len() int {
func (st *set[T]) Len() int {
return len(st.elements)
}

func (st *set) In(value any) bool {
func (st *set[T]) In(value T) bool {
if _, in := st.elements[value]; in {
return true
}
return false
}

func (st *set) IsSubsetOf(superSet Set) bool {
func (st *set[T]) IsSubsetOf(superSet Set[T]) bool {
if st.Len() > superSet.Len() {
return false
}
Expand All @@ -94,26 +94,26 @@ func (st *set) IsSubsetOf(superSet Set) bool {
return true
}

func (st *set) IsProperSubsetOf(superSet Set) bool {
func (st *set[T]) IsProperSubsetOf(superSet Set[T]) bool {
if st.Len() == superSet.Len() {
return false
}
return st.IsSubsetOf(superSet)
}

func (st *set) IsSupersetOf(subSet Set) bool {
func (st *set[T]) IsSupersetOf(subSet Set[T]) bool {
return subSet.IsSubsetOf(st)
}

func (st *set) IsProperSupersetOf(subSet Set) bool {
func (st *set[T]) IsProperSupersetOf(subSet Set[T]) bool {
if st.Len() == subSet.Len() {
return false
}
return st.IsSupersetOf(subSet)
}

func (st *set) Union(st2 Set) Set {
unionSet := New()
func (st *set[T]) Union(st2 Set[T]) Set[T] {
unionSet := New[T]()
for _, item := range st.GetItems() {
unionSet.Add(item)
}
Expand All @@ -123,9 +123,9 @@ func (st *set) Union(st2 Set) Set {
return unionSet
}

func (st *set) Intersection(st2 Set) Set {
intersectionSet := New()
var minSet, maxSet Set
func (st *set[T]) Intersection(st2 Set[T]) Set[T] {
intersectionSet := New[T]()
var minSet, maxSet Set[T]
if st.Len() > st2.Len() {
minSet = st2
maxSet = st
Expand All @@ -141,8 +141,8 @@ func (st *set) Intersection(st2 Set) Set {
return intersectionSet
}

func (st *set) Difference(st2 Set) Set {
differenceSet := New()
func (st *set[T]) Difference(st2 Set[T]) Set[T] {
differenceSet := New[T]()
for _, item := range st.GetItems() {
if !st2.In(item) {
differenceSet.Add(item)
Expand All @@ -151,9 +151,9 @@ func (st *set) Difference(st2 Set) Set {
return differenceSet
}

func (st *set) SymmetricDifference(st2 Set) Set {
symmetricDifferenceSet := New()
dropSet := New()
func (st *set[T]) SymmetricDifference(st2 Set[T]) Set[T] {
symmetricDifferenceSet := New[T]()
dropSet := New[T]()
for _, item := range st.GetItems() {
if st2.In(item) {
dropSet.Add(item)
Expand Down
30 changes: 15 additions & 15 deletions structure/set/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ func TestIsProperSupersetOf(t *testing.T) {
func TestUnion(t *testing.T) {
td := []struct {
name string
s1 Set
s2 Set
expSet Set
s1 Set[int]
s2 Set[int]
expSet Set[int]
}{
{"union of different sets", New(1, 2, 3), New(4, 5, 6), New(1, 2, 3, 4, 5, 6)},
{"union of sets with elements in common", New(1, 2, 3), New(1, 2, 4), New(1, 2, 3, 4)},
Expand All @@ -144,11 +144,11 @@ func TestUnion(t *testing.T) {
func TestIntersection(t *testing.T) {
td := []struct {
name string
s1 Set
s2 Set
expSet Set
s1 Set[int]
s2 Set[int]
expSet Set[int]
}{
{"intersection of different sets", New(0, 1, 2, 3), New(4, 5, 6), New()},
{"intersection of different sets", New(0, 1, 2, 3), New(4, 5, 6), New[int]()},
{"intersection of sets with elements in common", New(1, 2, 3), New(1, 2, 4), New(1, 2)},
{"intersection of same sets", New(1, 2, 3), New(1, 2, 3), New(1, 2, 3)},
}
Expand All @@ -170,13 +170,13 @@ func TestIntersection(t *testing.T) {
func TestDifference(t *testing.T) {
td := []struct {
name string
s1 Set
s2 Set
expSet Set
s1 Set[int]
s2 Set[int]
expSet Set[int]
}{
{"difference of different sets", New(1, 2, 3), New(4, 5, 6), New(1, 2, 3)},
{"difference of sets with elements in common", New(1, 2, 3), New(1, 2, 4), New(3)},
{"difference of same sets", New(1, 2, 3), New(1, 2, 3), New()},
{"difference of same sets", New(1, 2, 3), New(1, 2, 3), New[int]()},
}
for _, tc := range td {
t.Run(tc.name, func(t *testing.T) {
Expand All @@ -196,13 +196,13 @@ func TestDifference(t *testing.T) {
func TestSymmetricDifference(t *testing.T) {
td := []struct {
name string
s1 Set
s2 Set
expSet Set
s1 Set[int]
s2 Set[int]
expSet Set[int]
}{
{"symmetric difference of different sets", New(1, 2, 3), New(4, 5, 6), New(1, 2, 3, 4, 5, 6)},
{"symmetric difference of sets with elements in common", New(1, 2, 3), New(1, 2, 4), New(3, 4)},
{"symmetric difference of same sets", New(1, 2, 3), New(1, 2, 3), New()},
{"symmetric difference of same sets", New(1, 2, 3), New(1, 2, 3), New[int]()},
}
for _, tc := range td {
t.Run(tc.name, func(t *testing.T) {
Expand Down

0 comments on commit 30392a3

Please sign in to comment.