You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript高效转换JSON结构?请求排查代码问题

解决JSON数组按分类合并子分类的问题

首先咱们先看看你现有代码的问题:
你用forEach遍历每一项的时候,每次都新建了一个category对象并直接push到dataArr里,完全没做「判断当前分类是否已经存在」的操作。所以原来的4条数据会生成4个独立的对象,自然没法把同分类的子项合并到一起啦。

接下来给你一个高效的实现方式,用Array.reduce()来做分组合并,这是处理这类结构转换的常用方法:

let result = [
  { "category": "Social Media", "category_id": 6, "sub_category": "Facebook", "sub_category_id": 5 },
  { "category": "Social Media", "category_id": 6, "sub_category": "Instagram", "sub_category_id": 7 },
  { "category": "Tech", "category_id": 3, "sub_category": "Angular", "sub_category_id": 1 },
  { "category": "Tech", "category_id": 3, "sub_category": "Javascript", "sub_category_id": 6 }
];

// 用reduce进行分组合并
const mergedResult = result.reduce((acc, current) => {
  // 先根据category_id查找是否已经存在该分类
  const existingCategory = acc.find(item => item.category_id === current.category_id);
  
  if (existingCategory) {
    // 如果存在,就把当前子分类push到对应的sub_category数组里
    existingCategory.sub_category.push({
      sub_category: current.sub_category,
      sub_category_id: current.sub_category_id
    });
  } else {
    // 如果不存在,就新建一个分类对象,把当前子分类作为初始项
    acc.push({
      category: current.category,
      category_id: current.category_id,
      sub_category: [{
        sub_category: current.sub_category,
        sub_category_id: current.sub_category_id
      }]
    });
  }
  
  return acc;
}, []); // 初始值是空数组

console.log(mergedResult);

代码逻辑说明:

  1. reduce的第一个参数是累积函数,acc是我们最终要生成的结果数组,current是当前遍历到的元素。
  2. 每次遍历先检查acc里是否已经存在相同category_id的分类:
    • 存在的话,直接把当前子分类追加到它的sub_category数组中;
    • 不存在的话,创建一个新的分类对象,把当前子分类作为sub_category的初始元素,再加入到acc里。
  3. 最后返回累积的结果数组,就是你想要的嵌套结构啦。

如果你的数据量很大,用find可能效率稍低,可以优化成用对象做映射(以category_id为键),最后再把对象的值转成数组,这样查找的时间复杂度是O(1),更高效:

const mergedResult = Object.values(result.reduce((map, current) => {
  const id = current.category_id;
  if (!map[id]) {
    map[id] = {
      category: current.category,
      category_id: id,
      sub_category: []
    };
  }
  map[id].sub_category.push({
    sub_category: current.sub_category,
    sub_category_id: current.sub_category_id
  });
  return map;
}, {}));

这个版本先用对象做中间映射,避免了每次find的遍历,数据量大的时候性能会更好~

内容的提问来源于stack exchange,提问作者Sangram Badi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 21:43:12