从javascript对象构造层次结构对象

时间:2017-01-30 23:00:40

标签: javascript

我试图弄清楚如何从我拥有的一些较小的物体构建一个层次对象。以下是一些示例数据:

{ id: 1, name: 'Jackson', parent: null },
{ id: 2, name: 'Jordan', parent: 1 },
{ id: 3, name: 'Jefferson', parent: 1 },
{ id: 4, name: 'Elvis', parent: 2 },
{ id: 5, name: 'Sally', parent: null },
{ id: 6, name: 'Eric', parent: 4 }

这将被构造成一个看起来像这样的HIerarchy对象:

{ 
  '1': { 
    name: 'Jackson',
    children: {
       '2': {
         name: 'Jordan',
         children: { 
           '4': {
             name: 'Elvin',
             children: { 
               '6': {
                 name: 'Eric',
                 children: { }
             }  
           }
         } },
       '3': {
         name: 'Jefferson',
         children: { } }
     }
  },
  '5': {
     name: 'Sally',
     children: { } 
  }

我真的很难解决这个问题,然后为每个id做一个for循环。 (即:找到所有null父项,找到所有1父项,找到所有2父项等...)

1 个答案:

答案 0 :(得分:1)

以下是我对如何做到这一点的看法。

创建一个对象,该对象将根据其键保存对所有其他对象的引用。这允许我们在需要它作为另一个元素的父元素时,通过其键获得对每个对象的引用:

let register = {};

创建输出对象:

let output = {};

现在让我们遍历数组中的每个对象并将其添加到结构中:

// loop through the array
for (let el of elements) {
  // clone the element, so we don't modify the original array
  el = Object.assign({}, el);

  // insert the clone into the register
  register[el.id] = el;

  if (!el.parent) { // if no parent is set, add it to the top level
    output[el.id] = el;
  } else { // otherwise, add it as a child of whatever the parent is
    register[el.parent].children[el.id] = el;
  }

  // add a children property
  el.children = {};
  // remove the parent property
  delete el.parent;
}

请记住,对象始终通过引用存储,因此修改register对象中的对象也会在output对象中修改它。

以下是一个工作示例。

let input = [{
  id: 1,
  name: 'Jackson',
  parent: null
}, {
  id: 2,
  name: 'Jordan',
  parent: 1
}, {
  id: 3,
  name: 'Jefferson',
  parent: 1
}, {
  id: 4,
  name: 'Elvis',
  parent: 2
}, {
  id: 5,
  name: 'Sally',
  parent: null
}, {
  id: 6,
  name: 'Eric',
  parent: 4
}];

let register = {};

let output = {};

// loop through the array
for (let el of input) {
  // clone the element, so we don't modify the original array
  el = Object.assign({}, el);

  // insert the clone into the register
  register[el.id] = el;

  if (!el.parent) { // if no parent is set, add it to the top level
    output[el.id] = el;
  } else { // otherwise, add it as a child of whatever the parent is
    register[el.parent].children[el.id] = el;
  }

  // add a children property
  el.children = {};
  // remove the parent property
  delete el.parent;
}

console.log(JSON.stringify(output, undefined, 2));

请注意,这不适用于循环引用,或者密钥不正常(即子代出现在其父代之前)。