如何用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
而不是这样做。
我这样定义结构:
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
而不是这样做。