goweb-scrapinginterfacenested-map

Golang nested map filter


package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
)

func main() {
fmt.Println(fecthData())
}

func fecthData() (map[string]interface{}, error) {
body := strings.NewReader("dil_kodu=tr")
req, err := http.NewRequest("POST", "https://www.haremaltin.com/dashboard/ajax/doviz", body)
if err != nil {
    // handle err
    return nil, err
}
req.Header.Set("X-Requested-With", "XMLHttpRequest")

resp, err := http.DefaultClient.Do(req)
if err != nil {
    // handle err
    return nil, err
}
defer resp.Body.Close()
jsonData, err := ioutil.ReadAll(resp.Body)
if err != nil {
    panic(err)
    return nil, err
}

var data map[string]interface{}
err = json.Unmarshal(jsonData, &data)
if err != nil {
    return nil, err
}

return data, nil
}

You can see full code above and I have a go response as below and it is nested map as you see and want to reach "data-ATA5_ESKI-satis" value which is 34319. Is there anybody to help me. Thank you for your time

A part of response below:

map[data:map[AEDTRY:map[alis:4.6271 code:AEDTRY dir:map[alis_dir: satis_dir:] dusuk:4.7116 kapanis:4.6224 satis:4.7271 tarih:17-06-2022 19:41:45 yuksek:4.7276] AEDUSD:map[alis:0.2680 code:AEDUSD dir:map[alis_dir: satis_dir:] dusuk:0.27 kapanis:0.268 satis:0.2700 tarih:17-06-2022 19:30:02 yuksek:0.27]... ALTIN:map[alis:1024.790 code:ALTIN dir:map[alis_dir:down satis_dir:down] dusuk:1029.05 kapanis:1032.13 satis:1030.650 tarih:17-06-2022 19:41:58 yuksek:1040] ATA5_ESKI:map[alis:33869 code:ATA5_ESKI dir:map[alis_dir:down satis_dir:down] dusuk:34266 kapanis:34112 satis:34319 tarih:17-06-2022 19:41:58 yuksek:34630] XPTUSD:map[alis:933 code:XPTUSD dir:map[alis_dir: satis_dir:] dusuk:936 kapanis:953 satis:936 tarih:17-06-2022 19:41:58 yuksek:957]] meta:map[fiyat_guncelleme:2000 fiyat_yayini:web_socket time:1.655484118278e+12 time_formatted:]]


Solution

  • for _, v := range data { // we need value part of the map
        m, ok := v.(map[string]interface{}) // we need the convert the map 
                                            // into interface for iteration
        if !ok {
            fmt.Printf("Error %T", v)
        }
        for k, l := range m {
            if k == "ATA_ESKI"{ // the value we want is inside of this map
                a, ok := l.(map[string]interface{}) // interface convert again
                if !ok {
                    fmt.Printf("Error %T", v)
                }
                for b,c := range a{
                    if b == "satis"{ // the value we want
                        fmt.Println("Price is", c)
                    }
                }
            }
        }
    }
    

    We can get the value adding this iteration before "return data, nil" at the end but I think there must be easier methods for this.