Javascript从平面对象创建嵌套对象

时间:2017-05-15 20:26:58

标签: javascript jquery arrays json

我正在尝试创建一个层次结构,以便我可以将数据传递给我用来生成组织结构图的插件。

对于我的组织结构图,我拥有需要处理的所有数据,例如员工和一些基本数据。

FirstName
LastName
EmployeeID
ManagerEmployeeID
Manager Name

这些数据存储在一个没有嵌套或不同级别之间链接的数组中,这正是我试图通过一些jquery / javascript实现的。

我的目标是获取此数组并基于ManagerIDEmployeeID将其嵌套,以便我可以创建树层次结构。

我无法更改向我提供数据的方式,否则我会从数据库响应中嵌套数据。

示例数据:

•   Tom Jones
   o    Alice Wong
   o    Tommy J.
•   Billy Bob
   o    Rik A.
     ♣  Bob Small
     ♣  Small Jones
   o    Eric C.

我的平面数据示例:

    {
        "FirstName": "Tom"
        "LastName": "Jones"
        "EmployeeID": "123"
        "ManagerEmployeeID": ""
        "Manager Name": ""
    },
    {
        "FirstName": "Alice"
        "LastName": "Wong"
        "EmployeeID": "456"
        "ManagerEmployeeID": "123"
        "Manager Name": "Tom Jones"
    },
    {
        "FirstName": "Tommy"
        "LastName": "J."
        "EmployeeID": "654"
        "ManagerEmployeeID": "123"
        "Manager Name": "Tom Jones"
    },
    {
        "FirstName": "Billy"
        "LastName": "Bob"
        "EmployeeID": "777"
        "ManagerEmployeeID": ""
        "Manager Name": ""
    },
    {
        "FirstName": "Rik"
        "LastName": "A."
        "EmployeeID": "622"
        "ManagerEmployeeID": "777"
        "Manager Name": "Billy Bob"
    },
    {
        "FirstName": "Bob"
        "LastName": "Small"
        "EmployeeID": "111"
        "ManagerEmployeeID": "622"
        "Manager Name": "Rik A."
    },
    {
        "FirstName": "Small"
        "LastName": "Jones"
        "EmployeeID": "098"
        "ManagerEmployeeID": "622"
        "Manager Name": "Rik A"
    },
    {
        "FirstName": "Eric"
        "LastName": "C."
        "EmployeeID": "222"
        "ManagerEmployeeID": "777"
        "Manager Name": "Billy Bob"
    }

示例所需输出:

{
    "FirstName": "Tom",
    "LastName": "Jones",
    "EmployeeID": "123",
    "ManagerEmployeeID": "",
    "Manager Name": "",
    {
        "FirstName": "Alice",
        "LastName": "Wong",
        "EmployeeID": "456",
        "ManagerEmployeeID": "123",
        "Manager Name": "Tom Jones",

    },
    {
        "FirstName": "Tommy",
        "LastName": "J.",
        "EmployeeID": "654",
        "ManagerEmployeeID": "123",
        "Manager Name": "Tom Jones",

    },

},
{
    "FirstName": "Billy",
    "LastName": "Bob",
    "EmployeeID": "777",
    "ManagerEmployeeID": "",
    "Manager Name": "",
    {
        "FirstName": "Rik",
        "LastName": "A.",
        "EmployeeID": "622",
        "ManagerEmployeeID": "777",
        "Manager Name": "Billy Bob",
        ,
        {
            "FirstName": "Bob",
            "LastName": "Small",
            "EmployeeID": "111",
            "ManagerEmployeeID": "622",
            "Manager Name": "Rik A.",

        },
        {
            "FirstName": "Small",
            "LastName": "Jones",
            "EmployeeID": "098",
            "ManagerEmployeeID": "622",
            "Manager Name": "Rik A",

        },

    },

},
{
    "FirstName": "Eric",
    "LastName": "C.",
    "EmployeeID": "222",
    "ManagerEmployeeID": "777",
    "Manager Name": "Billy Bob",

}

有没有最佳做法来完成这样的事情?如果我有能力在数据库级别上执行此操作,我会的。但是,我只有一个数据列表以及基于ID的经理和员工之间的腐蚀。

3 个答案:

答案 0 :(得分:4)

您可以使用reduce()创建递归函数,并返回所需的数据结构。

var data = [{"FirstName":"Tom","LastName":"Jones","EmployeeID":"123","ManagerEmployeeID":"","Manager Name":""},{"FirstName":"Alice","LastName":"Wong","EmployeeID":"456","ManagerEmployeeID":"123","Manager Name":"Tom Jones"},{"FirstName":"Tommy","LastName":"J.","EmployeeID":"654","ManagerEmployeeID":"123","Manager Name":"Tom Jones"},{"FirstName":"Billy","LastName":"Bob","EmployeeID":"777","ManagerEmployeeID":"","Manager Name":""},{"FirstName":"Rik","LastName":"A.","EmployeeID":"622","ManagerEmployeeID":"777","Manager Name":"Billy Bob"},{"FirstName":"Bob","LastName":"Small","EmployeeID":"111","ManagerEmployeeID":"622","Manager Name":"Rik A."},{"FirstName":"Small","LastName":"Jones","EmployeeID":"098","ManagerEmployeeID":"622","Manager Name":"Rik A"},{"FirstName":"Eric","LastName":"C.","EmployeeID":"222","ManagerEmployeeID":"777","Manager Name":"Billy Bob"}];

function makeTree(data, parentId) {
  return data.reduce(function(r, e) {
    if (e.ManagerEmployeeID == parentId) {
      var employees = makeTree(data, e.EmployeeID);
      if (employees.length) e.employees = employees
      r.push(e)
    }
    return r;
  }, [])
}

console.log(makeTree(data, ''))

答案 1 :(得分:0)

所需的输出不是javascript的有效数据结构。你需要该对象中的一些键指向“孩子”。对于解决方案 - 通常您遍历整个对象保存ID作为对象中的键,其余作为给定id的值。例如

let tree = {}
flat.forEach(function(item) {
  item.children = [];
  tree[item.id] = item // build whole tree 

  // in case it is ordered by parent, you can use
  tree[item.parentId].children.push(item);
})
// in case it is not ordered, you have to traverse the structure again
flat.forEach(function(item) {
  tree[item.parentId].children.push(item);
})

答案 2 :(得分:0)

您可以使用单循环方法并检查父母,即ManagerEmployeeID和孩子。

此提案也适用于未分类的数据,无需递归。

var data = [{ FirstName: "Tom", LastName: "Jones", EmployeeID: "123", ManagerEmployeeID: "", "Manager Name": "" }, { FirstName: "Alice", LastName: "Wong", EmployeeID: "456", ManagerEmployeeID: "123", "Manager Name": "Tom Jones" }, { FirstName: "Tommy", LastName: "J.", EmployeeID: "654", ManagerEmployeeID: "123", "Manager Name": "Tom Jones" }, { FirstName: "Billy", LastName: "Bob", EmployeeID: "777", ManagerEmployeeID: "", "Manager Name": "" }, { FirstName: "Rik", LastName: "A.", EmployeeID: "622", ManagerEmployeeID: "777", "Manager Name": "Billy Bob" }, { FirstName: "Bob", LastName: "Small", EmployeeID: "111", ManagerEmployeeID: "622", "Manager Name": "Rik A." }, { FirstName: "Small", LastName: "Jones", EmployeeID: "098", ManagerEmployeeID: "622", "Manager Name": "Rik A" }, { FirstName: "Eric", LastName: "C.", EmployeeID: "222", ManagerEmployeeID: "777", "Manager Name": "Billy Bob" }],
    tree = function (data, root) {
        var r = [],
            o = {};

        data.forEach(function (a) {
            a.children = o[a.EmployeeID] && o[a.EmployeeID].children;
            o[a.EmployeeID] = a;
            if (a.ManagerEmployeeID === root) {
                r.push(a);
            } else {
                o[a.ManagerEmployeeID] = o[a.ManagerEmployeeID] || {};
                o[a.ManagerEmployeeID].children = o[a.ManagerEmployeeID].children || [];
                o[a.ManagerEmployeeID].children.push(a);
            }
        });
        return r;
    }(data, '');

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

问题是,您需要指定root,在这种情况下为MgrQID: "5555",其中"5555"是调用函数的根值

tree = function (data, root) {
    // code
}(data, "5555");
//      ^^^^^^

var data = [{ QID: "1234", MgrQID: "5555", PositionTitle: "Manager, Systems Administration 3" }, { QID:"5678", MgrQID: "1234", PositionTitle: "Systems Administrator 3" }],
    tree = function (data, root) {
        var r = [],
            o = {};

        data.forEach(function (a) {
            a.children = o[a.QID] && o[a.QID].children;
            o[a.QID] = a;
            if (a.MgrQID === root) {
                r.push(a);
            } else {
                o[a.MgrQID] = o[a.MgrQID] || {};
                o[a.MgrQID].children = o[a.MgrQID].children || [];
                o[a.MgrQID].children.push(a);
            }
        });
        return r;
    }(data, "5555");

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