Я имею дело с 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 в разделе bpi я могу запросить у api диапазон дат, чтобы это мог быть список данных за 100 дней
Это похоже на простую карту. Есть ли причина, по которой map[string]float64 вам не подходит?
Текущий способ, которым у меня это есть, работает для меня, но мне интересно, не буду ли я делать это слишком сложным образом.
Да, метод, который вы используете в своем вопросе, слишком сложен. Если нет сюрпризов, которые вы не описали, просто демаршалируйте структуру с таким полем: BPI map[string]float64
Понятно, попробую. Спасибо за вашу помощь!
Ваш JSON не является неструктурированным или динамическим.
JSON не является неструктурированным. JSON - это структура. Если он неструктурирован, это недействительный JSON.

Предполагая, что вы знаете ключи верхнего уровня, например 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
Я не совсем понимаю ваш формат ввода. Не могли бы вы привести пару примеров описываемого вами "динамического диапазона дат"?