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

JS/TS如何将含数组属性的对象转换为指定结构的扁平化数组

问题说明

开发中需要将键为id、值为对应消息数组的对象,转换为每条消息携带对应id的扁平数组,期望输出结果如下:

result = [
  {
    id: 'test-1',
    message: 'test#1.1'
  },
  {
    id: 'test-1',
    message: 'test#1.2'
  },
  {
    id: 'test-2',
    message: 'test#2.1'
  },
  {
    id: 'test-2',
    message: 'test#2.2'
  }
]

初始尝试使用Object.keys()搭配map()实现,代码运行结果不符合预期,初始代码如下:

mockData = {
  'test-1': [
    {
      message: 'test#1.1'
    },
    {
      message: 'test#1.2'
    }
  ],
  'test-2': [
    {
      message: 'test#2.1'
    },
    {
      message: 'test#2.2'
    }
  ]
}

const result = Object.keys(this.mockData).map((id) => {
  return {
    id,
    ...this.mockData[id],
  }
})

console.log(result)
错误原因分析
  • 你判断的方向完全正确:当前写法的核心问题是没有对this.mockData[id]对应的消息数组做二次遍历。
  • 直接展开数组到对象中时,JS会把数组的数字索引作为对象的键,最终生成的结构是{id: 'test-1', 0: {message: 'test#1.1'}, 1: {message: 'test#1.2'}},外层map返回的是长度为2的数组,和你需要的长度为4的扁平数组结构完全不匹配。
可行实现方案

没有绝对的最佳实现,你可以根据团队代码规范选择以下任意一种写法:

方案1:flatMap 链式实现

最简洁的链式写法,flatMap会自动将内层遍历返回的数组做一层拍平,不需要额外调用flat:

const result = Object.keys(mockData).flatMap(id => 
  mockData[id].map(msgItem => ({id, ...msgItem}))
)

方案2:reduce 实现

不需要做数组拍平,遍历过程中直接把组装好的对象推入结果数组,性能和可读性都很好:

const result = Object.entries(mockData).reduce((res, [id, msgList]) => {
  msgList.forEach(msg => res.push({id, ...msg}))
  return res
}, [])

两种写法运行后都会得到你期望的结果结构。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 08:51:59