JavaScript (Node.js) - JSON 递归提取对象到有序数组(展平)

JavaScript (Node.js) - JSON recursion extracting objects to array with order (faltten)

我有一个 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);

    }
}

}

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

有几个模块可以帮助拼合 json 对象。例如https://www.npmjs.com/package/flat

您可以使用递归来完成。这是我的建议:

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));

您正在寻找的结果结构并不“直观”,因此解决方案变得有点丑陋,但您可以通过以下方式使用 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

的作者