1

The following code serves to create a counter for each pair of float64.
Because the keys of a map cannot be a slice, I have to use arrays as keys, which forces me to to define a dimension with a constant.

counter := make( map[ [2]float64 ] int )
for _, comb := range combinations{ //combinations is a [n][2]float64
    for _, row := range data{  
        counter[ [...]float64{ row[comb[0]] , row[comb[1]] } ]++
    }
}

Having said that, is there a way to make this map dependent on the length of the keys (dependent on the dimensions of combinations?
I tried using a struct as key, but as far as I remember (I might be wrong), it was a bit slower... For my purposes (to apply this for all combinations ~n!) this is not the ideal solution.

Right now I'm only considering combinations of size 2 and 3, and I had to split this in two separate functions, which makes my code very verbose and harder to maintain. Can you find a way to simplify this, so I can scale it to more dimensions?

Thanks for any input

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
mik
  • 356
  • 1
  • 9
  • 24
  • 1
    Can you use `[3]float64`, and set the 3rd value to 0 (or some other unused value) when it's not used? Or use `[4]float64` with the first value being the (integer) length? These are logically the same as using a struct, but possibly more performant, at the expense of being harder to read. – Jonathan Hall Jul 10 '17 at 19:54
  • I actually have the [3]float64 case done also. I have a switch to navigate through dimensions. Because I wanted to generalize I also have an alternate method, though not so fast. I converted the input data to string, and proceeded to concatenate it. it doubles the processing time. however, for some applications its valid :) thanks for the input! – mik Jul 10 '17 at 20:57

1 Answers1

1

Why not use the pointer to a slice as key?

You could create a slice with make with a big enough capacity, while you do not surpass it's capacity, the pointer will remain the same.

Take a look here https://play.golang.org/p/333tRMpBLv , it exemplifies my suggestion. see that while len < cap the pointer of the slice is not changed, append only creates a new slice when len exceeds cap.

Alex Efimov
  • 3,335
  • 1
  • 24
  • 29
  • 1
    Maybe I'm missing the implementation of this. I intend to create a counter for the values in the slice. If I create a pointer to the slice, it will be a new value all the time, and the counter will be 1 for all entries. Is there an easy way to do this that I'm not seeing? – mik Jul 10 '17 at 15:24
  • 1
    You could create a slice with make with a big enough capacity, while you do not surpass it's capacity, the pointer will remain the same. – Alex Efimov Jul 11 '17 at 07:19
  • 1
    Take a look here https://play.golang.org/p/333tRMpBLv , it exemplifies my suggestion. see that while len < cap the pointer of the slice is not changed, append only creates a new slice when len exceeds cap. – Alex Efimov Jul 11 '17 at 08:42
  • Thanks for the suggestion. It seems the pointer remains the same - at least that's what it seems from my own machine and the sandbox you provided. maybe it was possible in an older go version... – mik Jul 13 '17 at 07:33
  • Append will change the pointer if you add more elements to the array that it's capacity and there is no more memory in that block. If it can expand in the same memory block it will and will not change the pointer. So you cannot be sure that it will not change when expanding array beyond its cap. So to be sure this does not happen I would recommend setting a high enough cap. – Alex Efimov Jul 14 '17 at 10:57