JSON的父子关系设置

时间:2015-06-02 18:22:53

标签: javascript json algorithm loops formatting

我有以下JSON数据:

[
 {id: 1, indent: '1'},
 {id: 2, indent: '1.1'},
 {id: 3, indent: '1.2'},
 {id: 4, indent: '2'},
 {id: 5, indent: '2.1'},
 {id: 6, indent: '2.2'},
 {id: 7, indent: '2.2.1'},
 {id: 8, indent: '1.2.1'},
 {id: 9, indent: '3'},
]

我想将其转换为如下所示:

[
 {id: 1, indent: '1', parent: null},
 {id: 2, indent: '1.1', parent: 1},
 {id: 3, indent: '1.2', parent: 1},
 {id: 4, indent: '2', parent: null},
 {id: 5, indent: '2.1', parent: 4},
 {id: 6, indent: '2.2', parent: 4},
 {id: 7, indent: '2.2.1', parent: 6},
 {id: 8, indent: '1.2.1', parent: 3},
 {id: 9, indent: '3', parent: null},
]

我可以通过2个for循环,外部和内部来实现这一点,但我正在寻找一种有效的方法来实现它。

ex: 
forloop each node
   get indent and check if dots ('.') are more than one
     if true
     for-loop the array and check for indent that start with the indent and ends with dot + 1

2 个答案:

答案 0 :(得分:3)

除非你的json中有超过100000个这些项目(这似乎不太可能需要很长时间才能下载/发送),那么你的方法就可以了。

您可以做的最佳优化是利用ID正常的事实。由于引用不是,这将要求您在前进时跟踪id以缩进对象中的引用。

看起来像这样

var jsonObj = [
 {id: 1, indent: '1'},
 {id: 2, indent: '1.1'},
 {id: 3, indent: '1.2'},
 {id: 4, indent: '2'},
 {id: 5, indent: '2.1'},
 {id: 6, indent: '2.2'},
 {id: 7, indent: '2.2.1'},
 {id: 8, indent: '1.2.1'},
 {id: 9, indent: '3'},
];
 
var parentIds = {};  
for(var i = 0; i < jsonObj.length; i++){
 var obj = jsonObj[i];
 var dot = obj.indent.lastIndexOf('.');
 if(dot > -1){
  obj.parent = parentIds[obj.indent.substr(0,dot)];  
 }else{
  obj.parent = null;
 }
 parentIds[obj.indent] = obj.id;
}

console.log(jsonObj);
document.querySelector("#d").innerHTML = JSON.stringify(jsonObj);
<div id="d"></div>

答案 1 :(得分:0)

您可以创建从缩进到ID的地图。

&#13;
&#13;
var data = [{id: 1, indent: '1'}, {id: 2, indent: '1.1'}, {id: 3, indent: '1.2'}, {id: 4, indent: '2'},{id: 5,indent: '2.1'},{id: 6, indent: '2.2'}, {id: 7,indent: '2.2.1'},{id: 8, indent: '1.2.1'}, {id: 9, indent: '3'}];

var indentToId = {};

for (var i=0, item; item = data[i]; i++) {
    indentToId[item.indent] = item.id;
}

for (var i=0, item; item = data[i]; i++) {
    var lastPeriodIndex = item.indent.lastIndexOf('.');
    // Added this as a performance tweak so it would compare to Travis's version :)
    if (lastPeriodIndex == -1) {
        item.parent = null;
    } else {
        // Again, stealing form Travis, subst is faster than slice
        item.parent = indentToId[item.indent.substr(0, lastPeriodIndex)];
    }
}
console.log(JSON.stringify(data));
// [{"id":1,"indent":"1","parent":null},{"id":2,"indent":"1.1","parent":1},
//  {"id":3,"indent":"1.2","parent":1},{"id":4,"indent":"2","parent":null},
//  {"id":5,"indent":"2.1","parent":4},{"id":6,"indent":"2.2","parent":4},
//  {"id":7,"indent":"2.2.1","parent":6},{"id":8,"indent":"1.2.1","parent":3},
//   {"id":9,"indent":"3","parent":null}]
&#13;
&#13;
&#13;

你担心有两个循环。但是,真正的问题是当你有嵌套循环时。两个循环,一个接一个,仍然是线性时间。请参阅this performance comparison