2

I have a sample as below,

result = [{"Key":"9802", "Record":{"action":"Warning","status":"Created","statusid":"9802","system":"CRM","thresholdtime":"9"}}]

how can i access thresholdtime value in go lang?

I'm trying to display like this: result[0]["Record"]["thresholdtime"]

error:  invalid operation: result[0]["Record"] (type byte does not support indexing)

Thanks

1
  • 3
    What have you tried so far? Why doesn't it work? Commented Sep 20, 2018 at 21:01

3 Answers 3

2

The json.Unmarshal(...) Example should get you started.

Here's one way to do it (Go Playground):

func main() {
  var krs []KeyRecord
  err := json.Unmarshal([]byte(jsonstr), &krs)
  if err != nil {
    panic(err)
  }

  fmt.Println(krs[0].Record.ThresholdTime)
  // 9
}

type KeyRecord struct {
  Key    int    `json:"Key,string"`
  Record Record `json:"Record"`
}

type Record struct {
  Action        string `json:"action"`
  Status        string `json:"status"`
  StatusId      int    `json:"statusid,string"`
  System        string `json:"system"`
  ThresholdTime int    `json:"thresholdtime,string"`
}

var jsonstr = `
[
  {
    "Key": "9802",
    "Record": {
      "action": "Warning",
      "status": "Created",
      "statusid": "9802",
      "system": "CRM",
      "thresholdtime": "9"
    }
  }
]
`

You can unmarshal the JSON document into a generic type; however, it's not recommended for many reasons, ultimately related to loss of type information:

xs := []map[string]interface{}{}
err := json.Unmarshal([]byte(jsonstr), &xs)
if err != nil {
    panic(err)
}

ttstr := xs[0]["Record"].(map[string]interface{})["thresholdtime"].(string)
fmt.Printf("%#v\n", ttstr) // Need to convert to int separately, if desired.
// "9"
Sign up to request clarification or add additional context in comments.

3 Comments

ohh yeahhhh i missed unmarshal
is it possible to access without creating data structures?
When i use the generic one im getting below error:no new variables on left side of :=
0

Something like this should get you pretty close i think: https://play.golang.org/p/ytpHTTNMjB-

Use the built-in json package to decode your data into structs (with attached json tags). Then its as simple as accessing a struct field.

1 Comment

But his original result is an array
0

Use json.Unmarshal to unmarshal the data into a suitable data type. In many instances, you can (and I would recommend) using custom-declared struct types with json tags for this purpose.

However, to your comment on another answer, it is possible to unmarshal into an interface{} and have the unmarshaller determine the most suitable data type to represent the JSON structure. For example, a slice of []interface{} type will represent a list, a map of map[string]interface{} a dictionary, primitive types for their equivalent JSON, etc.

I wrote a parser which uses this approach for another Stack question last week. This does not intend to be high-performance or highly tested code, but demonstrates the key points:

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "reflect"
    "strconv"
    "strings"
)

// Some arbitrary JSON
const js = `
{
  "key1": [
    {"key2": false, "some_other_key": "abc"},
    {"key3": 3}
  ],
  "key2": {
    "hello": "world"
  },
  "shallow": true,
  "null_value": null
}`

func indentStringLines(s string, n int) string {
    // Build indent whitespace - this has not been optimized!
    var indent string
    for i := 0; i < n; i++ {
        indent += " "
    }

    parts := strings.Split(s, "\n")
    for i := 0; i < len(parts) - 1; i++ {
        parts[i] = indent + parts[i]
    }
    return strings.Join(parts, "\n")
}

func recursivelyPrintSlice(m []interface{}, indent int) string {
    var str string
    for i, val := range m {
        str += fmt.Sprintf("%s: %s\n",
            strconv.FormatInt(int64(i), 10),
            recursivelyPrint(val, indent),
        )
    }
    return strings.TrimSpace(str)
}

func recursivelyPrint(val interface{}, indent int) string {
    var str string

    switch v := val.(type) {
    case bool:
        str += strconv.FormatBool(v)
    case float64:
        str += strconv.FormatFloat(v, 'g', -1, 64)
    case string:
        str += v
    case map[string]interface{}:
        str += "{\n"
        for key, childVal := range v {
            str += fmt.Sprintf("%s: %s\n", key, recursivelyPrint(childVal, indent))
        }
        str += "}"
    case []interface{}:
        str += "[\n" + recursivelyPrintSlice(v, indent) + "\n]"
    case nil:
        str += "null"
    default:
        str += fmt.Sprintf(
            "[unimplemented type printer for %s]",
            reflect.ValueOf(v).Kind(),
        )

    }
    return strings.TrimSpace(indentStringLines(str, indent+2))
}

func main() {
    var x interface{}
    err := json.Unmarshal([]byte(js), &x)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(recursivelyPrint(x, 0))
}

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.