从平面数组创建嵌套对象

时间:2018-04-23 06:52:13

标签: javascript arrays json object ecmascript-6

我目前有一个对象数组,我试图将ID作为对象键重新整形为嵌套对象,并使用ID定位parent id如果不是"0"。我已经尝试了几种方法,但是我很难过得很开心!对我来说,的主要障碍是超过一层或两层深的东西。理想情况下,我需要它是动态的,所以它可以处理任何深度,虽然在野外我怀疑它将超过3层。

这是传入的对象数组:

[

  {
    ID: "1671",
    parent: "0",
  },
  {
    ID: "1223",
    parent: "0",
  },
  {
    ID: "1668",
    parent: "0",
  },
  {
    ID: "1688",
    parent: "0",
  },
  {
    ID: "1669",
    parent: "0",
  },
  {
    ID: "1681",
    parent: "1669",
  },
  {
    ID: "1680",
    parent: "1669",
  },
  {
    ID: "1670",
    parent: "1669",
  },
  {
    ID: "1682",
    parent: "1669",
  },
  {
    ID: "1433",
    parent: "1682",
  },
  {
    ID: "1684",
    parent: "1682",
  },
  {
    ID: "1672",
    parent: "1684",
  },
  {
    ID: "1685",
    parent: "1672",
  },
  {
    ID: "1686",
    parent: "1672",
  },
  {
    ID: "1683",
    parent: "0",
  },
  {
    ID: "1230",
    parent: "0",
  },
  {
    ID: "1667",
    parent: "0",
  },
  {
    ID: "1687",
    parent: "0",
  }
];

这是理想的转型:

1671: {
    ID: "1671",
    parent: "0",
  },
  1223: {
    ID: "1223",
    parent: "0",
  },
  1668: {
    ID: "1668",
    parent: "0",
  },
  1688: {
    ID: "1688",
    parent: "0",
  },
  1669: {
    ID: "1669",
    parent: "0",
    children: {
      1681: {
        ID: "1681",
        parent: "1669",
      },
      1680: {
        ID: "1680",
        parent: "1669",
      },
      1670: {
        ID: "1670",
        parent: "1669",
      },
      1682: {
        ID: "1682",
        parent: "1669",
        children: {
          1433: {
            ID: "1433",
            parent: "1682",
          },
          1684: {
            ID: "1684",
            parent: "1682",
            children: {
              1672: {
                ID: "1672",
                parent: "1684",
                children: {
                  1685: {
                    ID: "1685",
                    parent: "1672",
                  },
                  1686: {
                    ID: "1686",
                    parent: "1672",
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  1683: {
    ID: "1683",
    parent: "0",
  },
  1230: {
    ID: "1230",
    parent: "0",
  },
  1667: {
    ID: "1667",
    parent: "0",
  },
  1687: {
    ID: "1687",
    parent: "0",
  }

我的大多数失败的方法一直在使用Array.reduce()和其他类型的递归但无济于事,所以我有兴趣看看是否有解决方案。

由于

2 个答案:

答案 0 :(得分:3)

您可以使用这样的递归函数:

function findFor(parentId) {
  // create a new object to store the result
  var z = {};

  // for each item in a
  for (var i = 0; i<a.length; i++){

    // find all children of parentId
    if (a[i].parent === parentId) {

      // recursively find children for each children of parentId
      var ch = findFor(a[i].ID);

      // if it has no children, skip adding the children prop
      var o = Object.keys(ch).length === 0 ? {} : { children: ch };
      z[a[i].ID] = Object.assign(o, a[i]);
    }
  }

  return z;
}

// find all item whose parent is "0"
console.log(findFor("0"));

&#13;
&#13;
var a = [
  { ID: "1671", parent: "0", },
  { ID: "1223", parent: "0", },
  { ID: "1668", parent: "0", },
  { ID: "1688", parent: "0", },
  { ID: "1669", parent: "0", },
  { ID: "1681", parent: "1669", },
  { ID: "1680", parent: "1669", },
  { ID: "1670", parent: "1669", },
  { ID: "1682", parent: "1669", },
  { ID: "1433", parent: "1682", },
  { ID: "1684", parent: "1682", },
  { ID: "1672", parent: "1684", },
  { ID: "1685", parent: "1672", },
  { ID: "1686", parent: "1672", },
  { ID: "1683", parent: "0", },
  { ID: "1230", parent: "0", },
  { ID: "1667", parent: "0", },
  { ID: "1687", parent: "0", }
];

function findFor(parentId) {
  var z = {};
  for (var i = 0; i<a.length; i++){
    if (a[i].parent === parentId) {
      var ch = findFor(a[i].ID);
      var o = Object.keys(ch).length === 0 ? {} : { children: ch };
      z[a[i].ID] = Object.assign(o, a[i]);
    }
  }
  
  return z;
}

console.log(findFor("0"));
&#13;
&#13;
&#13;

答案 1 :(得分:2)

通过尊重父母的单循环非递归方法。

var flat = [{ ID: "1671", parent: "0" }, { ID: "1223", parent: "0" }, { ID: "1668", parent: "0" }, { ID: "1688", parent: "0" }, { ID: "1669", parent: "0" }, { ID: "1681", parent: "1669" }, { ID: "1680", parent: "1669" }, { ID: "1670", parent: "1669" }, { ID: "1682", parent: "1669" }, { ID: "1433", parent: "1682" }, { ID: "1684", parent: "1682" }, { ID: "1672", parent: "1684" }, { ID: "1685", parent: "1672" }, { ID: "1686", parent: "1672" }, { ID: "1683", parent: "0" }, { ID: "1230", parent: "0" }, { ID: "1667", parent: "0" }, { ID: "1687", parent: "0" }],
    tree = function (data, root) {
        var o = {};
        data.forEach(function(a) {
            a = Object.assign({}, a);
            if (o[a.ID] && o[a.ID].children) {
                a.children = o[a.ID].children;
            }
            o[a.ID] = { [a.ID]: a };
            o[a.parent] = o[a.parent] || {};
            o[a.parent][a.parent] = o[a.parent][a.parent] || {};
            o[a.parent][a.parent].children = o[a.parent][a.parent].children || {};
            o[a.parent][a.parent].children[a.ID] = a;
        });
        return o[root][root].children;
    }(flat, '0');

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }