英文:
Filtering a slice of structs based on a different slice in Golang
问题
在下面的示例代码中,我有一些在manySimpleUsers
中的用户,我想根据用户名从manyFullUsers
中删除这些用户。
如果我使用嵌套的for...range
循环来完成,那么在过滤所有元素时将需要很多循环,特别是当两个切片中的元素数量很大时。
在Go语言中,最好的方法是什么?
package main
import "fmt"
func main() {
fmt.Println("Hello, playground")
type FullUser struct {
UserName string
UserEmail string
}
manyFullUsers := []FullUser{{"foo", "foo@jawohl.com"},
{"bar", "bar@jawohl.com"},
{"baz", "baz@jawohl.com"}}
type SimpleUser struct {
UserName string
}
manySimpleUsers := []SimpleUser{{"foo"}, {"bar"}}
fmt.Println(manyFullUsers)
fmt.Println(manySimpleUsers)
}
英文:
In the example code below, I have a few users in manySimpleUsers
that I would like to remove from manyFullUsers
based on the Username.
If I do it with a nested couple of for... range
loops, there will be many cycles required to filter all of the elements, especially when there are large numbers of elements in both Slices.
What is the best way to achieve this in Go?
package main
import "fmt"
func main() {
fmt.Println("Hello, playground")
type FullUser struct {
UserName string
UserEmail string
}
manyFullUsers := []FullUser{{"foo", "foo@jawohl.com"},
{"bar", "bar@jawohl.com"},
{"baz", "baz@jawohl.com"}}
type SimpleUser struct {
UserName string
}
manySimpleUsers := []SimpleUser{{"foo"}, {"bar"}}
fmt.Println(manyFullUsers)
fmt.Println(manySimpleUsers)
}
答案1
得分: 11
创建一个地图,然后使用它进行过滤。
func filterByUserName(fu []FullUser, su []SimpleUser) (out []FullUser) {
f := make(map[string]struct{}, len(su))
for _, u := range su {
f[u.UserName] = struct{}{}
}
for _, u := range fu {
if _, ok := f[u.UserName]; ok {
out = append(out, u)
}
}
return
}
英文:
Create a map then use it to filter.
func filterByUserName(fu []FullUser, su []SimpleUser) (out []FullUser) {
f := make(map[string]struct{}, len(su))
for _, u := range su {
f[u.UserName] = struct{}{}
}
for _, u := range fu {
if _, ok := f[u.UserName]; ok {
out = append(out, u)
}
}
return
}
答案2
得分: 1
你可以使用我创建的 https://github.com/ledongthuc/goterators 中的 Filter() 和 Exist() 函数来重用聚合和转换函数。
filteredFullUsers := goterators.Filter(manyFullUsers, func(item FullUser) bool {
return !goterators.Exist(manySimpleUsers, SimpleUser{item.UserName})
})
你还可以从 manySimpleUsers 构建一个映射,这将有助于优化搜索用户名。
这个库需要 Go 1.18 版本以支持你想要使用的泛型和动态类型。
英文:
you can use Filter() and Exist() from https://github.com/ledongthuc/goterators that I created to reuse aggregate & transform functions.
filteredFullUsers := goterators.Filter(manyFullUsers, func(item FullUser) bool {
return !goterators.Exist(manySimpleUsers, SimpleUser{item.UserName})
})
You also can build a map from manySimpleUsers that will be helpful to optimize searching username.
This lib requires the Go 1.18 to use that support generic + dynamic type you want to use with.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论