0

Input:

"data": {
    "filter": [
        "["EQ","foo",0],["LIKE","baz","%.2%"],["IN","bar",[1,5,9,11]],["EQ","myBool",true]"
    ],
    "limit": [
        "101"
    ],
    "offset": [
        "0"
    ],
    "sort": [
        "id:ASC"
    ]
}

Struct:

type MyStruct struct {
    Operator string
    Field    string
    Values   []interface{} //this could be an array of strings or int64
}

Test Code:

var parsed [][]interface{}
var parsedValues []MyStruct

    if err := json.Unmarshal([]byte(filters), &parsed); err != nil {
        fmt.Println("FAILED TO UNMARSHALL FILTERS : " + err.Error())
    }

    for _, y := range parsed {
        var myStuff MyStruct
        var values []interface{}
        for idx2, col := range y {
            if idx2 == 0 {
                myStuff.Operator = col.(string)
            } else if idx2 == 1 {
                myStuff.Field = col.(string)
            } else {
                values = append(values, col)
            }
        }
        myStuff.Values = values
        parsedValues = append(parsedValues, criteria)
    }

EDITED:

I am hitting an error in un marshaling.

FAILED TO UNMARSHALL FILTERS : invalid character ',' after top-level value

Is it expected that the commas between arrays in this string will mess up the parse? I tried to do a replace to remove commas between each sub array ... but ... now it just yells about the [.

Maybe this is the wrong approach altogether. I thought the answer below was going to work but with my input it didnt. I am not 100% sure where the disconnect is.

Any help with this would be appreciated.

2
  • Your test code doesn't use MySearchCriteria. What is GormStringSearchCriteria? If it is something that has its own json unmarshal method, and if it expects strings (which is what it looks like from its name), then the last element in the array you're unmarshaling will fail because it is a number. Commented Nov 9, 2019 at 5:21
  • Updated the code bit in the example to use MySearchCriteria Commented Nov 9, 2019 at 6:28

1 Answer 1

1

It appears like you're trying to unmarshal:

["IN","id", 342]

into

type MySearchCriteria struct {
    Operator string
    Field    string
    Values   []interface{} //this could be an array of strings or int64
}

Is your expectation for unmarshal is to populate the fields of the struct in order? If so, that's not going to work.

To unmarshal that JSON array, you have to use an array:

var flt []interface{}
json.Unmarshal(b, &flt)

Then you can do:

operator:=flt[0].(string)
field:=flt[1].(string)
inumbers:=make([]int64,0)
strvalues:=make([]string,0)
for i:=2;i<len(flt);i++ {
    if number, ok:=flt[i].(float64); ok {
         inumbers=append(inumbers,int64(number))
    } else if str, ok:=flt[i].(string); ok {
         strvalues=append(strvalues,str)
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Take into account for a moment that the input structure is technically setup to be an array or string arrays like so: "[\"IN\",\"id\", 342],[\"IN\",\"foo\", \"bar\"],[\"EQ\",\"id2\", 342]" How does that change your response ?
Your original code already handles that. The for loop with range v will process each element of filter. The code I have in my answer applies to one such element. You can process each string to build a MySearchCriteria instance, and append it to an array
I think this is close .... I updated the code above to reflect what I am trying to do now. I guess eventually I can deal with typing the Values portion of my struct but i really dont care at this stage. I just need to get them into the correct objects.
You need to escape those quotes in the filter string. Once you do that, it is an array of strings, so [][]interface{} won't do. Also, in that string you're expecting an array of strings and numbers, so a nested array won't do either. It should be ["IN","bar",1,5,9,11]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.