本文介绍一种使用 map 与对象遍历结合的方式,将含 items 数组(每个 item 是 { [key]: string, quantity: number } 结构)的原始对象数组,转换为每个对象直接以产品名为属性、数量为值的新数组。
在实际开发中,我们常遇到数据结构嵌套较深的场景:例如订单列表中每个订单包含多个商品项(items),而每项又以动态字段名(如 productOne、productTwo)标识商品类型,quantity 表示数量。此时若需将 items “展开”为同级属性(如 crust: 2.2, dust: 34),就需要一次语义清晰、可维护性强的扁平化处理。
核心思路是:对原数组每一项执行 map,创建新对象副本 → 遍历其 items 数组 → 对每个 item 动态提取非 quantity 字段作为属性名,quantity 值作为对应属性值 → 最后删除 items 字段,返回精简后的对象。
以下是推荐实现(已优化可读性与健壮性):
function flattenItems(arr) {
return arr.map(item => {
// 浅拷贝原对象,避免污染源数据
const flattened = { ...item };
// 遍历 items 数组
for (const entry of item.items || []) {
// 遍历 entry 的每个键,识别 product 字段和 quantity
let productName = null;
let quantityValue = null;
for (const key in entry) {
if (key === 'quantity') {
quantityValue = entry[key];
} else if (typeof entry[key] === 'string') {
productName = entry[key];
}
}
// 安全赋值:仅当两者均存在时才挂载到结果对象
if (productName !== null && quantityValue !== undefined) {
flattened[productName] = quantityValue;
}
}
// 移除原始 items 字段
delete flattened.items;
return flattened;
});
}
// 示例输入
const firstArray = [
{
amount: 343,
code: "RCU8YI0NKS",
items: [
{ productOne: "crust", quantity: 2.2 },
{ productTwo: "dust", quantity: 34 }
],
user_id: "wewewefwOHG22323kj"
},
{
amount: 343,
code: "RCU8YI0NKS",
items: [
{ productTwo: "dust", quantity: 32 },
{ productThree: "must", quantity: 34 }
],
u
ser_id: "m2LgLRD9MEVNAX56JTpRYDkOOjd2"
}
];
console.log(flattenItems(firstArray));
// 输出即为目标格式 secondArray✅ 注意事项:
此方案简洁、可读、可扩展,适用于中后台数据聚合、报表生成及 API 响应适配等典型场景。