Go: Convert Strings Array to Json Array String - json

Trying to convert a strings array to a json string in Go. But all I get is an array of numbers.
What am I missing?
package main
import (
"fmt"
"encoding/json"
)
func main() {
var urls = []string{
"http://google.com",
"http://facebook.com",
"http://youtube.com",
"http://yahoo.com",
"http://twitter.com",
"http://live.com",
}
urlsJson, _ := json.Marshal(urls)
fmt.Println(urlsJson)
}
Code on Go Playground: http://play.golang.org/p/z-OUhvK7Kk

By marshaling the object, you are getting the encoding (bytes) that represents the JSON string. If you want the string, you have to convert those bytes to a string.
fmt.Println(string(urlsJson))

Another way is to use directly os.Stdout.Write(urlsJson)

You could use stdout output encoder:
package main
import (
"encoding/json"
"os"
)
func main() {
json.NewEncoder(os.Stdout).Encode(urls)
}
or a string builder:
package main
import (
"encoding/json"
"strings"
)
func main() {
b := new(strings.Builder)
json.NewEncoder(b).Encode(urls)
print(b.String())
}
https://golang.org/pkg/encoding/json#NewEncoder

Related

Escape unicode characters in Go JSON so the output matches Python

In Python 2.7, if I encode JSON I get unicode-escaped strings:
>>> import json
>>> s = {"text": "三杯雞"}
>>> print(json.dumps(s))
it gives this output:
{"text": "\u4e09\u676f\u96de"}
But in Go, similar code:
package main
import (
"encoding/json"
"fmt"
)
type Food struct {
Name string `json:"name"`
}
func main() {
food := Food{Name: "三杯雞"}
v, _ := json.Marshal(food)
fmt.Println(string(v))
}
Gives this:
{"name":"三杯雞"}
The Chinese characters are not escaped. I am porting API endpoints from Python to Go - how can I get it to have the same escaped output as Python?
I tried variations using strconv.QuoteToASCII, but they result in the unicode being double-escaped:
func main() {
s := strconv.QuoteToASCII("三杯雞")
s = strings.Trim(s, "\"")
food := Food{Name: s}
v, _ := json.Marshal(food)
fmt.Println(string(v))
}
Outputs:
{"name":"\\u4e09\\u676f\\u96de"}
One solution is to use the strconv.QuoteToASCII method inside of a custom JSON marshaler:
package main
import (
"encoding/json"
"fmt"
"strconv"
)
type Food struct {
Name utf8String `json:"name"`
}
type utf8String string
func (s utf8String) MarshalJSON() ([]byte, error) {
return []byte(strconv.QuoteToASCII(string(s))), nil
}
func main() {
food := Food{Name: utf8String("三杯雞")}
v, _ := json.Marshal(food)
fmt.Println(string(v))
}
Output:
{"name":"\u4e09\u676f\u96de"}
This has the drawback that you can't use a plain string type in the struct definition, but the final output is ASCII-quoted, just like in Python.

golang convert array of interfaces to strings

I read JSON data from a remote source and convert it to a map. There's some array in the data of which I want to examine the string values. After converting I think m["t"] is an array of interfaces. fmt.Print converts this to printed text on the console but I cannot figure a way to do a simple string comparison like
if val[0] == "str-c" {fmt.Println("success")}
How do I iterate through that and do string comparisons?
package main
import (
"fmt"
"encoding/json"
)
func main() {
var m map[string]interface{}
sJSON := `{"k": "v", "t":["str-a","str-b","str-c"]}`
_ = json.Unmarshal([]byte(sJSON),&m)
// find out if one of the string values of "t" is "str-b"
fmt.Println(m["t"])
}
m["t"] is of type interface{} and is the full array, if you wanted to get str-b it is at index one and you have to do some type assertion to get it as a string. Here's an example; https://play.golang.org/p/W7ZnMgicc7
If you want to check for it in the collection that would look like this;
package main
import (
"fmt"
"encoding/json"
)
func main() {
var m map[string]interface{}
sJSON := `{"k": "v", "t":["str-a","str-b","str-c"]}`
_ = json.Unmarshal([]byte(sJSON),&m)
// find out if one of the string values of "t" is "str-b"
for _, v := range m["t"].([]interface{}) {
if v.(string) == "str-b" {
fmt.Println("match found!")
}
}
//fmt.Println(m["t"].([]interface{})[1].(string))
}
https://play.golang.org/p/vo_90bKw92
If you want to avoid this 'unboxing' stuff, which I would recommend you do, you could instead define a struct to unmarshal into, itwould look like this;
type MyStruct struct {
K string `json:"k"`
T []string `json:"t"`
}
Then you can just range over T without any type assertions and do the compare, working example here; https://play.golang.org/p/ehPxOygGf5

How to unmarshal json in golang when left part is a number

I'd like to unmarshal a json like this in the code. But this code doesn't work. Any suggestions? Thx!
PS. playground here http://play.golang.org/p/m2f94LY_d_
package main
import "encoding/json"
import "fmt"
type Response struct {
Page int
One string "1"
}
func main() {
in := []byte(`{"page":1, "1":"this is 1"}`)
res := &Response{}
json.Unmarshal(in, &res)
fmt.Println(res)
}
You need to tell the json library what the json field names are:
type Response struct {
Page int `json:"page"`
One string `json:"1"`
}
Live: http://play.golang.org/p/CNcvQMqBGD

How do I parse JSON in golang?

I tried to "Unmarshal" json in golang, but it doesn't seem to be working.
I get 0 printed out instead of 1. What am I doing wrong?
package main
import (
"fmt"
"encoding/json"
)
type MyTypeA struct {
a int
}
func main() {
var smthng MyTypeA
jsonByteArray := []byte(`{"a": 1}`)
json.Unmarshal(jsonByteArray, &smthng)
fmt.Println(smthng.a)
}
Two problems with your code.
You need to export fields or Marshal won't work, read about it here.
Your package must be called main or func main won't be executed.
http://play.golang.org/p/lJixko1QML
type MyTypeA struct {
A int
}
func main() {
var smthng MyTypeA
jsonByteArray := []byte(`{"a": 1}`)
json.Unmarshal(jsonByteArray, &smthng)
fmt.Println(smthng.A)
}

Marshall and UnMarshall JSON Content in GoLang

I have a sample json file which is structured like this
{
"method":"brute_force",
"bc":"select * from blah;",
"gc":[
"select sum(year) from blah;",
"select count(*) from table;"
]
}
I am trying to write a go program which can read this file and operate of json content.
package main
import (
"fmt"
"encoding/json"
"io/ioutil"
)
type Response2 struct {
method string
bc string
gc []string
}
func main() {
file,_ := ioutil.ReadFile("config.json")
fmt.Printf("%s",string(file))
res := &Response2{}
json.Unmarshal([]byte(string(file)), &res)
fmt.Println(res)
fmt.Println(res.method)
fmt.Println(res.gc)
}
res.method and res.gc dont print anything. I have no idea on whats going wrong.
type Response2 struct {
method string
bc string
gc []string
}
The name of the fields Must be Uppercase otherwise the Json module can't access them (they are private to your module).
You can use the json tag to specify a match between Field and name
type Response2 struct {
Method string `json:"method"`
Bc string `json:"bc"`
Gc []string `json:"gc"`
}