Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

golang , How to count elements in struct type interface{}?

Tags:

slice

struct

go

I'm rather new in Go, but trying hard..

I'm trying to write some logick, that need to check if an attribute of struct consists only of one element, or the first element has only one child.

Main struct is this :

type ChartOptins struct {
    Filters Filter `json:"filters"`
    Charts interface{} `json:"charts"`
}

Charts are born to be a composition of arrays of structure like this :

    $filters = array(
        "filters" => array(
            "DayStart" => "12-01-2015",
            "DayEnd" => "12-05-2015",
            "TimePeriods"=> array(
                array("qqq","www"),
            ),
            "lines" => array(
                "first","avokado","drunduki"
            )

        ),
        "charts" => array(
            "noagg" => array(
                array(
                    "name" => "HOLD",
                    "type" => "line"
                ),
                array(
                    "name" => "UKKR",
                    "type" => "line"
                ),
                array(
                    "name" => "SVO",
                    "type" => "line"
                ),
            ),
            "oracle" => array(
                array(
                    "name" => "TDD",
                    "type" => "line"
                ),
            ) 
        ),
    );

Into the stuct ChartOptions I parse the JSON from POST request. JSON looks like this :

{ "filters": { "dayStart": "11-10-2015", "dayEnd": "21-10-2015", "timePeriods": [ [ "qqq", "www" ] ], "lines": [ "first", "avokado", "drunduki" ] }, "charts": { "noagg": [ { "name": "HOLD", "type": "line" } ] } }

So , charts can have only 1 source and 1 element in it, or any amount of elements in any amount of sources.

"charts" : { "noagg": [ { "name": "HOLD", "type": "line" } ] }
or
"charts" : { "noagg": [ { "name": "HOLD", "type": "line" } , { "name": "TDD", "type": "line" } , { "name": "SVO", "type": "line" } ] }

Of cource, this is the JSON elements that comes to go script, and i parse them into interface{}. When I tried to use len(), Go said that I cant use it on interface..

What is the best practice to work with the amount of elements, and what is the best way to achieve such a check?

like image 423
Altenrion Avatar asked Feb 09 '16 11:02

Altenrion


2 Answers

Here is an exemple keeping interface: https://play.golang.org/p/Eu6Hj6ddSE

Just change: Charts interface{} witch Charts []interface{} if v is you ChartOptins then to get your len use .() operator on interface

fmt.Println(len(v.Charts.([]interface{})))
like image 60
SRS Avatar answered Oct 08 '22 04:10

SRS


As i understand you just need define structures for mapping json properly. It can be like this:

package main

import (
    "encoding/json"
    "fmt"
    "strings"
)

type ChartOptins struct {
    Filters map[string]interface{} `json:"filters"`
    Charts  map[string][]Chart     `json:"charts"`
}

type Chart struct {
    Name string `json:"name"`
    Type string `json:"type"`
}

func main() {
    const jsonStream = `{
        "filters": { "dayStart": "oneortwo", "dayEnd": "oneorthree", "timePeriods": [ [ "qqq", "www" ] ], "lines": [ "first", "avokado", "drunduki" ] }, 
        "charts": { "noagg": [ { "name": "HOLD", "type": "line" }, { "name": "UKKR", "type": "line" }, { "name": "SVO", "type": "line" } ], "oracle": [ { "name": "TDD", "type": "line" } ] } 
    }`

    var co ChartOptins
    json.NewDecoder(strings.NewReader(jsonStream)).Decode(&co)

    fmt.Println(co)

    for k, v := range co.Charts {
        fmt.Printf("key: %v\n", k)
        for _, ch := range v {
            fmt.Printf("Name: %v, type: %v\n", ch.Name, ch.Type)
        }
    }
}
like image 39
wlredeye Avatar answered Oct 08 '22 02:10

wlredeye