douzongluo7542 2016-09-24 21:22
浏览 34
已采纳

具有多个参数的过滤器结构

I have an array of a struct and a maps with variable name and some filter values. I want to filter my array with my maps.

Example Go Playground:

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)
   }
}

What is the best way to filter my data with dynamic filter (Represente here by a map of string)?

  • 写回答

1条回答 默认 最新

  • donglue8180 2016-09-25 09:32
    关注

    Using golang package reflect in this particular case will be the best.

    reflect will get you the fields of the struct and you can iterate over them comparing the values with the corresponding filter value.

    The example is specific to the struct that you provided, but you can easily modify it to apply to all structs, again using reflection.

    Example: Go Playground

    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)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示