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

如何在JavaScript中扁平化数组时分组匹配的嵌套子数组?

问题描述

从API获取到一组汽车品牌数据,需要将其转换为带分组属性的扁平化格式:以汽车品牌(carMake)、轮胎尺寸(size)、轮胎宽度(width)作为分组依据,当这三个属性都匹配时合并记录,把对应轮胎品牌合并到一个数组中,同时保留其他关联字段。

原始API响应数据

[
    {
        carMake: 'Ford',
        tires: [
            {
                brand: 'Dunlap',
                otherKey: 'aaa',
                size: 33,
                width: 12,
            },
            {
                brand: 'Good Year',
                size: 33,
                width: 12,
            },
            {
                brand: 'Continental',
                size: 33,
                width: 11,
            },
            {
                brand: 'Pirelli',
                size: 32,
                width: 12,
            }
        ]
    },
    {
        carMake: 'Chevy',
        tires: [
            {
                brand: 'Dunlap',
                size: 33,
                width: 12,
            },
        ]
    }
]

期望转换结果

[
    {
        carMake: 'Ford',
        otherKey: 'aaa',
        brands: ['Dunlap', 'Good Year'],
        size: 33,
        width: 12,
    },
    {
        carMake: 'Ford',
        brands: ['Continental'],
        size: 33,
        width: 11,
    },
    {
        carMake: 'Ford',
        brands: ['Pirelli'],
        size: 32,
        width: 12,
    },
    {
        carMake: 'Chevy',
        brands: ['Dunlap'],
        size: 33,
        width: 12,
    }
]

已尝试的代码

仅完成了第一层扁平化,未实现分组合并:

apiResponse.flatMap(({carMake, tires}) => tires.map((tire) => ({ carMake, ...tire })));

解决方案

通过扁平化数据 → 分组聚合 → 格式化输出三步实现需求:

1. 扁平化数据

先把嵌套的轮胎数据展开,每条记录带上对应汽车品牌:

const flatData = apiResponse.flatMap(({ carMake, tires }) => 
  tires.map(tire => ({ carMake, ...tire }))
);

2. 分组聚合

用reduce方法,以carMake-size-width作为唯一分组键,合并同组的轮胎品牌,同时保留其他字段(取同组第一条记录的对应值):

const grouped = flatData.reduce((acc, item) => {
  // 生成唯一分组标识
  const key = `${item.carMake}-${item.size}-${item.width}`;
  if (!acc[key]) {
    // 首次创建分组,初始化结构
    acc[key] = {
      carMake: item.carMake,
      size: item.size,
      width: item.width,
      brands: [item.brand],
      // 仅当存在时保留额外字段
      ...(item.otherKey && { otherKey: item.otherKey })
    };
  } else {
    // 已有分组,追加品牌到数组
    acc[key].brands.push(item.brand);
  }
  return acc;
}, {});

3. 转换为数组格式

将分组后的对象转为最终的数组结构:

const result = Object.values(grouped);

完整代码
const apiResponse = [
    { carMake: 'Ford', tires: [{ brand: 'Dunlap', otherKey: 'aaa', size: 33, width: 12 }, { brand: 'Good Year', size: 33, width: 12 }, { brand: 'Continental', size: 33, width: 11 }, { brand: 'Pirelli', size: 32, width: 12 }] },
    { carMake: 'Chevy', tires: [{ brand: 'Dunlap', size: 33, width: 12 }] }
];

const flatData = apiResponse.flatMap(({ carMake, tires }) => 
  tires.map(tire => ({ carMake, ...tire }))
);

const grouped = flatData.reduce((acc, item) => {
  const key = `${item.carMake}-${item.size}-${item.width}`;
  if (!acc[key]) {
    acc[key] = {
      carMake: item.carMake,
      size: item.size,
      width: item.width,
      brands: [item.brand],
      ...(item.otherKey && { otherKey: item.otherKey })
    };
  } else {
    acc[key].brands.push(item.brand);
  }
  return acc;
}, {});

const result = Object.values(grouped);
console.log(result);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:01:02