如何用struct过滤[]struct?

How to filter []struct with struct?

我这样定义结构:

type Repo struct {
    Key         string `json:"key"`
    Type        string `json:"type"`
    PackageType string `json:"packageType"`
}

而json数据类似于

[ { "key":"docker-sre", "type":"LOCAL", "packageType":"Docker" }, { "key":"docker-test", "type":"REMOTE", "packageType":"Docker" }, { "key":"go-local-dev", "type":"LOCAL", "packageType":"Go" }, { "key":"helm-cloudops", "type":"LOCAL", "packageType":"Helm" } ]

在不同条件下获取正确数据的最佳方法是什么?

func getWantedRepos(conf Repo) ([]Repo, error) {}

func main() {
    getWantedRepos(Repo{
        PackageType: "Docker",
    })

    getWantedRepos(Repo{
        Type: "LOCAL",
        PackageType: "Go",
    })
}

您可以使用 reflect 内置包来完成此操作。这是示例:

main.go

package main

import (
    "fmt"
    "reflect"
)

type Repo struct {
    Key         string `json:"key"`
    Type        string `json:"type"`
    PackageType string `json:"packageType"`
}

var someDatas = []Repo{
    {
        Key:         "test",
        Type:        "test",
        PackageType: "test",
    },
    {
        Key:         "test1",
        Type:        "test1",
        PackageType: "test1",
    },
    {
        Key:         "test",
        Type:        "LOCAL",
        PackageType: "test23",
    },
}

func getWantedRepos(conf map[string]interface{}) []Repo {
    var returned []Repo
    for _, val := range someDatas {
        flag := true
        for k := range conf {
            if !reflect.DeepEqual(reflect.ValueOf(val).FieldByName(k).Interface(), conf[k]) {
                flag = false
                break
            }
        }
        if flag {
            returned = append(returned, val)
        }
    }

    return returned
}

func main() {
    var repos []Repo
    repos = getWantedRepos(map[string]interface{}{
        "Key": "test",
    })

    fmt.Println("1 ============================")
    fmt.Printf("%+v\n", repos)

    repos = getWantedRepos(map[string]interface{}{
        "Type": "LOCAL",
    })
    fmt.Println("2 ============================")
    fmt.Printf("%+v\n", repos)

    repos = getWantedRepos(map[string]interface{}{
        "Type":        "LOCAL",
        "PackageType": "test23",
    })
    fmt.Println("3 ============================")
    fmt.Printf("%+v\n", repos)

    repos = getWantedRepos(map[string]interface{}{
        "Type":        "LOCAL",
        "PackageType": "NONE",
    })
    fmt.Println("4 ============================")
    fmt.Printf("%+v\n", repos)
}

Output:

1 ============================
[{Key:test Type:test PackageType:test} {Key:test Type:LOCAL PackageType:test23}]
2 ============================
[{Key:test Type:LOCAL PackageType:test23}]
3 ============================
[{Key:test Type:LOCAL PackageType:test23}]
4 ============================
[]

我使用 map[string]interface{} 而不是模型过滤,因为如果您使用模型,例如使用 string 属性,string 的默认值为“”。即使您没有初始化属性的值,它也会将“”作为默认值,并且 reflect for 循环将扫描并尝试将模型与空字符串“”匹配,以避免出现这种情况,我使用 map[string]interface 所以我们可以更灵活地 select 我们想要的属性,反之亦然。

我不知道你有什么测试用例,但如果你从数据库中获取数据,请尝试使用 WHERE 而不是这样做。