英文:
Delete element from custom type (slice of pointers) in Go
问题
我必须在运行自定义类型"MergedVars"的方法时从该自定义类型中删除一个元素(它是一个指针的切片):
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`\n", 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 = append((*m)[:pos], (*m)[pos+1:]...)
}
所以运行以下代码:
m := MergedVars{}
m.Insert("foo", 1)
m.Insert("bar", 2)
m.Insert("foo", 3)
应该得到一个包含两个元素的切片,其中键为"foo"的元素的值为3,其"old"字段指向"foo":1
在这里查看(不)工作的示例:
http://play.golang.org/p/0-cx8tdOZD
如何正确实现remove函数?
英文:
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`\n", 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?
答案1
得分: 1
根据您的要求,我理解您需要用更新后的值替换与新支柱的键匹配的支柱,并将旧支柱指向被替换的支柱。一种方法如下所示,您无需从切片中删除。
请注意,在这种情况下,插入顺序为新的 foo,即在 bar 之后插入的 3 将不会保持,并且将替换 foo,即在位置 0 的 1 之前的 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)
}
}
您可以在此链接中查看代码示例:http://play.golang.org/p/KINvnAP08Q
英文:
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)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论