Unmarshal JSON-строка в массив с интерфейсом - PullRequest
0 голосов
/ 09 ноября 2019

Ввод:

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

Структура:

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

Код теста:

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

РЕДАКТИРОВАНИЕ:

У меня ошибкав un marshaling.

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

Ожидается ли, что запятые между массивами в этой строке испортят синтаксический анализ? Я попытался сделать замену, чтобы удалить запятые между каждым вложенным массивом ... но ... теперь он просто кричит о [.

Может быть, это совсем не тот подход. Я думал, что ответ ниже будет работать, но с моим вкладом это не так. Я не уверен на 100%, где отключение.

Любая помощь с этим будет оценена.

1 Ответ

2 голосов
/ 09 ноября 2019

Похоже, вы пытаетесь разархивировать:

["IN","id", 342]

в

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

Ожидаете ли вы, что unmarshal заполнит поля структуры по порядку? Если это так, это не сработает.

Чтобы разобрать этот массив JSON, вы должны использовать массив:

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

Тогда вы можете сделать:

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)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...