【问题标题】:convert JSON object to JSON tree将 JSON 对象转换为 JSON 树
【发布时间】:2016-04-29 10:13:40
【问题描述】:
var obj = [{
    id: 1,
    child:[2,4],
    data : "hello"
},{
    id: 2,
    child:[3],
    data : "I m second"
},
{   
    id: 3,
    child:[],
    data : "I m third"
},
{
    id: 4,
    child:[6],
    data : "I m fourth"
},{
    id: 5,
    child:[],
    data : "I m fifth"
},{
    id: 6,
    child:[],
    data : "I m sixth"
}];

我已将此对象转换为

var newObj = [{
  id: 1,
  child: [{
    id: 2,
    child: [{
      id: 3,
      child: [],
      data: "I m third"
    }],
    data: "I m second"
  }, {
    id: 4,
    child: [{
      id: 6,
      child: [],
      data: "I m sixth"
    }],
    data: "I m fourth"
  }],
  data: "hello"
}, {
  id: 5,
  child: [],
  data: "I m fifth"
}];

这不过是基于每个属性的子数组的 JSON 的树格式。如何解决问题?如何用javascript编码??

任何帮助都会很重要。提前致谢。

Jsfiddle

【问题讨论】:

  • 抱歉,很难理解您要做什么。到目前为止你尝试了什么?我唯一能看到的是 2 个对象数组。
  • 其实这是个好问题。我看不出反对票的意义。
  • @Brduca 我必须将 obj 转换为 newObj。

标签: javascript arrays json


【解决方案1】:

带有临时对象的提案,用于保留对项目的引用。

var array = [{ id: 1, child: [2, 4], data: "hello" }, { id: 2, child: [3], data: "I m second" }, { id: 3, child: [], data: "I m third" }, { id: 4, child: [6], data: "I m fourth" }, { id: 5, child: [], data: "I m fifth" }, { id: 6, child: [], data: "I m sixth" }],
    tree = [];

array.forEach(function (a) {
    if (!this[a.id]) {
        this[a.id] = { id: a.id };
        tree.push(this[a.id]);
    }
    this[a.id].data = a.data;
    this[a.id].child = a.child.map(function (b) {
        this[b] = this[b] || { id: b };
        return this[b];
    }, this);
}, Object.create(null));

document.write('<pre>' + JSON.stringify(tree, 0, 4) + '</pre>');

【讨论】:

  • 嗨 Nina,Object.create(null) 在做什么?请解释一下?
  • 它创建了一个真正的空对象——一个没有任何原型的对象。
  • 我想知道我们为什么在这里这样做??
  • 哦,我明白了,它是 forEach 循环的 thisArgs。在其内部使用this,一个临时变量。
【解决方案2】:

好吧..正如我评论的那样,这是一个很好的问题,很高兴能对此进行一些思考。显然,这比展平嵌套对象数组更难。

顺便说一下,该算法不依赖于对象的 id 和数组中的对象键之间的任何关联。具有任何 id 的对象可以在数组中的任何位置。

var obj = [{ id: 1, child: [2, 4], data: "hello" }, { id: 2, child: [3], data: "I m second" }, { id: 3, child: [], data: "I m third" }, { id: 4, child: [6], data: "I m fourth" }, { id: 5, child: [], data: "I m fifth" }, { id: 6, child: [], data: "I m sixth" }];

function construct(flat){
  function nest(o) {
    o.forEach( c => { if (!!c.child.length) { // coolness starts here
                         c.child = c.child.map( e => flat.splice(flat.findIndex( f => f.id == e),1)[0]);
                         nest(c.child);
                         }
    	            });
  }
  nest(flat);
  return flat;
}

document.write("<pre>" + JSON.stringify(construct(obj), null, 2) + "</pre>");

【讨论】:

  • 谢谢这是我想要的!!你能告诉我每个循环内部实际发生了什么吗?
  • 嗨...它的工作原理是这样的;我们将一个平面数组传递给内部 nest() 函数。 nest 函数对传入数组的每个元素逐一遍历(forEach 循环)如果当前元素(c 参数)有子元素(!!child.length - !! 是布尔转换 0 变为 false 和任何其他number 变为真)用具有相应 id (c.child.map) 的平面数组中的对象替换 c.child 数组元素,但是必须从平面数组中删除从平面数组移动到子数组的对象。这是由flat.splice 完成的
  • @Rajan Singh :Splice 非常方便,因为它既删除元素又返回删除的元素。所以发生的事情是,搜索具有正确 id (findIndex) 的元素,从平面数组中删除并返回该索引元素,并将其映射到子数组中代替其 id 的位置。所以我们用对象构造子数组。子数组现在就像另一个平面数组,因为子数组中的元素可以包含它们的子元素。所以我们对嵌套(子)进行递归调用,这次同样的故事适用于子数组。这就是内嵌套函数的原因
猜你喜欢
  • 1970-01-01
  • 2017-06-16
  • 1970-01-01
  • 1970-01-01
  • 2017-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多