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", "[email protected]"},
{"bar", "[email protected]"},
{"baz", "[email protected]"}}
type SimpleUser struct {
UserName string
}
manySimpleUsers := []SimpleUser{{"foo"}, {"bar"}}
fmt.Println(manyFullUsers)
fmt.Println(manySimpleUsers)
}
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
}
playground
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With