This is a variant of the venerable question "why is my cartographic question out of order".
I have a (rather large) number of mappings of the form map[MyKey]MyValue , where MyKey and MyValue are (usually) structures. I have less functions for all types of keys.
I need to sort the cards in order. (In particular, the order determined by the smaller function of this type.) At the moment, my code is as follows:
type PairKeyValue struct { MyKey MyValue } type PairKeyValueSlice []Pair func (ps PairKeyValueSlice) Len() int { return len(ps) } func (ps PairKeyValueSlice) Swap(i,j int) { ps[i], ps[j] = ps[j], ps[i] } func (ps PairKeyValueSlice) Less(i,j int) { return LessKey(ps[i].MyKey, ps[j].MyKey) } func NewPairKeyValueSlice(m map[MyKey]MyValue) (ps PairKeyValueSlice) { ps = make(PairKeyValueSlice, len(m)) i := 0 for k,v := range m { ps[i] = PairKeyValue{k,v} i++ } sort.Sort(ps) }
And then, anytime I need iteration in order, it looks like this:
var m map[MyKey]MyValue m = GetMapFromSomewhereUseful() for _, kv := range NewPairKeyValueSlice(m) { key := kv.MyKey value := kv.MyValue DoUsefulWork(key, value) }
And that seems to work basically. The problem is that it is terribly verbose. In particular, since the problem is actually very little related to the implementation of ordered maps, it really is useful work in a loop.
In addition, I have several different types of keys and values. Thus, every time I want to iterate over the map in order, I copy / paste all this code and find / replace MyKey new key and MyValue with a new value. Copy / paste this value ... "smelly." This has already become a hassle, as I have already made several mistakes that I had to correct several times.
This technique also has the disadvantage that it requires a complete copy of all keys and values. This is undesirable, but I do not see the way around it. (I could only reduce it to keys, but that does not change the underlying nature of the problem.)
This question is trying to do the same with strings. This question does this with strings and ints. This question implies that you need to use reflection and must have a switch statement that includes all possible types, including all user types.
But with people who are puzzled that maps do not determine iteration, it seems like this should be the best solution to this problem. I am from an OO background, so I probably missed something fundamental.
So, is there a reasonable way to iterate over the map in order?
Update: Editing the question to have more source information if there is a better solution than this.
I have a lot of things that I need to group for output. Each level of grouping is in a structure that looks like this:
type ObjTypeTree struct { Children map[Type]*ObjKindTree TotalCount uint } type ObjKindTree struct { Children map[Kind]*ObjAreaTree TotalCount uint } type ObjAreaTree struct { Children map[Area]*ObjAreaTree TotalCount uint Objs []*Obj }
Then I will ObjTypeTree over the children in ObjTypeTree to print Type groupings. For each of them, I ObjKindTree over ObjKindTree to print Kind groups. Iterations are performed using methods for types, and each type of type requires a slightly different way to print the grouping level. Groups must be printed in order, which causes a problem.