Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering a slice of structs based on a different slice in Golang

Tags:

go

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)
}
like image 539
pardonmemiss Avatar asked Sep 30 '15 13:09

pardonmemiss


2 Answers

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

like image 196
OneOfOne Avatar answered Oct 26 '22 11:10

OneOfOne


you can use Filter() and Exist() from https://github.com/ledongthuc/goterators that I created to reuse aggregate & transform functions.

enter image description here

    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.

like image 36
Le Dong Thuc Avatar answered Oct 26 '22 10:10

Le Dong Thuc