JSON对象解析算法
问题描述:
这JSON是Chrome的书签表示:JSON对象解析算法
{
"checksum": "c3f0feee53f25f2382bc3eff47034d82",
"roots": {
"bookmark_bar": {
"children": [ {
"children": [ {
"children": [ {
"date_added": "13150632079496078",
"id": "10",
"name": "js page",
"type": "url",
"url": "http://page3.com/"
} ],
"date_added": "13150631991440413",
"date_modified": "13150632092493717",
"id": "7",
"name": "js",
"type": "folder"
}, {
"date_added": "13150632069464091",
"id": "9",
"name": "language page",
"type": "url",
"url": "http://page2.com/"
} ],
"date_added": "13150631979905599",
"date_modified": "13150632079496078",
"id": "6",
"name": "language",
"type": "folder"
}, {
"date_added": "13150632058452033",
"id": "8",
"name": "page 1",
"type": "url",
"url": "http://page1.com/"
}, {
"children": [ {
"date_added": "13150632233410110",
"id": "12",
"name": "linux",
"type": "url",
"url": "http://linux.com/"
}, {
"date_added": "13150632242559984",
"id": "13",
"name": "windows",
"type": "url",
"url": "http://windows.com/"
} ],
"date_added": "13150632129199190",
"date_modified": "13150632242559984",
"id": "11",
"name": "os",
"type": "folder"
} ],
"date_added": "13150631968031471",
"date_modified": "13150632129201358",
"id": "1",
"name": "Bookmarks Bar",
"type": "folder"
},
"other": {
"children": [ {
"children": [ {
"date_added": "13150632296451689",
"id": "15",
"name": "another url",
"type": "url",
"url": "http://anotherurl.com/"
} ],
"date_added": "13150632284982823",
"date_modified": "13150632296451689",
"id": "14",
"name": "another folder",
"type": "folder"
} ],
"date_added": "13150631968031475",
"date_modified": "13150632284984136",
"id": "2",
"name": "Other Bookmarks",
"type": "folder"
},
"synced": {
"children": [ ],
"date_added": "13150631968031476",
"date_modified": "0",
"id": "3",
"name": "Mobile Bookmarks",
"type": "folder"
}
},
"version": 1
}
我想拉平整个JSON 和每个父文件夹名称添加到相应的书签作为标记(可能到每个书签的标签:[]属性)。
例如:在图像中看到的那样,“语言网页”书签应该是:
[{
...
},
{
"date_added": "13150632069464091",
"id": "9",
"name": "language page",
"type": "url",
"url": "http://page2.com/",
tags: ["Bookmarks Bar","language"]
},
{
...
}]
如果将有所帮助,这里是我用扁平化JSON:
if (dataJson.roots) {
// build the bookmarks list
let bookmarks = [];
let keys = Object.keys(dataJson.roots);
for (let i = 0; i < keys.length; i++) {
const folder = keys[i];
const rootObject = dataJson.roots[folder];
// retrieve child nodes in each root folder
// and concatenate to global collection
const children = rootObject.children ? getChildren(rootObject.children) : [];
if (children.length) {
for (let j = 0; j < children.length; j++) {
bookmarks.push(children[j]);
}
}
}
const nb = new Array(bookmarks.length);
for (let i = 0; i < bookmarks.length; i++) {
nb[i] = normalize(bookmarks[i]);
}
resolve(nb);
} else {
resolve([]);
}
注意:解决方案当然可以更清晰的另一个循环。谢谢!
答
可以使用递归apporach深入到树,并添加标签到它:
function flatten(obj){
const result = [];
//as this is applied to a folder, iterate over all children:
for(const child of obj.children){
//if child is a folder
if(child.children){
//concat all flattened results
result.push(... flatten(child));
} else {
//just a regular child
result.push(child);
}
}
//add tag to each result:
result.forEach(o => (o.tags || (o.tags = [])).unshift(obj.name));
return result;
}
所以现在我们可以拉平一棵树,如:
const result = flatten(yourJSON.roots.other);
所以我们只需要现在它应用到所有的根和Concat的结果:
const result = Object.values(yourJSON.roots)
.map(flatten)
.reduce((a,b) => a.concat(b), []);
非常感谢,这更清洁。 – serkan