AbhiSam
AbhiSam

Reputation: 105

How to filter slice of struct using filter parameter in GO

I am new to GOlang, I trying to filter slice of struct in GO using struct which contain some parameter for filter it. I am trying to do below things but its not work for me. In that code I have filter function which take slice of struct i.e GRN which need to filter using FilterParameter struct.

My Struct which need to filer

type GRN struct {
        DocType          string    `json:"docType"`
        GRNNO            string    `json:"GRNNO"`
        PRID             string    `json:"PRID"`
        PRODUCE          string    `json:"PRODUCE"`
        VARIETY          string    `json:"VARIETY"`
}


manyGRNUsers := []GRN{{"GRNAsset","GRN0000109","PRFAINAPKR0086","Sweetcorn","CP2"},
    {"GRNAsset","GRN0000110","PRFAINAPKR0087","Sweetcorn","CP1",},
    {"GRNAsset","GRN0000112","PRFAINAPKR0087", "Sweetcorn","CP2",},
    {"GRNAsset","GRN0000113","PRFAINAPKR0089","Apple","Gala",}}

Struct which will used for filter parameter.here one thing the field in FilterParameter is dyanamic as above GRN struct value. it could me more then two field but less than or equal to GRN struct field

  type FilterParameter struct {
        PRODUCE            string    `json:"PRODUCE"`
        VARIETY          string    `json:"VARIETY"`
    
    }

manyFilterParameter := []FilterParameter{{"Sweetcorn","CP2" }

I tried below function but its not work for me as I can do only with one field from FilterParameter i.e PRODUCE only and its not dynamic

   func filter(fu []GRN, su []FilterParameter) (out []GRN) {
        f := make(map[string]struct{}, len(su))
        for _, u := range su {
            f[u.PRODUCE] = struct{}{}
        }
        for _, u := range fu {
            if _, ok := f[u.PRODUCE]; ok {
                out = append(out, u)
            }
        }
        return
    }

Upvotes: 0

Views: 5827

Answers (1)

Zombo
Zombo

Reputation: 1

You can't really do what you're trying to do, as it's not possible to iterate the fields of a struct (maybe with reflection). For another approach, you could use maps instead of structs, or even easier, if you can just explicitly use the fields you care about in the function parameters:

package main
import "fmt"
type GRN struct { DocType, GRNNO, PRID, PRODUCE, VARIETY string }

func filter(in []GRN, produce, variety string) []GRN {
   var out []GRN
   for _, each := range in {
      if each.PRODUCE == produce && each.VARIETY == variety {
         out = append(out, each)
      }
   }
   return out
}

func main() {
   manyGRNUsers := []GRN{
      {"GRNAsset","GRN0000109","PRFAINAPKR0086","Sweetcorn","CP2"},
      {"GRNAsset","GRN0000110","PRFAINAPKR0087","Sweetcorn","CP1"},
      {"GRNAsset","GRN0000112","PRFAINAPKR0087", "Sweetcorn","CP2"},
      {"GRNAsset","GRN0000113","PRFAINAPKR0089","Apple","Gala"},
   }
   out := filter(manyGRNUsers, "Sweetcorn", "CP2")
   fmt.Println(out)
}

Upvotes: 2

Related Questions