forEach遍历数组时如何累加合并动态键值对而非覆盖?
解决JavaScript forEach遍历累加对象键值对的问题
问题描述
我用JavaScript的forEach遍历choosen_products数组时,希望每次循环生成的6个动态命名键值对能累加合并到同一个对象中,但目前每次循环都会覆盖对象,只保留最新的键值对。尝试过merged = { tmp_ff, ff }的合并方式,但得到的merged对象仅包含两个属性,无法实现累加。期望最终对象能包含所有遍历生成的键值对,比如q_p1_fullname、q_p2_fullname等依次累加。
原代码
let ff = {}; let tmp_ff = {}; this.choosen_products.forEach((element, index, array) => { //q_p1_fullname let tmp1 = "q_p"+(index+1)+"_fullname"; //each time, tmp1 key are different let tmp2 = "q_p"+(index+1)+"_code"; let tmp3 = "q_p"+(index+1)+"_category"; let tmp4 = "q_p"+(index+1)+"_cost"; let tmp5 = "q_p"+(index+1)+"_margin"; let tmp6 = "q_p"+(index+1)+"_sell"; console.log(element.p_fullname + " " + element.p_category + " " + tmp1); /* ff.this.tmp1 = element.p_fullname, //I try this, no help ff.this.tmp2 = element.p_code, ff.this.tmp3 = element.p_category, ff.this.tmp4 = element.p_cost, ff.this.tmp5 = element.p_margin, ff.this.tmp6 = element.p_sell, */ tmp_ff = { [tmp1]: element.p_fullname, //works but only the most recent loop, how to merged?? [tmp2]: element.p_code, [tmp3]: element.p_category, [tmp4]: element.p_cost, [tmp5]: element.p_margin, [tmp6]: element.p_sell, }; let merged = { tmp_ff, ff }; Object.keys(tmp_ff).forEach(key => { console.log("[previewBtn-choosen_products2]" + key, tmp_ff[key]); //not cimulative }); console.log("[previewBtn-choosen_products2] " ); // 100, 200, 300 console.log(index); // 0, 1, 2 console.log(array); // same myArray object 3 times bodyData.push(element); console.log("[previewBtn-choosen_products2]" + Object.keys(merged).tmp1); });
解决方案
问题原因
你之前用{ tmp_ff, ff }的方式是创建了一个新对象,其中包含tmp_ff和ff两个子属性,而不是把两个对象的键值对合并到一起,所以无法实现累加。同时每次循环没有更新原本的ff对象,导致旧的键值对被丢弃。
两种解决方法
方法1:直接给ff对象添加动态属性
不需要额外的tmp_ff和merged变量,直接在循环中给ff赋值动态键:
let ff = {}; this.choosen_products.forEach((element, index) => { let tmp1 = `q_p${index+1}_fullname`; let tmp2 = `q_p${index+1}_code`; let tmp3 = `q_p${index+1}_category`; let tmp4 = `q_p${index+1}_cost`; let tmp5 = `q_p${index+1}_margin`; let tmp6 = `q_p${index+1}_sell`; // 直接将动态键值对追加到ff对象 ff[tmp1] = element.p_fullname; ff[tmp2] = element.p_code; ff[tmp3] = element.p_category; ff[tmp4] = element.p_cost; ff[tmp5] = element.p_margin; ff[tmp6] = element.p_sell; bodyData.push(element); }); // 循环结束后ff就是包含所有键值对的最终对象 console.log(ff);
方法2:用Object.assign合并临时对象到ff
如果还是想用临时对象存储当前循环的6个键值对,可以用Object.assign将临时对象的属性合并到ff中:
let ff = {}; this.choosen_products.forEach((element, index) => { let tmp1 = `q_p${index+1}_fullname`; let tmp2 = `q_p${index+1}_code`; let tmp3 = `q_p${index+1}_category`; let tmp4 = `q_p${index+1}_cost`; let tmp5 = `q_p${index+1}_margin`; let tmp6 = `q_p${index+1}_sell`; const tmp_ff = { [tmp1]: element.p_fullname, [tmp2]: element.p_code, [tmp3]: element.p_category, [tmp4]: element.p_cost, [tmp5]: element.p_margin, [tmp6]: element.p_sell, }; // 将tmp_ff的所有键值对合并到ff中,ff会自动累加属性 Object.assign(ff, tmp_ff); bodyData.push(element); }); console.log(ff);
说明
- 两种方法的核心都是更新同一个
ff对象,而不是每次创建新对象。 - 动态键的方括号语法
ff[tmp1]是正确的赋值方式,你之前尝试的ff.this.tmp1是错误的语法。
内容的提问来源于stack exchange,提问作者ZION WONG
相关产品推荐
相关产品推荐

