golang why don't we have a set datastructure

Data StructuresGoSet

Data Structures Problem Overview


I'm trying to solve "The go programming lanaguage" exercise #1.4 which requires me to have a set. I can create a set type but why doesn't the language come with one ? go, having come from google, where guava also originated, why didn't the language designers opt for adding support for fundamental data structures ? why force your users to create their own implementations for something so basic as a set ?

Data Structures Solutions


Solution 1 - Data Structures

One reason is that it is easy to create a set from map:

s := map[int]bool{5: true, 2: true}
_, ok := s[6] // check for existence
s[8] = true // add element 
delete(s, 2) // remove element

Union

s_union := map[int]bool{}
for k, _ := range s1{
	s_union[k] = true
}
for k, _ := range s2{
	s_union[k] = true
}

Intersection

s_intersection := map[int]bool{}
if len(s1) > len(s2) {
  s1, s2 = s2, s1 // better to iterate over a shorter set
}
for k,_ := range s1 { 
  if s2[k] {
    s_intersection[k] = true
  }
}

It is not really that hard to implement all other set operations.

Solution 2 - Data Structures

Partly, because Go doesn't have generics (so you would need one set-type for every type, or fall back on reflection, which is rather inefficient).

Partly, because if all you need is "add/remove individual elements to a set" and "relatively space-efficient", you can get a fair bit of that simply by using a map[yourtype]bool (and set the value to true for any element in the set) or, for more space efficiency, you can use an empty struct as the value and use _, present = the_setoid[key] to check for presence.

Solution 3 - Data Structures

Like Vatine wrote: Since go lacks generics it would have to be part of the language and not the standard library. For that you would then have to pollute the language with keywords set, union, intersection, difference, subset...

The other reason is, that it's not clear at all what the "right" implementation of a set is:

  1. There is a functional approach:

     func IsInEvenNumbers(n int) bool {
         if n % 2 == 0 {
             return true
         }
        return false
     }
    

This is a set of all even ints. It has a very efficient lookup and union, intersect, difference and subset can easily be done by functional composition.

  1. Or you do a has-like approach like Dali showed.

A map does not have that problem, since you store something associated with the value.

Solution 4 - Data Structures

Another possibility is to use bit sets, for which there is at least one package or you can use the built-in big package. In this case, basically you need to define a way to convert your object to an index.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionanjanbView Question on Stackoverflow
Solution 1 - Data StructuresSalvador DaliView Answer on Stackoverflow
Solution 2 - Data StructuresVatineView Answer on Stackoverflow
Solution 3 - Data Structures0x434D53View Answer on Stackoverflow
Solution 4 - Data StructuresWill FitzgeraldView Answer on Stackoverflow