使用.map()修改对象数组属性时仅返回属性值的问题解决
如何修改对象数组中每个对象的指定属性并返回完整对象数组?
问题场景
你需要修改对象数组中每个对象的name属性(将指定字符替换为其他字符),并返回包含修改后属性的完整对象数组,但当前代码仅返回了修改后的name字符串数组,不符合预期:
示例数组:
var students = [ { "number": 4251, "name": "Melissa", "surname": "Giron" }, { "number": 4321, "name": "Gisele", "surname": "Johnsen" } ]
当前实现函数:
function changeLetterInName(students) { return students.map(x => x.name.replace("e", "z")); }
预期输出:
[ { number: 4251, name: 'Mzlissa', surname: 'Giron' }, { number: 4321, name: 'Giszlz', surname: 'Johnsen' } ]
实际输出:
['Mzlissa', 'Giszlz']
错误原因
你的map回调函数直接返回了x.name.replace(...)的结果(字符串类型),所以map会将原数组的每个对象映射为对应的字符串,最终得到字符串数组,而非完整对象数组。
修改方案
需要在map回调中返回包含修改后name属性的新对象,同时尽量避免修改原数组的对象(保持数据不可变性),以下是两种常用实现方式:
1. 使用对象展开运算符(推荐,ES6+)
通过展开运算符复制原对象的所有属性,再覆盖name属性:
function changeLetterInName(students) { return students.map(x => ({ ...x, // 展开原对象的所有属性 name: x.name.replace(/e/g, "z") // 替换name属性的指定字符 })); }
2. 使用Object.assign
通过Object.assign创建新对象,合并原对象和修改后的name属性:
function changeLetterInName(students) { return students.map(x => Object.assign({}, x, { name: x.name.replace(/e/g, "z") })); }
关键注意点
- 若需要全局替换所有匹配的字符,必须使用正则表达式并添加
g标志(如/e/g),否则String.replace()仅会替换第一个匹配的字符。 - 上述两种方式都会创建新对象,不会修改原数组中的对象,避免了副作用。
内容的提问来源于stack exchange,提问作者Friedrich Zizek
相关产品推荐
相关产品推荐

