在Go列表中按值删除元素

问题描述 投票:0回答:3

我有一个元素列表,我想按值删除其中一个。在 Python 中,这将是

l = ["apples", "oranges", "melon"]
l.remove("melon")
print(l) # ["apples", "orange"]

Go 中的等价物是什么?我发现了一个切片技巧来通过索引删除元素,但它的可读性不太好,仍然需要我手动查找索引,并且仅适用于单个项目类型:

func remove(l []string, item string) {
    for i, other := range l {
        if other == item {
            return append(l[:i], l[i+1:]...)
        }
    }
}

list.List
结构,但它不是通用的,因此需要大量的类型转换才能使用。

从列表中删除元素的惯用方法是什么?

list go slice
3个回答
23
投票

从列表中删除元素的惯用方法是像示例中那样循环遍历它。从切片中按值删除元素在程序中应该不会太常见,因为它是一个

O(n)
操作,并且该语言中有更好的数据结构。因此,Go 没有提供内置的切片删除功能。

如果您发现自己经常使用按值删除,请考虑使用集合来代替,其中删除和添加元素是

O(1)
,同时仍然是可迭代的。

set := map[string]bool{"apples":true, "oranges":true, "melon":true}
delete(set,"melon") // is O(1)

9
投票

在通用 Go (1.18) 中,过滤函数适用于任何

comparable
类型。它仅删除第一个出现的项目。 func remove[T comparable](l []T, item T) []T { for i, other := range l { if other == item { return append(l[:i], l[i+1:]...) } } return l }

游乐场:
https://go.dev/play/p/ojlYkvf5dQG?v=gotip

如果要删除
所有

出现的情况,请将匹配的项目附加到新切片: func remove[T comparable](l []T, item T) []T { out := make([]T, 0) for _, element := range l { if element != item { out = append(out, element) } } return out }

游乐场:
https://go.dev/play/p/W2MerNbh72H

如果切片项不具有可比性,您可以使用自定义相等函数进行过滤:

func main() { list := [][]int{{1, 2}, {2, 2}, {1, 10}} newlist := remove(list, func(element []int) bool { return element[0] == 1 }) fmt.Println(newlist) } func remove[T any](l []T, remove func(T) bool) []T { out := make([]T, 0) for _, element := range l { if !remove(element) { out = append(out, element) } } return out }

游乐场:
https://go.dev/play/p/qZWoFbM_RUl


0
投票
slices.DeleteFunc

import "slices"

l := []string{"apples", "oranges", "melon"}

l = slices.DeleteFunc(l, func(cmp string) bool {
  return cmp == "melon"
})

	
© www.soinside.com 2019 - 2024. All rights reserved.