Javascript - 从平面数组动态生成无限嵌套数组

Javascript - dynamically generate an infinitely nested Array from a flat Array

我有一个员工列表,我通过 AJAX 从服务器端请求获得,这个列表中的每个项目都是它下面的项目的父项,除了最后一个子项,所以在客户端,我最终得到一个 JavaScript 数组,如下所示:

data = [
{ FirstName: "John", LastName: "Doe", Position: "Manager", ID: "5656" },
{ FirstName: "Sam", LastName: "Doe", Position: "Sale", ID: "654654" },
{ FirstName: "Sarah", LastName: "Doe", Position: "Employee", ID: "6541" },
{ FirstName: "Sally", LastName: "Doe", Position: "Clerk", ID: "8754" },
{ FirstName: "Joe", LastName: "Doe", Position: "Clerk", ID: "654564" }
];

到目前为止一切顺利,现在我的问题是我想使用 bootstrap-treeview,而这个组件需要一个像这样的 JavaScript 数组:

var tree = [
  {
      text: "John - Manager",
      nodes: [
        {
            text: "Sam - Sale",
            nodes: [
              {
                  text: "Sarah - Employee",
                  nodes: [
                      {
                          text: "Sally - Clerk",
                          nodes: [
                              {
                                  text: "Joe - Clerk"
                              }
                          ]
                      }
                  ]
              }
            ]
        }
      ]
  }
];

我的树不是静态的,所以我必须动态生成它,如何使用 JavaScript 动态生成这样的无限嵌套数组?

此提案的特点是 Array.prototype.reduceRight()

The reduceRight() method applies a function against an accumulator and each value of the array (from right-to-left) has to reduce it to a single value.

var data = [
        { FirstName: "John", LastName: "Doe", Position: "Manager", ID: "5656" },
        { FirstName: "Sam", LastName: "Doe", Position: "Sale", ID: "654654" },
        { FirstName: "Sarah", LastName: "Doe", Position: "Employee", ID: "6541" },
        { FirstName: "Sally", LastName: "Doe", Position: "Clerk", ID: "8754" },
        { FirstName: "Joe", LastName: "Doe", Position: "Clerk", ID: "654564" }
    ],
    tree = data.reduceRight(function (r, a) {
        var o = { text: a.FirstName + ' - ' + a.Position };
        if (r) {
            o.nodes = r;
        }
        return [o];
    }, undefined);

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

或使用Array.prototype.reduce().

The reduce() method applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value.

var data = [
        { FirstName: "John", LastName: "Doe", Position: "Manager", ID: "5656" },
        { FirstName: "Sam", LastName: "Doe", Position: "Sale", ID: "654654" },
        { FirstName: "Sarah", LastName: "Doe", Position: "Employee", ID: "6541" },
        { FirstName: "Sally", LastName: "Doe", Position: "Clerk", ID: "8754" },
        { FirstName: "Joe", LastName: "Doe", Position: "Clerk", ID: "654564" }
    ], tree = [];

data.reduce(function (r, a) {
    var o = { text: a.FirstName + ' - ' + a.Position, nodes: [] };
    r.push(o);
    return o.nodes;
}, tree);

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

这两个提案之间的区别在于第一种情况是从最后一行开始迭代和构建 array/object,而 return 始终是完整的树。

第二个提案的特点是给定数组和 return 对包含的 row/nodes 的引用。建筑方案是从第一排到最后一排,与第一个提案相反。

第二种解决方案的缺点是空数组nodes