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

huangapple go评论89阅读模式
英文:

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

问题

我在Go语言方面还比较新,但是我正在努力学习。

我正在尝试编写一些逻辑,需要检查结构体的属性是否只包含一个元素,或者第一个元素是否只有一个子元素。

主要的结构体如下:

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

Charts应该是由以下结构体数组组成:

$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"
            ),
        ) 
    ),
);

我将从POST请求中解析出的JSON数据解析到结构体ChartOptions中。JSON数据如下:

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

所以,charts可以只有一个源和一个元素,或者任意数量的元素和任意数量的源。

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

或者

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

当然,这些是传递给Go脚本的JSON元素,我将它们解析为interface{}。当我尝试使用len()函数时,Go语言提示我不能在interface{}上使用它。

在处理元素数量时,最佳实践是什么?如何实现这样的检查?

英文:

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?

答案1

得分: 7

这是一个保持接口的示例:
https://play.golang.org/p/Eu6Hj6ddSE

只需将 Charts interface{} 更改为 Charts []interface{}
如果 v 是你的 ChartOptions,那么要获取长度,请在接口上使用 .() 运算符

fmt.Println(len(v.Charts.([]interface{})))
英文:

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{})))

答案2

得分: 3

根据你提供的代码,我为你翻译了结构体的定义部分:

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)
		}
	}
}

希望对你有帮助!

英文:

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)
		}
	}
}

huangapple
  • 本文由 发表于 2016年2月9日 19:54:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/35291429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定