1

I am writing a counter function in Go that accepts an iterable data structure (namely an array, slice, or string), and then counts the elements of that structure:

func NewFreqDist(iterable interface{}) *FreqDist {
  fd := FreqDist{make(map[reflect.Value]int)}
  switch reflect.TypeOf(iterable).Kind() {
    case reflect.Array, reflect.Slice, reflect.String:
      i := reflect.ValueOf(iterable)
      for j := 0; j < i.Len(); j++ {
        fd.Samples[i.Index(j)]++
      }
    default:
      Code to handle if the structure is not iterable...
  }
  return &fd
}

The FreqDist object contains a map (Samples) which contains the counts. However, when I print the map outside the function, it looks like this:

map[<uint8 Value>:1 <uint8 Value>:1]

Accessing a value in the map with a key does not work properly. The answer suggesting the use of the reflect package for this problem is here. So, how does one go about traversing an arbitrary data structure in Go?

Community
  • 1
  • 1

1 Answers1

1

The top comment on the answer you linked to is

The only thing to add would be that s.Index(i) returns a reflect.Value so in my case I needed s.Index(i).Interface() to reference the actual value. – Nucleon

If I'm understanding your question correctly, I believe this is your solution. Instead of using i.Index(j) to define keys in your map, try i.Index(j).Interface(). Your map will need to be map[interface{}]int. This way you can use data from the original iterable as keys when accessing values in the map.

Here's a playground example I (crudely) adapted from your code: https://play.golang.org/p/Rwtm9EOmyN

Depending on your data, you may want to use CanInterface() at some point to avoid a panic.

doykle
  • 127
  • 7