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

React+TypeScript开发:如何扁平化含子分类的对象数组

React + TypeScript 嵌套分类数组扁平化实现

类型定义

先统一定义分类项的TypeScript类型,适配父项与子项的结构:

interface CategoryItem {
  id: string;
  name: string;
  subCategories?: CategoryItem[];
}

实现方法

方法一:Array.reduce递归处理

利用数组reduce方法简洁构建结果数组:

const flattenCategories = (categories: CategoryItem[]): CategoryItem[] => {
  return categories.reduce((acc, item) => {
    // 将当前父项加入结果
    acc.push(item);
    // 处理子分类:移除subCategories后递归扁平化
    if (item.subCategories) {
      const flattenedSubs = item.subCategories.map(sub => {
        const { subCategories, ...rest } = sub;
        return rest;
      });
      acc.push(...flattenCategories(flattenedSubs));
    }
    return acc;
  }, [] as CategoryItem[]);
};

方法二:forEach循环+递归(直观易读)

如果觉得reduce逻辑不够直观,可使用forEach配合递归函数处理:

const flattenCategories = (categories: CategoryItem[]): CategoryItem[] => {
  const result: CategoryItem[] = [];

  const processItem = (item: CategoryItem) => {
    // 添加父项到结果
    result.push(item);
    // 遍历处理所有子项
    item.subCategories?.forEach(sub => {
      // 移除subCategories后添加子项
      const { subCategories, ...subItem } = sub;
      result.push(subItem);
      // 若子项还有嵌套分类,递归处理
      if (sub.subCategories) {
        processItem(sub);
      }
    });
  };

  categories.forEach(processItem);
  return result;
};

测试示例

// 原始嵌套数据
const originalData: CategoryItem[] = [
  {
    id: "item1",
    name: "foo",
    subCategories: [
      { id: "item1-1", name: "bar1" },
      { id: "item1-2", name: "bar2" }
    ]
  },
];

// 执行扁平化处理
const flattenedData = flattenCategories(originalData);

处理后输出结果符合需求:

[
  { id: "item1", name: "foo", subCategories: [...] },
  { id: "item1-1", name: "bar1" },
  { id: "item1-2", name: "bar2" }
]

扩展说明

上述两种方法均支持多层嵌套的分类结构,无论子项是否包含自身的subCategories,都会自动递归扁平化到一维数组中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:02:52