如何合并JavaScript数组中相同VendorID的对象行?
解决方案
核心思路是按VendorID分组合并对象,补全缺失的月份字段为0,同时保留同一VendorID下非0的原始月份值。
完整代码实现
var testarray = [ { "VendorID": "001", "Jan": "130", "Feb": "500" }, { "VendorID": "001", "Jan": "0", "Feb": "0", "Mar": "1000" }, { "VendorID": "002", "Mar": "20" } ]; // 临时映射表,按VendorID存储合并后的对象 const vendorMap = {}; // 定义需要包含的所有月份字段 const requiredMonths = ['Jan', 'Feb', 'Mar']; testarray.forEach(item => { const vendorId = item.VendorID; // 初始化该VendorID的默认结构:所有月份默认0 if (!vendorMap[vendorId]) { vendorMap[vendorId] = { VendorID: vendorId, Jan: '0', Feb: '0', Mar: '0' }; } // 遍历当前对象的字段,仅覆盖非0的月份值(避免把已有有效数据覆盖成0) Object.keys(item).forEach(key => { if (requiredMonths.includes(key) && item[key] !== '0') { vendorMap[vendorId][key] = item[key]; } }); }); // 将映射表的值转为数组,得到最终结果 var finalarray = Object.values(vendorMap); console.log(finalarray);
代码说明
- 分组存储:用
vendorMap对象按VendorID作为键,确保每个供应商只保留一个合并后的对象。 - 默认值初始化:每个新供应商的对象会先把所有月份设为
0,保证最终数组里每个对象都包含Jan、Feb、Mar三个字段。 - 字段覆盖规则:遍历原始对象的字段时,只替换非
0的月份值,这样像001的Jan和Feb会保留第一个对象的130、500,不会被第二个对象的0覆盖。 - 结果转换:最后用
Object.values()把映射表的所有值提取为数组,就是你要的最终结构。
你原有代码的问题
- 没必要用
$.when:$.each是同步遍历操作,异步包装完全多余。 - 未处理合并逻辑:仅提取了
Jan字段,没有对同一VendorID的对象进行合并,也没补全其他月份字段,所以得不到目标结果。
内容的提问来源于stack exchange,提问作者grabrep gg
相关产品推荐
相关产品推荐

