【问题标题】:JavaScript (Node.js) - JSON recursion extracting objects to array with order (faltten)JavaScript (Node.js) - JSON 递归提取对象到数组的顺序(展平)
【发布时间】:2016-02-08 22:05:19
【问题描述】:

我有一个 JSON 配置文件如下:

var conf = [
    {
        "value": "baz",
        "threshold": 20,
        "other": 123
    },
    {
        "value": "mo",
        "other": 456,
        "child": {
            "value": "foo",
            "other": 789,
            "child": {
                "value": "larry",
                "other": 123
            }
        }
    }
];

如果它们有子对象,我需要提取每个对象并将它们按顺序保存在一起。例如,对象 1 (baz) 是独立的。对象 2 (mo) 将有两个子对象。这 3 个作为一组必须一起提取。

子对象的数量没有限制。

我试图使用一个数组来持久化每个对象以保持顺序。所以所需的输出看起来像:

[[{"value":"baz","threshold":20,"other":123}],
[[{"value":"mo","other":456,"child":{"value":"foo","other":789,"child":{"value":"larry","other":123}}}],
[{"value":"foo","other":789,"child":{"value":"larry","other":123}}],
[{"value":"larry","other":123}]]]

最后一个要求是实际从父母中删除子值,以便输出实际上可以像:

    [
     [{"value":"baz","threshold":20,"other":123}],
     [
       [{"value":"mo","other":456}],
       [{"value":"foo","other":789}],
       [{"value":"larry","other":123}]
     ]
   ]

我已经为此挂了几个小时,进展甚微。我知道我需要创建一个递归函数,将每个节点推入一个数组,然后检查子对象并重复。

这是我目前所拥有的。我的想法是,如果我可以获取每个任务被推送到的数组 id(使用循环 id),也许我可以在再次调用函数时映射它。

感谢任何指导。

var execSets = []; 函数解析器(任务){

// an ordered array of task execution

for (let eachTask in tasks) {
    var taskSet = [];
    console.log("====================================");
    console.log(tasks[eachTask]);

    if(!tasks[eachTask].child && typeof(tasks[eachTask]) === 'object'){

        console.log(tasks[eachTask]);
        taskSet.push(tasks[eachTask]);
        execSets.push(taskSet);

    }

    if(tasks[eachTask].child){

        let childAlias = tasks[eachTask].child;
        delete tasks[eachTask].child;
        taskSet.push(tasks[eachTask]);

        execSets.push(taskSet);
        parser(childAlias);

    }
}

}

【问题讨论】:

    标签: arrays json node.js recursion flatten


    【解决方案1】:

    您正在寻找的结果结构不是“直观的”,因此解决方案有点难看,但您可以使用object-scan 回答您的问题

    // const objectScan = require('object-scan');
    
    const data = [{"value":"baz","threshold":20,"other":123},{"value":"mo","other":456,"child":{"value":"foo","other":789,"child":{"value":"larry","other":123}}}]
    
    const fn = (haystack) => objectScan(['[*]', '**.child'], {
      filterFn: ({
        key: [id, ...p],
        value: { child, ...node },
        context
      }) => {
        if (!(id in context)) {
          context[id] = [];
        }
        context[id].push(child || p.length !== 0 ? [node] : node);
      }
    })(haystack, []);
    
    console.log(fn(data));
    // => [ [ { value: 'baz', threshold: 20, other: 123 } ], [ [ { value: 'larry', other: 123 } ], [ { value: 'foo', other: 789 } ], [ { value: 'mo', other: 456 } ] ] ]
    .as-console-wrapper {max-height: 100% !important; top: 0}
    <script src="https://bundle.run/object-scan@13.7.1"></script>

    免责声明:我是object-scan的作者

    【讨论】:

      【解决方案2】:

      您可以使用递归来做到这一点。这是我的建议:

      var conf = [
      {
          "value": "baz",
          "threshold": 20,
          "other": 123
      },
      {
          "value": "mo",
          "other": 456,
          "child": {
              "value": "foo",
              "other": 789,
              "child": {
                  "value": "larry",
                  "other": 123
              }
          }
      }
      ];
      
      
      function getFlattenedObject(object){
      
         var response = [];   
         flatten(object, response, 0);    
         return response;
      
      }
      
      
      function flatten(object, array, index){
      
         if(!array[index]){
             array.push([]);
         }
      
         array[index].push(object);
      
         if(object.child){
              flatten(object.child, array, index + 1);
              object.child = undefined;
         }      
      }
      
      //Logs for comparison
      console.dir(conf)
      console.dir(getFlattenedObject(conf));
      

      【讨论】:

      • 非常感谢这个例子 - 非常有帮助。
      【解决方案3】:

      npm 注册表是您的朋友;试试'npm search flat,

      有一些模块可以帮助扁平化 json 对象。例如https://www.npmjs.com/package/flat

      【讨论】:

      • 没问题,有时最好使用现有的解决方案
      猜你喜欢
      • 2015-07-14
      • 2018-04-20
      • 2016-08-16
      • 2020-02-25
      • 2019-09-27
      • 2018-02-24
      • 2015-05-23
      • 2023-01-11
      • 2013-12-02
      相关资源
      最近更新 更多