如何更新JavaScript Map中存储为值的数组?分组对象遇push报错
问题:使用JavaScript Map分组对象数组时存储数组长度而非数组,调用push报错
我尝试用JavaScript的Map存储数组,想把对象数组按对象的"last"键分组,但存储的总是数组长度而非数组本身,后续调用.push()还会抛出错误。
控制台日志
[] [] [] 1
控制台报错
Uncaught TypeError: acc.get(...).push is not a function at ():15:45 at Array.reduce () at :10:27
示例代码
let names = [ {first: "John", last: "Smith", age: 12}, {first: "Jessica", last: "Jones", age: 22}, {first: "Lois", last: "Lane", age: 32}, {first: "Joe", last: "Smith", age: 42}, {first: "Jenny", last: "Jones", age: 52}, {first: "Mary", last: "Smith", age: 62} ]; let grouppedArray = names.reduce(function(acc, cv) { if (!acc.has(cv["last"])) { acc.set(cv["last"], []); } console.log(acc.get(cv["last"])); //this returns 1 when on the second smith acc.set(cv["last"], acc.get(cv["last"]).push(cv["last"])); return acc; }, new Map()); console.log("grouppedArray", grouppedArray);
问题原因与解决方案
问题根源
核心问题在这行代码:
acc.set(cv["last"], acc.get(cv["last"]).push(cv["last"]));
- 数组的
push()方法返回的是新数组的长度,而非数组本身。第一次给Map键设置空数组后,第二次调用push时,你把返回的长度(数字1)存进了Map,后续再调用.push()时,就会因为数字没有push方法抛出类型错误。 - 另外你还写错了存入数组的内容:应该把当前对象
cv存入数组,而非仅存cv["last"](姓氏字符串)。
修正后的代码
let names = [ {first: "John", last: "Smith", age: 12}, {first: "Jessica", last: "Jones", age: 22}, {first: "Lois", last: "Lane", age: 32}, {first: "Joe", last: "Smith", age: 42}, {first: "Jenny", last: "Jones", age: 52}, {first: "Mary", last: "Smith", age: 62} ]; let groupedArray = names.reduce(function(acc, cv) { // 若键不存在,初始化空数组 if (!acc.has(cv.last)) { acc.set(cv.last, []); } // 直接对Map中的数组执行push,无需重新set(数组是引用类型) acc.get(cv.last).push(cv); return acc; }, new Map()); console.log("groupedArray", groupedArray);
代码说明
- 移除多余的
acc.set操作:数组是引用类型,直接修改acc.get(cv.last)返回的数组,Map中存储的数组会同步更新,不需要重新调用set。 - 修正存入内容:将
cv["last"]改为cv,确保分组后每个数组里是完整的对象。 - 规范变量名:把拼写错误的
grouppedArray改为groupedArray。
内容的提问来源于stack exchange,提问作者Lee
相关产品推荐
相关产品推荐

