result, ok := data.([][]float64) should it work?

103 views
Skip to first unread message

webzak

unread,
Jul 6, 2015, 3:58:26 AM7/6/15
to golan...@googlegroups.com
Hello,

I am new to Go, but it looks really great for some tasks. Probably my question is quite stupid, but I can't find a solution with search.

I am converting JSON data where I don't know exactly the structure, so part of it is converted to complex map. After cheking some fields I am able to continue convertion  the rest of data to the proper structure.

So my destination structure looks like:

type Response struct {
    Name string
    .....

    Data    map[string]interface{}
}



var rs []Response
err := json.Unmarshal(input, &rs)

When Data map has only scalar values, the task is trivial, but sometimes it has values like: 
 

{"bids": []interface {}{[]interface {}{255.5, 3.066}, []interface {}{255.49, 0.175}, []interface {}{255.42, 0.709}, []interface {}{255.41, 0.125}}


(original input: ..."data":{"bids":[[255.5,3.066],[255.49,0.175],[255.42,0.709],[255.41,0.125]], "asks": ......)


I wonder about simplest way to iterate over that data without using reflection package.


I thought it's possible to make type assertion like:


result, ok := data.([][]float64)

or may be 

result, ok := data.([][2]float64)

But both constructions return ok as false. Is there any simple way to solve this problem?

Tamás Gulácsi

unread,
Jul 6, 2015, 9:25:46 AM7/6/15
to golan...@googlegroups.com
Write a helper func, which type asserts []interface{}, ranges through it, and builds a same sized []float64 slice:

floats:=make([]float64, len(ifaces))
for i,v:=range ifaces{
floats[i]=v.(float64)
}

webzak

unread,
Jul 6, 2015, 12:27:33 PM7/6/15
to golan...@googlegroups.com
Thanks. Yep I've already done this way, just I need 2 loops for my case.
Basically slices  convertion even single dimention is not working:


It would be nice to have it supported by compiler in the future versions..


Matt Harden

unread,
Jul 6, 2015, 12:55:08 PM7/6/15
to webzak, golan...@googlegroups.com
That's been explicitly ruled out in the past; the reason as I understand it being that it would compile a very simple and innocuous expression into a loop that could take a long time to execute, depending on the size of the slices involved. Basically it would take what syntactically looks like an O(1) activity and compile it to an O(N) loop.

You might think that this can be done in O(1) by simply changing the type of the value, but the memory layout of a []interface{} vs. a []T for any given non-interface type T will be different. If T is an interface type, the memory layout *might* be the same but the language spec does not guarantee it, and there would still have to be a loop to assert each element to be sure they all implement T.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages