【问题标题】:Deserialize JSON in Hack strict mode在 Hack 严格模式下反序列化 JSON
【发布时间】:2017-02-11 09:03:54
【问题描述】:

我有一个嵌套的 JSON 文件,由仅是字符串的键和值组成。但是 JSON 文件的结构并不固定,所以有时可以嵌套 3 层,有时只有 2 层。 我想知道如何在严格模式下对其进行序列化?

  "live" : {
"host" : "localhost",
"somevalue" : "nothing",
"anobject" : {
  "one" : "two",
  "three" : "four",
  "five" : {
    "six" : "seven"
  }
}

}

如果我知道 JSON 的结构,我会为它编写自己的类,但由于键不固定,而且嵌套可能分为几个层次,我真的想知道我是如何剪切这样的对象转换为特定类型。

感谢任何帮助或提示

【问题讨论】:

    标签: hhvm hacklang


    【解决方案1】:

    我认为invariants 在这里可以很好地为您服务。首先,知道您可以在 Hack 中严格键入键控树可能会有所帮助:

    <?hh // strict
    class KeyedTree<+Tk as arraykey, +T> {
      public function __construct(
        private Map<Tk, KeyedTree<Tk, T>> $descendants = Map{},
        private ?T $v = null
      ) {}
    }
    

    (必须是类,因为cyclic shape definitions are sadly not allowed

    我还没有尝试过,但type_structures 和Fred Emmott's TypeAssert 看起来也很有趣。如果已知 JSON blob 的某些部分已修复,那么您可以隔离嵌套的、不确定的部分并使用invariants 从中构建一棵树。在整个 blob 未知的极限情况下,您可以删除 TypeAssert,因为没有有趣的固定结构可以断言:

    use FredEmmott\TypeAssert\TypeAssert;
    class JSONParser {
        const type Blob = shape(
            'live' => shape(
                'host' => string, // fixed
                'somevalue' => string, // fixed
                'anobject' => KeyedTree<arraykey, mixed> // nested and uncertain
            )
        );
        public static function parse_json(string $json_str): this::Blob {
            $json = json_decode($json_str, true);
            invariant(!array_key_exists('anobject', $json), 'JSON is not properly formatted.');
            $json['anobject'] = self::DFS($json['anobject']);
              // replace the uncertain array with a `KeyedTree`
            return TypeAssert::matchesTypeStructure(
                type_structure(self::class, 'Blob'),
                $json
            );
            return $json;
        }
        public static function DFS(array<arraykey, mixed> $tree): KeyedTree<arraykey, mixed> {
            $descendants = Map{};
            foreach($tree as $k => $v) {
                if(is_array($v))
                    $descendants[$k] = self::DFS($v);
                else
                    $descendants[$k] = new KeyedTree(Map{}, $v); // leaf node
            }
            return new KeyedTree($descendants);
        }
    }
    

    在路上,您仍然需要在 KeyedTree 上补充 containsKey 不变量,但这就是 Hack 中非结构化数据的现实。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-02
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 2011-08-14
      • 2018-12-31
      • 1970-01-01
      相关资源
      最近更新 更多