Golang json демаршалинг в соответствии с парой ключ-значение

У меня есть json следующим образом

"data": [
    {
        "id": "recent_search",
        "items": [],
        "name": ""
    },
    {
        "id": "popular_search",
        "items": [],
        "name": ""
    },
    {
        "id": "digital",
        "items": [],
        "name": "DIGITAL"
    }
]

и структуры следующие:

type universeTypeData struct {
Recent       universeSearchInfo 
Popular      universeSearchInfo 
Digital      universeSearchInfo 
}

type universeSearchInfo struct {
ID    string               `json:"id"`
Name  string               `json:"name"`
Items []universeSearchItem `json:"items"`
}

Я хочу демаршалировать свой json как «id» со значением «Recent_search», сопоставить его с «Последние», «id» со значением «Popular_search» сопоставить с «Popular». Есть ли способ сделать это в голанге?

Мой подход к этому

for _, v := range result.Data {
    if v.ID == "in_category" {
        finalResult.Universe.InCategory.ID = v.ID
        finalResult.Universe.InCategory.Name = v.Name
        for _, abc := range v.Items {
            finalResult.Universe.InCategory.Items = append(finalResult.Universe.InCategory.Items, abc)
        }
    }
    if v.ID == "recent_search" {
        finalResult.Universe.Recent.ID = v.ID
        finalResult.Universe.Recent.Name = v.Name
        for _, abc := range v.Items {
            finalResult.Universe.Recent.Items = append(finalResult.Universe.Recent.Items, abc)
        }
    }
    if v.ID == "popular_search" {
        finalResult.Universe.Popular.ID = v.ID
        finalResult.Universe.Popular.Name = v.Name
        for _, abc := range v.Items {
            finalResult.Universe.Popular.Items = append(finalResult.Universe.Popular.Items, abc)
        }
    }

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

всегда показывать код, который вы написали, чтобы решить проблему

Scott Stensland 16.07.2018 11:52

@ScottStensland отредактировал вопрос

Aditi Singh 16.07.2018 12:02

Реализуйте интерфейс unmarshaler для синтаксического анализа json для реализации в структуре

Himanshu 16.07.2018 12:02
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
3
3
3 606
2

Ответы 2

Реализуйте интерфейс Unmarshaler:

Unmarshaler is the interface implemented by types that can unmarshal a JSON description of themselves. The input can be assumed to be a valid encoding of a JSON value. UnmarshalJSON must copy the JSON data if it wishes to retain the data after returning.

Интерфейс json unmarshaler присваивает значение из json структуре после анализа результата и применения условий для получения значения.

package main

import (
    "encoding/json"
    "fmt"
)

type Details struct {
    Data []universeSearchInfo `json:"data"`
}

type universeTypeData struct {
    Recent  universeSearchInfo
    Popular universeSearchInfo
    Digital universeSearchInfo
}

type universeSearchInfo struct {
    ID    string   `json:"id"`
    Name  string   `json:"name"`
    Items []string `json:"items"`
}

func main() {
    var result universeTypeData
    jsonBytes := []byte(`{"data": [
                    {
                        "id": "recent_search",
                        "items": [],
                        "name": ""
                    },
                    {
                        "id": "popular_search",
                        "items": [],
                        "name": ""
                    },
                    {
                        "id": "digital",
                        "items": [],
                        "name": "DIGITAL"
                    }
                ]}`)
    if err := json.Unmarshal(jsonBytes, &result); err != nil {
        fmt.Println(err)
    }
    fmt.Println(result)

}

func (universeData *universeTypeData) UnmarshalJSON(data []byte) error {
    var result Details
    if err := json.Unmarshal(data, &result); err != nil {
        return err
    }
    for _,value := range result.Data{
        switch value.ID {
            case "recent_search":
                universeData.Recent = value
        }
    }
    return nil
}

Рабочий код на Перейти на игровую площадку

Вы хотите развернуть массив JSON в структуру Go, что не является естественным отображением. В любом случае, вам, скорее всего, сначала следует развернуть фрагмент, а затем проанализировать этот фрагмент. Некоторым обходным путем является использование json.Decoder

dec := json.NewDecoder(JSONdataReader)
var res universeTypeData
// read open bracket
dec.Token()
// while the array contains values
for dec.More() {
    var m universeSearchInfo
    // decode an array value
    dec.Decode(&m)
    switch m.ID {
    case "recent_search":
        res.Recent = m
    case "popular_search":
        res.Popular = m
    case "digital":
        res.Digital = m
    }
}
// read closing bracket
dec.Token()

которые позволяют декодировать на лету, за один проход, без использования промежуточного представления среза. Рабочий пример

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