拼合嵌套的json对象
问题描述:
[
{
"children": [
{
"children": [
{
"dateAdded": 1493033302670,
"id": "1534",
"index": 0,
"parentId": "1",
"title": "data1",
"url": "data2"
},
{
"children": [
{
"dateAdded": 1489571506844,
"id": "1451",
"index": 0,
"parentId": "1401",
"title": "data3",
"url": "data4"
}
],
"dateAdded": 1490363326576,
"dateGroupModified": 1490363326576,
"id": "1401",
"index": 1,
"parentId": "1",
"title": "daily"
},
{
"children": [
{
"dateAdded": 1481787664555,
"id": "1429",
"index": 0,
"parentId": "1407",
"title": "data56",
"url": "data"
},
{
"dateAdded": 1483365608504,
"id": "1430",
"index": 1,
"parentId": "1407",
"title": "data34",
"url": "data55"
}
]
}
]
}
]
}
]
这是Chrome书签数据的表示形式。拼合嵌套的json对象
如果对象有url属性它表示这是一个书签。如果它没有url属性它是一个文件夹。
它是一个树形结构。
我想使用附加属性类型创建平坦对象。像:
[
{
"dateAdded": 1489571506844,
"id": "1451",
"index": 0,
"parentId": "1401",
"title": "title",
"url": "some url",
"type": "bookmark"
},
{
"dateAdded": 1489571506844,
"id": "1451",
"index": 0,
"parentId": "1402",
"title": "title2",
"url": "some url2"
"type": "folder"
}
]
在此先感谢。
答
你可以使用获得的平面数据迭代和递归方法。
function flatten(array) {
var result = [];
array.forEach(function iter(o) {
var temp = {},
keys = Object.keys(o);
if (keys.length > 1) {
keys.forEach(function (k) {
if (k !== 'children') {
temp[k] = o[k];
}
});
temp.type = 'url' in o ? 'bookmark' : 'folder';
result.push(temp);
}
Array.isArray(o.children) && o.children.forEach(iter);
});
return result;
}
var data = [{ children: [{ children: [{ dateAdded: 1493033302670, id: "1534", index: 0, parentId: "1", title: "data1", url: "data2" }, { children: [{ dateAdded: 1489571506844, id: "1451", index: 0, parentId: "1401", title: "data3", url: "data4" }], dateAdded: 1490363326576, dateGroupModified: 1490363326576, id: "1401", index: 1, parentId: "1", title: "daily" }, { children: [{ dateAdded: 1481787664555, id: "1429", index: 0, parentId: "1407", title: "data56", url: "data" }, { dateAdded: 1483365608504, id: "1430", index: 1, parentId: "1407", title: "data34", url: "data55" }] }] }] }];
console.log(flatten(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }
答
我已经做了一个遍历包含对象的数组的函数。如果给定对象具有名为children
的属性,则该函数自行调用。如果没有,那么它会被推到一个新的阵列flattenedBookmarks
。
解决方案
var flattenedBookmarks = [];
flattenBookmarks(bookmarks);
function flattenBookmarks(bookmarks) {
for (var i = 0; i < bookmarks.length; i++) {
var potentialBookmark = bookmarks[i];
if (potentialBookmark.hasOwnProperty("url")) {
potentialBookmark.type = "bookmark";
} else {
potentialBookmark.type = "folder";
}
if (potentialBookmark.hasOwnProperty("children")) {
flattenBookmarks(potentialBookmark.children);
if (potentialBookmark.hasOwnProperty("dateGroupModified")) {
flattenedBookmarks.push(potentialBookmark);
}
} else {
flattenedBookmarks.push(potentialBookmark);
}
}
}
你或许应该从函数返回扁平阵列,而不是将其存储在一个新的全球阵列flattenedBookmarks
的,但至少这将让你开始。
答
的例子展示了如何做到这一点
data = [
{
"children": [
{
"children": [
{
"dateAdded": 1493033302670,
"id": "1534",
"index": 0,
"parentId": "1",
"title": "data1",
"url": "data2"
},
{
"children": [
{
"dateAdded": 1489571506844,
"id": "1451",
"index": 0,
"parentId": "1401",
"title": "data3",
"url": "data4"
}
],
"dateAdded": 1490363326576,
"dateGroupModified": 1490363326576,
"id": "1401",
"index": 1,
"parentId": "1",
"title": "daily"
},
{
"children": [
{
"dateAdded": 1481787664555,
"id": "1429",
"index": 0,
"parentId": "1407",
"title": "data56",
"url": "data"
},
{
"dateAdded": 1483365608504,
"id": "1430",
"index": 1,
"parentId": "1407",
"title": "data34",
"url": "data55"
}
]
}
]
}
]
}
];
data2 = [];
function search(data) {
for (n in data) {
if (typeof data[n] == 'object') {
if (data[n].id != undefined) {
if (data[n].url != undefined) {
data[n].type="folder";
} else {
data[n].type="bookmark";
}
data2.push(data[n]);
}
search(data[n]);
}
}
}
search(data);
console.log(data2);
能否请您解释一下代码,而不是仅仅把它放在这里 – kaldoran