如何在Haxe中将JSON /动态结构转换为Map?

时间:2018-08-07 01:43:00

标签: json dictionary haxe

我是编码的新手,通常使用基于Haxe(Stencyl)作为爱好的拖放编辑器。

我有一个JSON文件,我想将其转换为嵌套地图(字典)。我尝试使用JSON解析功能,但它返回匿名(动态)结构。

如何将JSON文件转换为地图或将匿名结构转换为地图?

JSON示例:

{
  "apple": {
    "value": 10,
    "health": 15,
    "tags": [
      "fruit",
      "fiber",
      "sweet"
    ]
  },
  "lemon": {
    "value": 5,
    "health": 10,
    "tags": [
      "fruit",
      "citrus",
      "sour"
    ]
  },
  "ham": {
    "value": 50,
    "health": 50,
    "tags": [
      "salty",
      "meat"
    ]
  }
}

3 个答案:

答案 0 :(得分:4)

另一种选择是使用json2object库,natively supports Map<String, T>

import sys.io.File;
import json2object.JsonParser;

class Main {
    public static function main() {
        var parser = new JsonParser<Data>();
        var source = File.getContent("data.json");
        var data = parser.fromJson(source, "data.json");
        trace(data["apple"].value); // 10
    }
}

typedef Data = Map<String, {
    var value:Int;
    var health:Int;
    var tags:Array<String>;
}>

这种方法避免了通常被认为是不良做法的反射和Dynamic

答案 1 :(得分:3)

您可以创建Map并通过Reflect api进行填充:

var parse = haxe.Json.parse(s);
var map:Map<String, StructData> = new Map();
for(field in Reflect.fields(parse))
{
    map.set(field, Reflect.field(parse, field));
}

typedef StructData = {
var value:Int;
var health:Int;
var tags:Array<String>;
}

https://try.haxe.org/#DFa77

答案 2 :(得分:1)

看看DynamicAccess摘要here

鉴于您的示例,我举了一个简短的示例here

import haxe.DynamicAccess;

typedef Food = {
    var value:Int;
    var health:Int;
    var tags:Array<String>;
}

class Test {
    static function main() {
        var json = {
          "apple": {
            "value": 10,
            "health": 15,
            "tags": [
              "fruit",
              "fiber",
              "sweet"
            ]
          },
          "lemon": {
            "value": 5,
            "health": 10,
            "tags": [
              "fruit",
              "citrus",
              "sour"
            ]
          },
          "ham": {
            "value": 50,
            "health": 50,
            "tags": [
              "salty",
              "meat"
            ]
          }
        };

        var foodMap:DynamicAccess<Food> = json;

        // Get a single entry
        var apple = foodMap.get("apple");
        trace(apple.tags.join(", "));

        // Loop through names
        for (foodName in foodMap.keys()) {
            trace(foodName);
            trace(foodMap.get(foodName).value);
        }  
    }
}