首页 > 解决方案 > 如何从 JSON 数据构建树?通过使用任何编程语言修改如下所示的条目

问题描述

输入:

const data = [
  {
    category: 'Techonology',
    subcategory: 'laptop',
    sale: 19000,
    profit: 909049,
  },
  {
    category: 'Furniture',
    subcategory: 'badge',
    sale: 2009900,
    profit: 699600,
  },
  {
    category: 'Techonology',
    subcategory: 'chair',
    sale: 30000,
    profit: 500,
  },
  {
    category: 'Furniture',
    subcategory: 'bed',
    sale: 400,
    profit: 200000,
  },
]

输出应如下所示:

{
  "name": "data",
  "children": [
    {
      "name": "Techonology",
      "children": [
        {
          "name": "laptop",
          "children": [
            {
              "name": "sale",
              "value": 19000
            }
          ]
        },
        {
          "name": "chair",
          "children": [
            {
              "name": "sale",
              "value": 30000
            }
          ]
        }
      ]
    },
    {
      "name": "Furniture",
      "children": [
        {
          "name": "badge",
          "children": [
            {
              "name": "sale",
              "value": 2009900
            }
          ]
        },
        {
          "name": "bed",
          "children": [
            {
              "name": "sale",
              "value": 400
            }
          ]
        }
      ]
    }
  ]
}

标签: javascriptjson

解决方案


我假设您从某个站点获取数据,该结构已经定义并且无法更改。我建议您将结构更改为更易于管理的另一种方法。

无论如何,无论是否遵循你的结构,当你需要构建一棵树时,你必须递归地工作,以获得最深的结构并正确定义你需要的东西。

请记住这一点:

  • 在您的结构中,每个项目只有一个子类别,但您可以拥有许多具有相同父类别的条目,其中唯一的变化是子类别元素,这不是最优的。
  • 由于结构已经定义,我认为最好在武装树结构之前对其进行处理和重新排序
  • 为了获得一个完整的示例,我修改了您的数据结构,添加了两个子元素,因为您拥有的一些“子类别”没有出现在那里。

所以,我使用的结构是:

var data1 = [
  {
    category: 'Techonology',
    subcategory: 'laptop',
    sale: 19000,
    profit: 909049,
  },
  {
    category: 'badge',
    sale: 19000,
    profit: 909049,
  },

  {
    category: 'childrenchair',
    sale: 19000,
    profit: 909049,
  },
  {
    category: 'chair',
    subcategory: 'childrenchair',
    sale: 19000,
    profit: 909049,
  },
  {
    category: 'Furniture',
    subcategory: 'badge',
    sale: 2009900,
    profit: 699600,
  },
  {
    category: 'Techonology',
    subcategory: 'chair',
    sale: 30000,
    profit: 500,
  },
  {
    category: 'Furniture',
    subcategory: 'bed',
    sale: 400,
    profit: 200000,
  },
]

下面的代码定义了树结构:

// loops the data to get all subcategory elements, this is used to
// avoid unnecessary iterations.
allChildren = data1.map(item=> item.subcategory).filter(item => !!item);
// this map has the data with the structure we need
preparedData = new Map()
data1.forEach(item => {
    console.log(1, item.category, item.subcategory);
    const data = preparedData.get(item.category) ?? {children: []};
    data.isChildren = allChildren.includes(item.category);
    if(item.subcategory) data.children.push(item.subcategory);
    preparedData.set(item.category, Object.assign(item, data));
});


tree = [];
/**
 getChildren method is recursive, it will be called for each category or subcategory with children's (recursively)

*/
getChildren = item=> {
    const children = item.children.filter(item=> {
        if(!preparedData.has(item)) return;
        const data = preparedData.get(item);

        const {category: name, sale, profit} = data;
        subchildren = data.children.length ? getChildren(item) : [];
        return {name, sale, profit, children: subchildren};

    });
    return children;
};
// loop the data
preparedData.forEach(item=>{
    // it the item has the property isChildren as true, then is a subcategory and
    // is not necessary to check it in the first level of the tree

  
    if(item.isChildren) return;
    const {category: name, sale, profit} = item;
    children = item.children.length ? getChildren(item) : [];
    tree.push({name, sale, profit, children});
});

我在 devtools 控制台中检查了此代码并运行,您可以将其复制并粘贴以进行检查,然后进行所需的调整


推荐阅读