0

I do not know how to ask, so i will ask with an example.

I have some data like that

{
..
    "velocityStatEntries":  {

    "8753":  {

        "estimated":  {"value":  23.0,"text":  "23.0"},

        "completed":  {"value":  27.0,"text":  "27.0"}
    },

    "8673":  {

        "estimated":  {"value":  54.5,"text":  "54.5"},

        "completed":  {"value":  58.5,"text":  "58.5"}
    },
    .
    .
    .

    }
..
}

I want to declare a type that takes map key to its "KEY" or any property that is given by me. Is it possible without using map iteration?

Expected output:

{...
   "velocityStatEntries": {
   {
     "key": "8753",
     "estimated":  {"value":  54.5,"text":  "54.5"},
     "completed":  {"value":  58.5,"text":  "58.5"}
   },
   {
     "key": "8673",
     "estimated":  {"value":  54.5,"text":  "54.5"},
     "completed":  {"value":  58.5,"text":  "58.5"}
   },
  }
...
}

This is what i have done

type VelocityStatEntry struct {
    Key string
    Estimated struct {
        Value float64 `json:"value"`
        Text  string  `json:"text"`
    } `json:"estimated"`
    Completed struct {
        Value float64 `json:"value"`
        Text  string  `json:"text"`
    } `json:"completed"`
}

type RapidChartResponse struct {
    ...
    VelocityStatEntries map[string]VelocityStatEntry `json:"velocityStatEntries"`
    ..
}

But it is not working. I want to take that string map key to KEY property.

0

1 Answer 1

3

If the data originates from JSON then you should skip the map[string]interface{} and instead use a custom unmarshaler implemented by your desired struct that does what you want. Perhaps by utilizing a map[string]json.RawMessage. But map[string]interface{} to struct conversion is a pain, avoid it if possible.

For example:

type VelocityStatEntryList []*VelocityStatEntry

func (ls *VelocityStatEntryList) UnmarshalJSON(data []byte) error {
    var m map[string]json.RawMessage
    if err := json.Unmarshal(data, &m); err != nil {
        return err
    }
    for k, v := range m {
        e := &VelocityStatEntry{Key: k}
        if err := json.Unmarshal([]byte(v), e); err != nil {
            return err
        }
        *ls = append(*ls, e)
    }
    return nil
}

https://go.dev/play/p/VcaW_BWXRVr

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.