如何用循环合并JS同键嵌套数组?数组重组最优方法
解决方案:合并同品牌的分散对象
嘿,针对你提出的两个问题,我来一步步给你讲清楚怎么实现:
问题1:用循环实现合并
如果一定要用循环来做,核心思路是先借助一个临时对象缓存每个品牌的合并结果,然后遍历原始数组把属性逐个合并进去,最后再把临时对象转成目标数组。
首先先把你的原始数组修正成合法的JavaScript格式(你原来的写法不符合JS语法规范):
const brands = [ { name: "ZARA", product: "ZARA Black Shiny Shirt" }, { name: "ZARA", fit: "Slim Fit" }, { name: "ZARA", size: "46" }, { name: "H&M", product: "H&M Black Shirt" }, { name: "H&M", fit: "Regular Fit" }, { name: "H&M", size: "44" } ];
然后是循环实现的代码:
// 临时对象,用来缓存每个品牌的合并结果 const brandMap = {}; // 遍历原始数组 for (const item of brands) { const brandName = item.name; // 如果这个品牌还没在缓存里,先初始化一个带name的空对象 if (!brandMap[brandName]) { brandMap[brandName] = { name: brandName }; } // 把当前item的所有属性合并到缓存对象里 Object.assign(brandMap[brandName], item); } // 把临时对象的值转成数组,就是目标结果 const mergedBrands = Object.values(brandMap); console.log(mergedBrands);
这段代码会输出你想要的结构:每个品牌对应一个整合了所有属性的对象,放在数组里。
问题2:最优实现方式
在JavaScript里,**Array.reduce()**是处理这类数组重组合并的最优方式之一——代码更简洁,逻辑清晰,而且是原生方法不需要额外依赖。
用reduce实现的基础版本代码如下:
const mergedBrands = brands.reduce((acc, current) => { // 查找当前品牌在累加器中是否已存在 const existingBrand = acc.find(item => item.name === current.name); if (existingBrand) { // 存在则合并属性 Object.assign(existingBrand, current); } else { // 不存在则将当前对象加入累加器 acc.push({ ...current }); } return acc; }, []); // 初始值为一个空数组 console.log(mergedBrands);
如果数组数据量较大,追求更高性能的话,可以结合临时对象的思路优化reduce,避免每次用find遍历数组(时间复杂度从O(n²)降到O(n)):
const mergedBrands = Object.values( brands.reduce((acc, current) => { const brandName = current.name; // 合并属性:若缓存中无该品牌则创建新对象,否则合并现有属性 acc[brandName] = { ...(acc[brandName] || {}), ...current }; return acc; }, {}) );
不管用哪种方式,最终都能得到你期望的输出结构:
[ { name: "ZARA", product: "ZARA Black Shiny Shirt", fit: "Slim Fit", size: "46" }, { name: "H&M", product: "H&M Black Shirt", fit: "Regular Fit", size: "44" } ]
内容的提问来源于stack exchange,提问作者Rahul Jat
相关产品推荐
相关产品推荐

