How can I iterate Dynamic object in Haxe
Asked Answered
D

1

28

I have Object parsed from JSON (haxe.Json.parse()) and I need to iterate over it. I already tried to cast this object to Array<Dynamic>:

var data:String='{"data":{"0":0,"1":1},"method":"test"}';
var res:{method:String,data:Array<Dynamic>} = haxe.Json.parse(data);
for (n in res.data)
    trace('aa')

There is no Can't iterate dynamic exception, just not working (iterating). I completley don't understand why in Haxe iterating procedure is so difficult.

Desensitize answered 20/3, 2013 at 17:29 Comment(4)
The problem solved. for (n in Reflect.fields(data))Desensitize
This will only get you a list of field names. You'll also need to do Reflect.field(data, n);Logging
@IgorBloom: I guess you forgot about this question. Out of courtesy, it would be nice to either accept an answer or comment what's wrong about them instead of leaving them in the open. Thanks.Amplify
Sorry. Im starts using Reflects and its helps me in all waysDesensitize
D
39

For the sake of posting a complete answer, and in case other people are wondering

In your first example, you've told the compiler that "res" contains two properties - one called "method" (which is a String) and one called "data" (which is Array). Now the JSON you're using doesn't actually have an Array<Dynamic>, it just has a dynamic object. An Array would look like: "data":[0,1].

So, assuming you meant for the JSON to have data as a Dynamic object, here is how you loop over it, using Reflect (as you mentioned in the comments):

var data:String='{"data":{"0":0,"1":1},"method":"test"}';
var res = haxe.Json.parse(data);
for (n in Reflect.fields(res.data))
    trace(Reflect.field(res.data, n));

Note here we don't have to specify the type of "res", since we're using Reflection just leaving it as Dynamic will be fine.

Now, if your JSON actually contains an Array, the code might look like this:

var data:String='{"data":[0,1],"method":"test"}';
var res:{method:String,data:Array<Int>} = haxe.Json.parse(data);
for (n in res.data)
    trace(n);

Here you use explicit typing to tell the compiler that res.data is an Array (and this time it actually is), and it can loop over it normally.

The reason you didn't get an error at compile-time is because the compiler thought there was genuinely going to be an array there, as you told it there was. At runtime, whether or not it throws an exception probably depends on the target... but you probably want to stay out of that anyway :)

Demo of both styles of code: http://try.haxe.org/#772A2

Diphenylhydantoin answered 21/3, 2013 at 8:54 Comment(4)
Jason, why are you so cool? :D You should write a book for Haxe!Farriery
in Haxe 3.1.3 (the current version) the array iteration gives the following compile error: Test.hx:19: characters 11-19 : You can't iterate on a Dynamic value, please specify Iterator or IterableInterregnum
@Interregnum I've updated the try.haxe.org link to use the code in the answer here, and it works. The type annotation (res:{method:String,data:Array<Int>}) is necessary if you want to iterate.Wallas
Yeah, the book being a joint effort between Jason an @back2dos, it'd be awesome!Decode

© 2022 - 2024 — McMap. All rights reserved.