11

I'm struggling to get the keys and values of the following interface, which is the result of JSON marshaling the result returned by Execute as demonstrated in this example:

[
    [
        {
            "id": 36,
            "label": "TestThing",
            "properties": {
                "schema__testBoolean": [
                    {
                        "id": 40,
                        "value": true
                    }
                ],
                "schema__testInt": [
                    {
                        "id": 39,
                        "value": 1
                    }
                ],
                "schema__testNumber": [
                    {
                        "id": 38,
                        "value": 1.0879834
                    }
                ],
                "schema__testString": [
                    {
                        "id": 37,
                        "value": "foobar"
                    }
                ],
                "uuid": [
                    {
                        "id": 41,
                        "value": "7f14bf92-341f-408b-be00-5a0a430852ee"
                    }
                ]
            },
            "type": "vertex"
        }
    ]
]

A reflect.TypeOf(result) results in: []interface{}.

I've used this to loop over the array:

s := reflect.ValueOf(result)
for i := 0; i < s.Len(); i++ {
  singleVertex := s.Index(i).Elem() // What to do here?
}

But I'm getting stuck with errors like:

reflect.Value.Interface: cannot return value obtained from unexported field or method

3
  • If there is no requirement to use reflection then you should avoid it and loop over the []interface{}. Commented Jul 4, 2018 at 11:28
  • So, I would only use reflection if I don't know the structure? Commented Jul 4, 2018 at 11:32
  • @BobvanLuijt: Basically. Commented Jul 4, 2018 at 11:33

2 Answers 2

13

If you know that's your data structure, there's no reason to use reflection at all. Just use a type assertion:

for key, value := range result.([]interface{})[0].([]interface{})[0].(map[string]interface{}) {
    // key == id, label, properties, etc
}
Sign up to request clarification or add additional context in comments.

Comments

7

For getting the underlying value of an interface use type assertion. Read more about Type assertion and how it works.

package main

import (
    "fmt"
)

func main() {
     res, err := g.Execute( // Sends a query to Gremlin Server with bindings
           "g.V(x)",
            map[string]string{"x": "1234"},
            map[string]string{},
     )
     if err != nil {
          fmt.Println(err)
          return
     }
     fetchValue(res)
}

func fetchValue(value interface{}) {
    switch value.(type) {
    case string:
        fmt.Printf("%v is an interface \n ", value)
    case bool:
        fmt.Printf("%v is bool \n ", value)
    case float64:
        fmt.Printf("%v is float64 \n ", value)
    case []interface{}:
        fmt.Printf("%v is a slice of interface \n ", value)
        for _, v := range value.([]interface{}) { // use type assertion to loop over []interface{}
            fetchValue(v)
        }
    case map[string]interface{}:
        fmt.Printf("%v is a map \n ", value)
        for _, v := range value.(map[string]interface{}) { // use type assertion to loop over map[string]interface{}
            fetchValue(v)
        }
    default:
        fmt.Printf("%v is unknown \n ", value)
    }
}

3 Comments

It is just an example my main concern was to unmarshal and then use type assertion to get the underlying value. I m just using recursion to get the value of slice of interface{}. I have used json as an example Since OP has given the json in his question.
The OP has explained that his result variable is the output of the Execute method, which does not return, nor consume, JSON. Perhaps the data in the database is stored as JSON, but it is not accessible in that form via the Go client library, so answering with json.Unmarshal is a non-answer.
Ok but using recursion to fetch the value of slice of interface{} can be done in any case. So I am edited my answer according to you thanks for infromation.

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.