
本文介绍多种简洁高效的方式,将包含一个对象的数组转换为按字段分组的三个对象组成的数组,涵盖解构赋值、flatmap 和对象简写等现代 javascript 技巧。
本文介绍多种简洁高效的方式,将包含一个对象的数组转换为按字段分组的三个对象组成的数组,涵盖解构赋值、flatmap 和对象简写等现代 javascript 技巧。
在实际开发中,我们常需对 API 返回的扁平化数据结构进行语义化重组。例如,原始响应 res.data 仅含一个对象,但业务逻辑要求将其字段按功能划分为三类:基础连接信息(name/ipaddr/port)、SSH 认证信息(sshuser/sshpass/sshport)和授权信息(license),最终生成一个由三个独立对象构成的新数组。
以下是三种推荐实现方式,兼顾可读性、简洁性与扩展性:
✅ 方式一:使用解构 + 对象简写(最简洁,适用于单元素场景)
const res = {
data: [{
name: 'c2',
ipaddr: '192.168.1.5',
port: 4435,
sshuser: "abc",
sshpass: "xyz",
sshport: 22,
license: 'license.txt',
}]
};
// 一行解构 + 三行对象字面量(利用属性名缩写)
const [{ name, ipaddr, port, sshuser, sshpass, sshport, license }] = res.data;
const newState = [
{ name, ipaddr, port },
{ sshuser, sshpass, sshport },
{ license }
];
✅ 优势:语法极简、语义清晰、性能最优;
⚠️ 注意:仅适用于 res.data 确保有且仅有一个对象(否则需加校验)。
✅ 方式二:使用 flatMap()(支持多元素数组,更具扩展性)
const newState = res.data.flatMap(
({ name, ipaddr, port, sshuser, sshpass, sshport, license }) => [
{ name, ipaddr, port },
{ sshuser, sshpass, sshport },
{ license }
]
);
✅ 优势:天然兼容 res.data 包含多个对象的场景(如后续接口返回批量设备);
? 提示:若 res.data 为空数组,flatMap 会安全返回空数组,无需额外判空。
✅ 方式三:函数封装 + 显式映射(提升复用性与可维护性)
const splitDeviceConfig = (device) => [
{ name: device.name, ipaddr: device.ipaddr, port: device.port },
{ sshuser: device.sshuser, sshpass: device.sshpass, sshport: device.sshport },
{ license: device.license }
];
const newState = res.data.map(splitDeviceConfig).flat();
// 或直接:const newState = res.data.flatMap(splitDeviceConfig);
✅ 优势:逻辑分离、便于单元测试、字段变更时只需修改一处;
? 建议:当字段分组规则复杂或需动态配置时,此方式更稳健。
⚠️ 注意事项
- 避免使用
var声明变量,统一采用const(不可变引用)或let(需重赋值); - 若原始数据结构不稳定(如某些字段可能缺失),应在解构时提供默认值,例如
sshport = 22; -
flatMap是 ES2019 特性,如需兼容旧环境(如 IE),可用map().flat()替代(需确保flat()可用)或手动reduce实现。
无论选择哪种方式,核心思想都是通过解构提取字段,再按语义分组构造新对象。根据项目规模、数据确定性及团队规范,合理选用即可。










