Home  >  Article  >  Backend Development  >  How to Unmarshal a Struct with a Map of Slices into a Map of Slices in Go?

How to Unmarshal a Struct with a Map of Slices into a Map of Slices in Go?

Barbara Streisand
Barbara StreisandOriginal
2024-10-28 04:58:30967browse

How to Unmarshal a Struct with a Map of Slices into a Map of Slices in Go?

Custom Unmarshaling a Struct into a Map of Slices

In Go, custom unmarshaling can be employed when the default unmarshaling behavior does not suffice. Consider the following scenario: a struct with a map field that needs to be populated from a JSON object with dynamic keys.

Example Issue

The provided code demonstrates an attempt to unmarshal a JSON response into a struct containing a map of slice structs (Pair map[string][]Candles). However, the map remains empty after unmarshaling.

Solution: Opting for a Simpler Structure

A straightforward solution is to eliminate the map and modify the struct to align with the JSON structure:

<code class="go">type OHLC_RESS struct {
    Pair []Candles `json:"XXBTZUSD"`
    Last int64     `json:"last"`
}</code>

Custom Unmarshaling Using JSON.Unmarshaler

Alternatively, to preserve the map-based structure, custom implementation of the json.Unmarshaler interface is required. This approach provides complete control over the unmarshaling process.

Implementation Details:

  1. Decode the JSON object's keys into non-decoded JSON values.
  2. Identify the "last" element and if present, decode it into the Last field.
  3. Declare the Pair map and iterate through the remaining elements in the JSON object, decoding them into the map.

Code Snippet:

<code class="go">func (r *OHLC_RESS) UnmarshalJSON(d []byte) error {
    // Decode keys only.
    var obj map[string]json.RawMessage
    if err := json.Unmarshal(d, &obj); err != nil {
        return err
    }

    // Decode "last" element.
    if last, ok := obj["last"]; ok {
        if err := json.Unmarshal(last, &r.Last); err != nil {
            return err
        }
        delete(obj, "last")
    }

    // Decode remaining elements into Pair map.
    r.Pair = make(map[string][]Candles, len(obj))
    for key, val := range obj {
        cc := []Candles{}
        if err := json.Unmarshal(val, &cc); err != nil {
            return err
        }
        r.Pair[key] = cc
    }
    return nil
}</code>

The above is the detailed content of How to Unmarshal a Struct with a Map of Slices into a Map of Slices in Go?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn