github.com/blend/go-sdk@v1.20220411.3/collections/set.go (about)

     1  /*
     2  
     3  Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package collections
     9  
    10  import (
    11  	"strconv"
    12  	"strings"
    13  )
    14  
    15  // NewSetOfInt creates a new SetOfInt.
    16  func NewSetOfInt(values ...int) SetOfInt {
    17  	set := SetOfInt{}
    18  	for _, v := range values {
    19  		set.Add(v)
    20  	}
    21  	return set
    22  }
    23  
    24  // SetOfInt is a type alias for map[int]int
    25  type SetOfInt map[int]bool
    26  
    27  // Add adds an element to the set, replaceing a previous value.
    28  func (si SetOfInt) Add(i int) {
    29  	si[i] = true
    30  }
    31  
    32  // Remove removes an element from the set.
    33  func (si SetOfInt) Remove(i int) {
    34  	delete(si, i)
    35  }
    36  
    37  // Contains returns if the element is in the set.
    38  func (si SetOfInt) Contains(i int) bool {
    39  	_, ok := si[i]
    40  	return ok
    41  }
    42  
    43  // Len returns the number of elements in the set.
    44  func (si SetOfInt) Len() int {
    45  	return len(si)
    46  }
    47  
    48  // Copy returns a new copy of the set.
    49  func (si SetOfInt) Copy() SetOfInt {
    50  	newSet := NewSetOfInt()
    51  	for key := range si {
    52  		newSet.Add(key)
    53  	}
    54  	return newSet
    55  }
    56  
    57  // Union joins two sets together without dupes.
    58  func (si SetOfInt) Union(other SetOfInt) SetOfInt {
    59  	union := NewSetOfInt()
    60  	for k := range si {
    61  		union.Add(k)
    62  	}
    63  
    64  	for k := range other {
    65  		union.Add(k)
    66  	}
    67  	return union
    68  }
    69  
    70  // Intersect returns shared elements between two sets.
    71  func (si SetOfInt) Intersect(other SetOfInt) SetOfInt {
    72  	intersection := NewSetOfInt()
    73  	for k := range si {
    74  		if other.Contains(k) {
    75  			intersection.Add(k)
    76  		}
    77  	}
    78  	return intersection
    79  }
    80  
    81  // Difference returns non-shared elements between two sets.
    82  func (si SetOfInt) Difference(other SetOfInt) SetOfInt {
    83  	difference := NewSetOfInt()
    84  	for k := range si {
    85  		if !other.Contains(k) {
    86  			difference.Add(k)
    87  		}
    88  	}
    89  	for k := range other {
    90  		if !si.Contains(k) {
    91  			difference.Add(k)
    92  		}
    93  	}
    94  	return difference
    95  }
    96  
    97  // IsSubsetOf returns if a given set is a complete subset of another set,
    98  // i.e. all elements in target set are in other set.
    99  func (si SetOfInt) IsSubsetOf(other SetOfInt) bool {
   100  	for k := range si {
   101  		if !other.Contains(k) {
   102  			return false
   103  		}
   104  	}
   105  	return true
   106  }
   107  
   108  // AsSlice returns the set as a slice.
   109  func (si SetOfInt) AsSlice() []int {
   110  	output := []int{}
   111  	for key := range si {
   112  		output = append(output, key)
   113  	}
   114  	return output
   115  }
   116  
   117  // String returns the set as a csv string.
   118  func (si SetOfInt) String() string {
   119  	var values []string
   120  	for _, i := range si.AsSlice() {
   121  		values = append(values, strconv.Itoa(i))
   122  	}
   123  
   124  	return strings.Join(values, ", ")
   125  }
   126  
   127  // NewSetOfString creates a new SetOfString.
   128  func NewSetOfString(values ...string) SetOfString {
   129  	set := SetOfString{}
   130  	for _, v := range values {
   131  		set.Add(v)
   132  	}
   133  	return set
   134  }
   135  
   136  // SetOfString is a set of strings
   137  type SetOfString map[string]bool
   138  
   139  // Add adds an element.
   140  func (ss SetOfString) Add(entry string) {
   141  	if _, hasEntry := ss[entry]; !hasEntry {
   142  		ss[entry] = true
   143  	}
   144  }
   145  
   146  // Remove deletes an element, returns if the element was in the set.
   147  func (ss SetOfString) Remove(entry string) bool {
   148  	if _, hasEntry := ss[entry]; hasEntry {
   149  		delete(ss, entry)
   150  		return true
   151  	}
   152  	return false
   153  }
   154  
   155  // Contains returns if an element is in the set.
   156  func (ss SetOfString) Contains(entry string) bool {
   157  	_, hasEntry := ss[entry]
   158  	return hasEntry
   159  }
   160  
   161  // Len returns the length of the set.
   162  func (ss SetOfString) Len() int {
   163  	return len(ss)
   164  }
   165  
   166  // Copy returns a new copy of the set.
   167  func (ss SetOfString) Copy() SetOfString {
   168  	newSet := SetOfString{}
   169  	for key := range ss {
   170  		newSet.Add(key)
   171  	}
   172  	return newSet
   173  }
   174  
   175  // Union joins two sets together without dupes.
   176  func (ss SetOfString) Union(other SetOfString) SetOfString {
   177  	union := NewSetOfString()
   178  	for k := range ss {
   179  		union.Add(k)
   180  	}
   181  
   182  	for k := range other {
   183  		union.Add(k)
   184  	}
   185  	return union
   186  }
   187  
   188  // Intersect returns shared elements between two sets.
   189  func (ss SetOfString) Intersect(other SetOfString) SetOfString {
   190  	intersection := NewSetOfString()
   191  	for k := range ss {
   192  		if other.Contains(k) {
   193  			intersection.Add(k)
   194  		}
   195  	}
   196  	return intersection
   197  }
   198  
   199  // Difference returns non-shared elements between two sets.
   200  func (ss SetOfString) Difference(other SetOfString) SetOfString {
   201  	difference := NewSetOfString()
   202  	for k := range ss {
   203  		if !other.Contains(k) {
   204  			difference.Add(k)
   205  		}
   206  	}
   207  	for k := range other {
   208  		if !ss.Contains(k) {
   209  			difference.Add(k)
   210  		}
   211  	}
   212  	return difference
   213  }
   214  
   215  // IsSubsetOf returns if a given set is a complete subset of another set,
   216  // i.e. all elements in target set are in other set.
   217  func (ss SetOfString) IsSubsetOf(other SetOfString) bool {
   218  	for k := range ss {
   219  		if !other.Contains(k) {
   220  			return false
   221  		}
   222  	}
   223  	return true
   224  }
   225  
   226  // AsSlice returns the set as a slice.
   227  func (ss SetOfString) AsSlice() []string {
   228  	output := []string{}
   229  	for key := range ss {
   230  		output = append(output, key)
   231  	}
   232  	return output
   233  }
   234  
   235  // String returns the set as a csv string.
   236  func (ss SetOfString) String() string {
   237  	return strings.Join(ss.AsSlice(), ", ")
   238  }