我有一个元素列表,我想按值删除其中一个。在 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
结构,但它不是通用的,因此需要大量的类型转换才能使用。
从列表中删除元素的惯用方法是什么?
从列表中删除元素的惯用方法是像示例中那样循环遍历它。从切片中按值删除元素在程序中应该不会太常见,因为它是一个
O(n)
操作,并且该语言中有更好的数据结构。因此,Go 没有提供内置的切片删除功能。
如果您发现自己经常使用按值删除,请考虑使用集合来代替,其中删除和添加元素是
O(1)
,同时仍然是可迭代的。
set := map[string]bool{"apples":true, "oranges":true, "melon":true}
delete(set,"melon") // is O(1)
在通用 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
slices.DeleteFunc
:
import "slices"
l := []string{"apples", "oranges", "melon"}
l = slices.DeleteFunc(l, func(cmp string) bool {
return cmp == "melon"
})