Reputation: 1080
I'm parsing a JSON object which contains an array of strings :
var ii interface{}
json := "{\"aString\": [\"aaa_111\", \"bbb_222\"], \"whatever\":\"ccc\"}"
err := json.Unmarshal([]byte(json), &ii)
if err != nil {
log.Fatal(err)
}
data := ii.(map[string]interface{})
fmt.Println(data["aString"]) // outputs: ["aaa_111" "bbb_222"]
I tried to convert data["aString"]
to []string to be able to loop over it, but it fails :
test := []string(data["aString"]).([]string)
fmt.Println(test) // panic -> interface conversion:
// interface is string, not []string
How can I convert data["aString"]
?
I didn't express myself properly. If I print data
, I have such map :
map[aString:["BBB-222","AAA-111"] whatever:ccc]
I want to loop over aString (to manipule each array entry). But I can't find how, because aString is type interface {}
:
for i, v := range aString { // <-- fails
// ...
fmt.Println(i, v)
}
That's why I want to convert aString. I don't want to convert a string which looks like an array to an array.
Upvotes: 20
Views: 43407
Reputation: 1
I'm solving that by just Marshall and Unmarshall:
type Paragraph struct {
Paragraph_id string `json:"paragraph_id"`
Parent_document_id string `json:"parent_document_id"`
Page_in_document int `json:"page_in_document"`
Text string `json:"text"`
Previous_paragraph_id string `json:"previous_paragraph_id"`
Parent_paragraph_id string `json:"parent_paragraph_id"`
Child_paragraph_ids []string `json:"child_paragraph_ids"`
Next_paragraph_id string `json:"next_paragraph_id"`
Summary string `json:"summary"`
Vector []float64 `json:"vector"`
Definitions []string `json:"definitions"`
Keywords []string `json:"keywords"`
IsLeaf bool `json:"leaf"`
}
_, err := session.ExecuteRead(db_ctx, func(transaction neo4j.ManagedTransaction) (any, error) {
result, _:= transaction.Run(db_ctx,
"MATCH (paragraph:Paragraph) RETURN paragraph",
map[string]any{},
)
paragraphs = []Paragraph{}
for result.Next(db_ctx) {
record := result.Record()
para, _ := record.Get("paragraph")
properties := para.(neo4j.Node).GetProperties()
bytes, _ := json.Marshal(properties)
var paragraph knowledge_structs.Paragraph
json.Unmarshal(bytes, ¶graph)
paragraphs = append(paragraphs, paragraph)
}
Not sure how efficient it is ;)
Upvotes: 0
Reputation: 1
For another approach, you can use a struct
instead:
package main
import (
"encoding/json"
"fmt"
)
func main() {
s := []byte(`{"aString": ["aaa_111", "bbb_222"], "whatever":"ccc"}`)
var t struct {
Astring []string
Whatever string
}
json.Unmarshal(s, &t)
fmt.Printf("%+v\n", t) // {Astring:[aaa_111 bbb_222] Whatever:ccc}
}
Upvotes: 0
Reputation: 48086
I recommend you move away from this implementation in general. Your json may vary but you can easily use objects and avoid all this type unsafe nonsense.
Anyway, that conversion doesn't work because the types inside the slice are not string
, they're also interface{}
. You have to iterate the collection then do a type assertion on each item like so:
aInterface := data["aString"].([]interface{})
aString := make([]string, len(aInterface))
for i, v := range aInterface {
aString[i] = v.(string)
}
Upvotes: 48
Reputation: 2668
Is it what you need?
package main
import (
"fmt"
"encoding/json"
)
func main() {
js := "{\"aString\": [\"aaa_111\", \"bbb_222\"], \"whatever\":\"ccc\"}"
a := make(map[string]interface{})
json.Unmarshal([]byte(js), &a)
for _, v := range a["aString"].([]interface{}) {
str := v.(string)
fmt.Println(str)
}
}
Check on Go Playground
Upvotes: 5