Немаршалинг данных Json в карту в Go

Я имею дело с api, который возвращает данные json, такие как:

    {
  "bpi": {
    "2018-06-01": 128.2597,
    "2018-06-02": 127.3648
  },
  "disclaimer": "something here.",
  "time": {
    "updated": "Sep 6, 2013 00:03:00 UTC",
    "updatedISO": "2013-09-06T00:03:00+00:00"
  }

Однако данные о ценах, которые имеют сопутствующие даты, могут возвращать динамический диапазон дат (т.е. может быть что угодно от 1 пары данных до 1000).

Я пытаюсь взять только пары даты и цены и поместить их на карту для дальнейшего использования, но я не нахожу прямого способа сделать это. Когда я помещаю это в генератор автоматической структуры json-to-go, он создает статически именованную структуру для ценообразования.

Это моя лучшая попытка динамической обработки данных. Я передаю пустой интерфейс из тела ответа http get, а именно:

var unstructuredJSON interface{} json.Unmarshal(body, &unstructuredJSON)

и передать неструктурированный JSON в функцию:

func buildPriceMap(unstructuredJSON interface{}, priceMap map[string]float64) {
jsonBody := unstructuredJSON.(map[string]interface{})

for k, v := range jsonBody {
    switch vv := v.(type) {
    case string:
        // Do Nothing
    case float64:
        priceMap[k] = vv
    case interface{}:
        buildPriceMap(vv, priceMap)
    default:
        log.Fatal("Json unknown data handling unmarshal error: ", k, vv)
    }
}

Есть лучший способ это сделать?

Я не совсем понимаю ваш формат ввода. Не могли бы вы привести пару примеров описываемого вами "динамического диапазона дат"?

Flimzy 04.09.2018 09:41

@Flimzy в разделе bpi я могу запросить у api диапазон дат, чтобы это мог быть список данных за 100 дней

Connor 04.09.2018 09:46

Это похоже на простую карту. Есть ли причина, по которой map[string]float64 вам не подходит?

Flimzy 04.09.2018 09:47

Текущий способ, которым у меня это есть, работает для меня, но мне интересно, не буду ли я делать это слишком сложным образом.

Connor 04.09.2018 09:49

Да, метод, который вы используете в своем вопросе, слишком сложен. Если нет сюрпризов, которые вы не описали, просто демаршалируйте структуру с таким полем: BPI map[string]float64

Flimzy 04.09.2018 09:50

Понятно, попробую. Спасибо за вашу помощь!

Connor 04.09.2018 09:51

Ваш JSON не является неструктурированным или динамическим.

Volker 04.09.2018 09:54

JSON не является неструктурированным. JSON - это структура. Если он неструктурирован, это недействительный JSON.

Adrian 04.09.2018 15:27
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
8
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Предполагая, что вы знаете ключи верхнего уровня, например bpi, disclaimer, time и т. д. И что «пары динамических данных», о которых вы говорите, являются частью поля bpi, и что типы ключей и значений каждого из членов bpi всегда являются string: decimal number, вы делаете что-то вроде ... .

type APIResp struct {
    BPI        map[string]float64 `json:"bpi"`
    Disclaimer string
    // other fields
}

Теперь каждая из ваших пар будет набрана правильно и содержаться в карте APIResp.BPI. Unmarshal, как вы уже делаете;

var r APIResp
err := json.Unmarshal(body, &r)
// TODO: check err

Другие вопросы по теме