I have to remove an element from custom type "MergedVars" (which is a slice of pointers) while running a method of that custom type:
type Merged struct {
Key string
Value int
Old *Merged
}
type MergedVars []*Merged
func (m MergedVars) String() string {
var out string
for _, v := range m {
out += fmt.Sprintf("Key: `%s`, Value: `%d`, Old: `%v`
", v.Key, v.Value, v.Old)
}
return out
}
func (m *MergedVars) Insert(key string, value int) {
v := &Merged{
Key: key,
Value: value,
}
for k, mv := range *m {
if mv.Key == key {
v.Old = mv
m.remove(k)
}
}
*m = append(*m, v)
}
// This fails
func (m *MergedVars) remove(pos int) {
// https://github.com/golang/go/wiki/SliceTricks
m, m[len(m)-1] = append(m[:pos], m[pos+1:]...), nil
}
So running this...
m := MergedVars{}
m.Insert("foo", 1)
m.Insert("bar", 2)
m.Insert("foo", 3)
... should get me a slice of two elements where the element with the key "foo" has value 3 and its "old" field points to "foo": 1
See it (not) working at:
http://play.golang.org/p/0-cx8tdOZD
How do I have to implement the remove function proparly?
From you requirement, what I understand is that you need to replace strut whose key matches with new strut with updated value and point Old to the previous one getting replaced. One way to do as follows, where you don't need to remove from slice.
Please note in this case your insertion order fro the new foo, 3 which is inserted after bar will not be maintained, and will be the replace the foo, 1 at position 0, before bar.
func (m *MergedVars) Insert(key string, value int) {
v := &Merged{
Key: key,
Value: value,
}
found := false
for k, mv := range *m {
if mv.Key == key {
v.Old = mv
m1 := *m
m1[k] = v
found = true
}
}
if !found {
*m = append(*m, v)
}
}