Как извлечь вложенные данные JSON? - PullRequest
0 голосов
/ 23 марта 2019

У меня есть следующее в data.json:

{  
    "table":"orderBook10",
    "action":"update",
    "data":[  
       {  
          "symbol":"XBTUSD",
          "bids":[  
             [  
                3996,
                49137
             ],
             [  
                3995.5,
                116
             ],
             [  
                3995,
                165
             ],
             [  
                3994.5,
                166
             ],
             [  
                3994,
                237
             ],
             [  
                3993.5,
                45
             ],
             [  
                3992,
                20064
             ],
             [  
                3991.5,
                209
             ],
             [  
                3991,
                134
             ],
             [  
                3990.5,
                2948
             ]
          ],
          "timestamp":"2019-03-23T00:34:40.505Z",
          "asks":[  
             [  
                3996.5,
                975
             ],
             [  
                3997,
                289
             ],
             [  
                3997.5,
                334
             ],
             [  
                3998,
                419
             ],
             [  
                3998.5,
                423
             ],
             [  
                3999,
                930
             ],
             [  
                3999.5,
                547
             ],
             [  
                4000,
                538
             ],
             [  
                4000.5,
                703
             ],
             [  
                4001,
                997
             ]
          ]
       }
    ]
 }

Моя программа может извлечь поле data:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
)

func main() {

    dat, err := ioutil.ReadFile("./data.json")
    if err != nil {
        panic(err)
    }

    var ob map[string]interface{}
    if err := json.Unmarshal(dat, &ob); err != nil {
        panic(err)
    }
    fmt.Println(ob["data"])
}

Теперь я хотел бы извлечь вложенное поле «спрашивает».

Я пробовал:

data := ob["data"]
asks := data["asks"].([][]int)

но это приводит к синтаксической ошибке, которую я не могу расшифровать.

Как мне присвоить вложенное поле asks переменной?

Ответы [ 3 ]

1 голос
/ 23 марта 2019

Подход для разбора любого JSON может быть достигнут следующим.

Шаг 1: Определение структур

type OuterJson struct {
  Table string `json:"table"`
  Action string `json:"action"`
  DataJson []DataJson `json:"data"`
}

type DataJson struct {
  Symbol string `json:"symbol"`
  Timestamp string `json:"timestamp"`
  BidsJson [][]float64 `json:"bids"`
  AsksJson [][]float64 `json:"asks"`

}

Шаг 2: Объявление входа и выхода

input := `{"table":"orderBook10","action":"update","data":[{"symbol":"XBTUSD","bids":[[3996,49137],[3995.5,116],[3995,165],[3994.5,166],[3994,237],[3993.5,45],[3992,20064],[3991.5,209],[3991,134],[3990.5,2948]],"timestamp":"2019-03-23T00:34:40.505Z","asks":[[3996.5,975],[3997,289],[3997.5,334],[3998,419],[3998.5,423],[3999,930],[3999.5,547],[4000,538],[4000.5,703],[4001,997]]}]}`
var output OuterJson

Шаг 3: Получить выходной сигнал от заданного входа (или Unmarshalling)

json.Unmarshal([]byte(input), &output)

Объединяя все, вы получаете

package main

import (
    "fmt"
    "encoding/json"
)

type OuterJson struct {
  Table string `json:"table"`
  Action string `json:"action"`
  DataJson []DataJson `json:"data"`
}

type DataJson struct {
  Symbol string `json:"symbol"`
  Timestamp string `json:"timestamp"`
  BidsJson [][]float64 `json:"bids"`
  AsksJson [][]float64 `json:"asks"`

}  

func main() {
    fmt.Println("Hello, playground")
    input := `{"table":"orderBook10","action":"update","data":[{"symbol":"XBTUSD","bids":[[3996,49137],[3995.5,116],[3995,165],[3994.5,166],[3994,237],[3993.5,45],[3992,20064],[3991.5,209],[3991,134],[3990.5,2948]],"timestamp":"2019-03-23T00:34:40.505Z","asks":[[3996.5,975],[3997,289],[3997.5,334],[3998,419],[3998.5,423],[3999,930],[3999.5,547],[4000,538],[4000.5,703],[4001,997]]}]}`
    var output OuterJson
    json.Unmarshal([]byte(input), &output)
    fmt.Println(output)     
}

Попробуйте ссылку

1 голос
/ 23 марта 2019

Ваша ob["data"] JSON структура выглядит следующим образом:

([]interface {}) {
  (map[string]interface {}) {
    (string) "": (string) "",
    (string) "": ([]interface {}) {
      ([]interface {}) {
        (float64),
        (float64) 
      }
    },
    (string) "": (string) "",
    (string) "": ([]interface {}) {
      ([]interface {}) {
        (float64),
        (float64)
      }
    }
  }
}

, поэтому вам нужно использовать следующее:

ob["data"].([]interface{})[0].(map[string]interface{})["asks"]

, который:

  • приведение ob["data"] к []interface{}
  • используйте первый (и в вашем примере единственный) элемент [0]
  • приведите этот элемент к map[string]interface{} и
  • затем извлечь "asks"

Примечание: Если вы не уверены, всегда используйте эту форму t, ok := i.(T) для утверждений типа :

Если у меня есть T, то t будет лежать в основе, и ok будет true.

Если нет, то ok будет false, а t будет нулевым значением типа T, и паники не будет.

0 голосов
/ 23 марта 2019

Ваша структура должна быть

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
)
type JsonData struct {
    Table  string `json:"table"`
    Action string `json:"action"`
    Data   []struct {
        Symbol    string      `json:"symbol"`
        Bids      [][]int     `json:"bids"`
        Timestamp time.Time   `json:"timestamp"`
        Asks      [][]float64 `json:"asks"`
    } `json:"data"`
}

func main() {
    dat, err := ioutil.ReadFile("./data.json")
    if err != nil {
        panic(err)
    }

    var ob JsonData
    if err := json.Unmarshal([]byte(dat), &ob); err != nil {
        panic(err)
    }
    fmt.Println(ob)
   }

Вы можете использовать ссылки ниже для генерации структуры из вложенных объектов JSON.

https://mholt.github.io/json-to-go/

http://json2struct.mervine.net/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...