英文:
How to delete a key from a complex map?
问题
我知道delete(...)
函数的用法。但是我有一个包含多个映射的数组:
[
{key: "aa", value1: 1, value2: "33"},
{key: "bb", value1: 23, value2: "333"},
{key: "cc", value1: 33, value2: "3366"},
{key: "yy", value1: 99, value2: "666"},
// 其他项
]
我该如何从这个结构中删除具有特定key
的项?比如说,key == "bb"
和key == "yy"
。
请注意,这个数组的实际大小更大,可能有几十个或几百个项。因此,我希望有一个高效的解决方案。
英文:
I'm aware of the function delete(...)
. But I have an array of maps:
[
{key: "aa", value1: 1, value2: "33"},
{key: "bb", value1: 23, value2: "333"},
{key: "cc", value1: 33, value2: "3366"},
{key: "yy", value1: 99, value2: "666"},
// other items
]
How would I delete the items from this structure which have certain key
-s ? Let's say, key == "bb"
and key == "yy"
Note that the real size of this array is bigger - dozens or hundreds of items. As such, I'd prefer a performant solution.
答案1
得分: 0
你可以使用一个常见的技巧,在迭代过程中将元素向下移动,然后在最后进行截断。
j := 0
for _, v := range mySlice {
if v.key != "bb" && v.key != "yy" {
mySlice[j] = v
j++
}
}
mySlice = mySlice[:j]
这种方法使用了 O(1) 的额外内存,并且效率很高。
在 go1.18 中,你将能够编写一个通用函数(通常称为 filter),来执行切片操作。下面是一个完整的示例,你也可以在 gotip playground 上运行它。
package main
import "fmt"
// filter 函数返回一个切片(重用 m 的底层数组),其中包含 f 返回 true 的所有元素。
func filter[T any](m []T, f func(*T) bool) []T {
j := 0
for i := range m {
if f(&m[i]) {
m[j] = m[i]
j++
}
}
return m[:j]
}
type data struct {
key string
value1 int
value2 string
}
func main() {
xs := []data{
{key: "aa", value1: 1, value2: "33"},
{key: "bb", value1: 23, value2: "333"},
{key: "cc", value1: 33, value2: "3366"},
{key: "yy", value1: 99, value2: "666"},
}
xs = filter(xs, func(x *data) bool { return x.key != "bb" && x.key != "yy" })
fmt.Println(xs)
}
英文:
You can use a standard trick of moving things down in the slice as you iterate, and then truncating at the end.
j := 0
for _, v := range mySlice {
if v.key != "bb" && v.key != "yy" {
mySlice[j] = v
j++
}
}
mySlice = mySlice[:j]
This uses O(1) extra memory, and is efficient.
In go1.18, you'll be able to write a generic function (which is typically called filter) to do the slicing. Here's a complete example, which you can also run on the gotip playground.
package main
import "fmt"
// filter returns a slice (reusing the backing array of m), that
// contains all the elements of m for which f returns true.
func filter[T any](m []T, f func(*T) bool) []T {
j := 0
for i := range m {
if f(&m[i]) {
m[j] = m[i]
j++
}
}
return m[:j]
}
type data struct {
key string
value1 int
value2 string
}
func main() {
xs := []data{
{key: "aa", value1: 1, value2: "33"},
{key: "bb", value1: 23, value2: "333"},
{key: "cc", value1: 33, value2: "3366"},
{key: "yy", value1: 99, value2: "666"},
}
xs = filter(xs, func(x *data) bool { return x.key != "bb" && x.key != "yy" })
fmt.Println(xs)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论