从Go中的自定义类型(指针切片)中删除元素

huangapple go评论66阅读模式
英文:

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)
	}
}

http://play.golang.org/p/KINvnAP08Q

huangapple
  • 本文由 发表于 2015年11月23日 21:37:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/33872452.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定