'Does golang have the plan for supporting set datastructure?

This feature can be implemented with 'map'.

countrySet := map[string]bool{
  "US": true,
  "JP": true, 
  "KR": true,
}

But to ease the eyes of readers, 'set' is a necessary data structure.

countrySet := set[string]{"US", "JP", "KR"}

Does golang have the plan for supporting syntax like this?



Solution 1:[1]

I don't know about such plans.

What you may do to ease the initialization:

Use a one-letter bool constant:

const t = true
countrySet := map[string]bool{"US": t, "JP": t, "KR": t}

Use a loop to add the keys, so you only need to list the keys:

countrySet := map[string]bool{}
for _, v := range []string{"US", "JP", "KR"} {
    countrySet[v] = true
}

This is only profitable if you have more elements.

But you can always create a helper function:

func createSet(es ...string) map[string]bool {
    m := map[string]bool{}
    for _, v := range es {
        m[v] = true
    }
    return m
}

And then using it:

countrySet := createSet("US", "JP", "KR")

Solution 2:[2]

The plan is not to support everything in the Go standard library. The plan is to encourage open source, independently developed packages. For example, one of many,

package sets

import "k8s.io/apimachinery/pkg/util/sets"

Package sets has auto-generated set types.

Solution 3:[3]

I think the map[string]bool is a good option. Another option is map[string]struct{}:

package main
import "fmt"

func main() {
   s := map[string]struct{}{
      "JP": {}, "KR": {}, "US": {},
   }
   s["UA"] = struct{}{}
   if _, ok := s["UA"]; ok {
      println("ok")
   }
   fmt.Println(s)
}

It's marginally better than bool, as the values take up zero bytes versus one byte, but it's a little more awkward to work with. Another option is fstest.MapFS:

package main

import (
   "fmt"
   "testing/fstest"
)

func main() {
   s := fstest.MapFS{"JP": nil, "KR": nil, "US": nil}
   s["UA"] = nil
   if _, ok := s["UA"]; ok {
      println("ok")
   }
   a, e := s.Glob("U*")
   if e != nil {
      panic(e)
   }
   fmt.Println(a) // [UA US]
}

This is neat because you can do pattern matching on the Set items.

https://golang.org/pkg/testing/fstest

Solution 4:[4]

Now with the Go 1.18+ generics feature, there are great packages that implement a generic Set data structure! You may use them for any comparable type of items.

Take a look at this one: https://github.com/amit7itz/goset

package main

import "github.com/amit7itz/goset"

func main() {
   s := goset.NewSet("a", "b", "c", "d")
   s2 := goset.NewSet("c", "d", "e", "f")
   fmt.Println(s.Intersection(s2)) // Set[string]{"c", "d"}
   fmt.Println(s.Union(s2)) // Set[string]{"a", "b", "c", "d", "e", "f"}
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 peterSO
Solution 3 halfer
Solution 4 Amit Itzkovitch