5

In Go I usually unmarshal my JSON into a struct and read values from the struct.. it works very well.

This time around I am only concerned with a certain element of a JSON object and because the overall JSON object is very large, I don't want to have to create a struct.

Is there a way in Go so that I can lookup values in the JSON object using keys or iterate arrays as per usual.

Considering the following JSON how could I pull out the title field only.

{
  "title": "Found a bug",
  "body": "I'm having a problem with this.",
  "assignee": "octocat",
  "milestone": 1,
  "labels": [
    "bug"
  ]
}
jim
  • 8,670
  • 15
  • 78
  • 149
  • 2
    You can make a struct exclusively for the parts you want. This from the json package under Unmarshal(): *"To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match. Unmarshal will only set exported fields of the struct."* If the field doesn't exist the json key/value pair should simply be ignored. – Snowman Jun 07 '16 at 14:05
  • Ah ok, I thought it would complain about unmatched fields. Thanks. – jim Jun 07 '16 at 14:30

5 Answers5

8

Dont declare fields you dont want.

https://play.golang.org/p/cQeMkUCyFy

package main

import (
    "fmt"
    "encoding/json"
)

type Struct struct {
    Title   string  `json:"title"`
}

func main() {
    test := `{
        "title": "Found a bug",
        "body": "I'm having a problem with this.",
        "assignee": "octocat",
        "milestone": 1,
        "labels": [
          "bug"
        ]
    }`

    var s Struct
    json.Unmarshal([]byte(test), &s)

    fmt.Printf("%#v", s)

}

Or if you want to completely get rid of structs:

var i interface{}
json.Unmarshal([]byte(test), &i)

fmt.Printf("%#v\n", i)
fmt.Println(i.(map[string]interface{})["title"].(string))

Or. It will swallow all conversion errors.

m := make(map[string]string)

json.Unmarshal([]byte(test), interface{}(&m))

fmt.Printf("%#v\n", m)
fmt.Println(m["title"])
Darigaaz
  • 1,414
  • 10
  • 11
1

To extend Darigaaz's answer, you can also use an anonymous struct declared within the parsing function. This avoids having to have package-level type declarations litter the code for single-use cases.

https://play.golang.org/p/MkOo1KNVbs

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    test := `{
        "title": "Found a bug",
        "body": "I'm having a problem with this.",
        "assignee": "octocat",
        "milestone": 1,
        "labels": [
          "bug"
        ]
    }`

    var s struct {
        Title string `json:"title"`
    }
    json.Unmarshal([]byte(test), &s)

    fmt.Printf("%#v", s)

}
Kaedys
  • 9,600
  • 1
  • 33
  • 40
0

Check out go-simplejson

Example:

js, err := simplejson.NewJson([]byte(`{
  "test": {
    "string_array": ["asdf", "ghjk", "zxcv"],
    "string_array_null": ["abc", null, "efg"],
    "array": [1, "2", 3],
    "arraywithsubs": [{"subkeyone": 1},
    {"subkeytwo": 2, "subkeythree": 3}],
    "int": 10,
    "float": 5.150,
    "string": "simplejson",
    "bool": true,
    "sub_obj": {"a": 1}
  }
}`))

if _, ok = js.CheckGet("test"); !ok {
  // Missing test struct
}

aws := js.Get("test").Get("arraywithsubs")
aws.GetIndex(0)
basgys
  • 4,320
  • 28
  • 39
  • Thanks but, imho, this is too trivial a problem to add an external dependency. – jim Jun 08 '16 at 12:17
  • 1
    @conor Of course, it all depends on your needs. I particularly like this library when I have to unit test JSON payloads for instance. But good habit to not add 3rd party libs for small tasks :) – basgys Jun 08 '16 at 12:26
0
package main

import (
    "encoding/json"
    "fmt"
)


type Seller struct {
  Name string
  ShareName string
  Holdings int
  Quantity int
  PerShare float64
}

type Buyer struct {
  Name string
  ShareName string
  Holdings int
  Quantity int
  PerShare float64

}
func validateTransaction(seller Seller,buyer Buyer) bool{         
    var isallowTransact bool =false
    if (seller.Quantity >=buyer.Quantity &&seller.PerShare == buyer.PerShare && seller.ShareName ==buyer.ShareName){
         isallowTransact=true; 
    }  

    return isallowTransact
    }

func executeTransaction(seller Seller,buyer Buyer) {         
       seller.Holdings -=seller.Quantity;
       buyer.Holdings +=seller.Quantity;
    fmt.Printf("seller current holding : %d, \n buyyer current holding: %d",seller.Holdings,buyer.Holdings)

}

func main() {   
    sellerJson :=`{"name":"pavan","ShareName":"TCS","holdings":100,"quantity":30,"perShare":11.11}`
    buyerJson :=`{"name":"Raju","ShareName":"TCS","holdings":0,"quantity":30,"perShare":14.11}`
    var seller Seller 
    var buyer Buyer 
    json.Unmarshal([]byte(sellerJson ), &seller)
    json.Unmarshal([]byte(buyerJson ), &buyer)

    //fmt.Printf("seller name : %s, shares of firm: %s,total holdings: %d, want to sell: %d,unit cost: %f", seller.Name , seller.ShareName,seller.Holdings , seller.Quantity,seller.PerShare )
      var isallowExecute bool =false
    isallowExecute  =validateTransaction(seller,buyer)

    if(isallowExecute){ 
    executeTransaction(seller,buyer)
    }else{
     fmt.Print("\n seems buyer quotes are not matching with seller so we are not able to perform transacrion ,Please check and try again");

    }
    fmt.Println("\n Happy Trading...!!");

    }
pa1 Raju
  • 153
  • 1
  • 7
  • 1
    Hi, while this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. – Dwhitz Mar 18 '19 at 13:31
-3

Update: This answer is wrong; I'm leaving it as an example of what not to do.

You should look it up with a regex then (pseudocode):

String s = {json source};
int i = s.indexOf("\"title\": \"")
s.substring(i,s.indexOf("\"",i))

more on substrings in Java

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Vale
  • 1,104
  • 1
  • 10
  • 29
  • { "body": "here goes \"title\":\"pick me\"", "title": "catch me if you can" } – Darigaaz Jun 07 '16 at 14:08
  • @Darigaaz ? Is that because I'm over complicating a simple solution or a ray of inspiration? – Vale Jun 07 '16 at 14:11
  • Parsing "structured" text like json/html/xml with regex is a bad idea in general. And i gave you an example. – Darigaaz Jun 07 '16 at 14:15
  • Aaaah, I apologize. I won't delete the answer to serve it as an example for the future, risking my reputation nonetheless – Vale Jun 07 '16 at 14:17