我有一个结构数组和一个带有变量名和一些过滤值的地图。 我想用我的地图过滤我的数组。
package main
import "fmt"
type cnts []cnt
type cnt struct {
ID int `json:"Id"`
Area string `json:"Area"`
State string `json:"State"`
City string `json:"City"`
}
func main() {
mycnts := cnts{
cnt{124, "Here", "South", "Home"},
cnt{125, "Here", "West", "Home"},
cnt{126, "", "South", "Home"},
cnt{127, "Here", "West", "NY"}}
// my maps with filter
mapFilter := map[string]string{"Area": "Here", "City": "Home"}
fmt.Println(mapFilter)
mycntsFilter := make(cnts, 0)
for _, val := range mycnts {
// I want to select only row where the map filter it's ok
mycntsFilter = append(mycntsFilter, val)
fmt.Println(val, mycntsFilter)
}
}
使用动态过滤器过滤数据的最佳方法是什么(这里用字符串映射表示)?
答案 0 :(得分:1)
在这种特殊情况下使用golang包反映将是最好的。
反射会为您提供结构的字段,您可以进行迭代 将它们与相应的过滤值进行比较。
示例对您提供的结构具体,但您可以使用反射轻松将其修改为应用于所有结构。
package main
import (
"fmt"
"reflect"
)
type cnts []cnt
type cnt struct {
ID int `json:"Id"`
Area string `json:"Area"`
State string `json:"State"`
City string `json:"City"`
}
// Filtering function
func filterItem(val *cnt, filter map[string]string) bool {
item := reflect.ValueOf(val).Elem()
itemType := item.Type()
isValid := true
// Iterate over the struct fileds
for i := 0; i < item.NumField(); i++ {
field := item.Field(i)
filterValue, ok := filter[itemType.Field(i).Name]
if ok {
// filter out
if filterValue != field.Interface() {
isValid = false
break
}
}
}
return isValid
}
func main() {
mycnts := cnts{
cnt{124, "Here", "South", "Home"},
cnt{125, "Here", "West", "Home"},
cnt{126, "", "South", "Home"},
cnt{127, "Here", "West", "NY"}}
// my maps with filter
mapFilter := map[string]string{"Area": "Here", "City": "Home"}
fmt.Println(mapFilter)
mycntsFilter := make(cnts, 0)
for _, val := range mycnts {
if filterItem(&val, mapFilter) {
mycntsFilter = append(mycntsFilter, val)
}
}
fmt.Println(mycntsFilter)
}