JSON 对象解析算法

JSON object parse algorithm

这个JSON是Chrome的书签表示:

{
   "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 将每个父文件夹名称添加到相应的书签作为标签(可能是标签:[] 属性 每个书签)。

例如:如图所示,"language page" 书签应该是:

       [{
         ...
        },
        {
           "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([]);
    }

注意:解决方案当然可以更清楚另一个loop.Thanks!

可以使用递归方法深入到树中,并向其添加标签:

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

所以我们现在只需要将其应用于所有根并连接结果:

const result = Object.values(yourJSON.roots)
                .map(flatten)
                .reduce((a,b) => a.concat(b), []);

Try it