将平面列表转换为父子树

时间:2019-04-22 13:48:31

标签: javascript arrays

我正在尝试从一个平面列表中构建一棵树,并且我知道我缺少一些东西,这会使它变得更加容易和快捷。我尝试了几种方法。最新的功能是我在下面发布的功能。

看起来像这样的平面列表:

var input = [
  {
    "Parent Category": "Agricultural Feed + Seed",
    Category: "Agricultural Feed + Seed",
    Name: "Agfinity"
  },
  {
    "Parent Category": "Agricultural Feed + Seed",
    Category: "Agricultural Feed + Seed",
    Name: "Agland Co-op"
  },
  {
    "Parent Category": "Agricultural Feed + Seed",
    Category: "Agricultural Equipment",
    Name: "Agri Supply"
  },
  {
    "Parent Category": "Agricultural Equipment",
    Category: "Tractors",
    Name: "Agway"
  },
  {
    "Parent Category": "Agricultural Equipment",
    Category: "Tractors",
    Name: "Agway2"
  },
  {
    "Parent Category": "Travel",
    Category: "Travel",
    Name: "Amtrak"
  },
  {
    "Parent Category": "Travel",
    Category: "Accessories",
    Name: "Bentley Leathers & Luggage"
  }
];

从此列表中,我正在尝试构建如下所示的树:

[
  {
    "label": "Agricultural Feed + Seed",
    "children": [
      {
        "label": "Agfinfity"
      },
      {
        "label": "Agland Co-op"
      },
      {
        "label": "Agricultural Equipment",
        "children": [
          {
            "label": "Agri Supply"
            "children": [
              {
                "label": "Tractors",
                "children": [
                  {
                    "label": "Agway"
                  },
                  {
                    "label": "Agway2"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "label": "Travel",
    "children": [
      {
        "label": "Amtrak"
      },
      {
        "label": "Acessories",
        "children": [
          {
            "label": "Bentley Leathers & Luggage"
          },
      }
    ]
  }
];

我有一个几乎可以正常工作的函数,但是我知道这不是正确的方法。


    function formatBrandNames(rawBrands) {
      let output = [];

      for (let i = 0; i < rawBrands.length; i++) {
        // Parent Category
        if (!output.find(v => v.label === rawBrands[i]["Parent Category"])) {
          output.push({
            label: rawBrands[i]["Parent Category"],
            children: []
          });
        }

        // Category
        let parentCat = output.find(v => v.label === rawBrands[i]["Parent Category"]);
        if (rawBrands[i]["Category"] === parentCat.label) {
          const name = trimBrandNumbers(rawBrands[i]["Name"]);

          parentCat.children.push({ label: name });
          continue;
        }
        if (!parentCat.children.find(v => v.label === rawBrands[i]["Category"])) {
          parentCat.children.push({ label: rawBrands[i]["Category"], children: [] });
        }

        // Name
        let cat = parentCat.children.find(v => v.label === rawBrands[i]["Category"]);
        const name = trimBrandNumbers(rawBrands[i]["Name"]);

        cat.children.push({ label: name });
      }

      return output;
    }

对此将提供任何帮助或见解。

1 个答案:

答案 0 :(得分:1)

逻辑可以简化为

如果节点没有父类别,则它是根类别之一

按父类别找到父节点,然后将该节点添加到父节点的子节点中

如果父级不存在,请创建它。

 function toTree(nodes) {
   const roots = [];
   const byCategory = new Map();

   for(const { Name: label, ["Parent Category"]: parent, Category: category } of nodes) {
     const node = { label, children: [] };

     if(byCategory.has(category)) {
        byCategory.get(category).children.push(node);     
     } else {
         const categoryObj = {
           label: category,
           children: [node]
         };

         byCategory.set(category, categoryObj);

         if(parent === category) {
           roots.push(categoryObj);
        } else if(byCategory.has(parent)) {
           byCategory.get(parent).children.push(categoryObj);
        } else {
           byCategory.set(parent, { label: parent, children: [categoryObj] });
        }
     } 


   }

   return roots;
 }