【问题标题】:Parent and child relation setup from JSON来自 JSON 的父子关系设置
【发布时间】:2015-06-02 18:22:53
【问题描述】:

我有以下 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

【问题讨论】:

  • 不是顺便说一下 JSON,它只是 JavaScript 数据
  • @Kevin,我试过了,但我无法使用地图解决。
  • @JuanMendes,我们可以放心地假设它的 javascript 对象 :)
  • 仅仅因为您将其隐藏在语言功能中并不意味着您将拥有少于 2 个循环。尝试使循环更高效如何?

标签: javascript json algorithm loops formatting


【解决方案1】:

除非您的 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);
&lt;div id="d"&gt;&lt;/div&gt;

【讨论】:

  • 非常感谢您的解决方案适用于所有浏览器并优化为使用一个循环。很好的解决方案。
  • @user3130446 如果有帮助,请务必接受此答案。
【解决方案2】:

您可以创建从缩进到 ID 的映射。

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}]

您担心存在两个循环。然而,真正的问题是当你有嵌套循环时。两个循环,一个接一个,仍然是线性时间。见this performance comparison

【讨论】:

  • @user3130446 它们不是嵌套循环,这是最大的区别,所以它仍然是线性时间,而不是指数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-09
  • 1970-01-01
  • 1970-01-01
  • 2012-08-07
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
相关资源
最近更新 更多