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
的作者
我有一个 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
的作者