如何用map/filter/reduce简洁重写redux1,保留对象指定键?
问题解决:优化redux1并修复redux2的字段移除问题
先来看第一个任务:用map/reduce等函数式方法重写redux1,让它更简洁且避免修改原数据。
原redux1通过forEach遍历原数组并直接修改每个对象,这种方式会改变原始数据。我们可以用map结合reduce或者Object.fromEntries来生成新的对象数组,既简洁又符合函数式编程的无副作用原则:
重写后的redux1(两种可选方案)
方案一:使用map + reduce
function redux1(data) { const reducedData = data.map(person => keys_to_keep.reduce((acc, key) => { acc[key] = person[key]; return acc; }, {}) ); console.log(reducedData); return reducedData; }
方案二:使用map + Object.fromEntries(更简洁)
function redux1(data) { const reducedData = data.map(person => Object.fromEntries(keys_to_keep.map(key => [key, person[key]])) ); console.log(reducedData); return reducedData; }
这两种方式都会返回一个全新的数组,每个对象只保留keys_to_keep中指定的键,完全不会修改原始的data数组。
接下来解决redux2的问题:原redux2无法移除age字段,核心原因是用错了方法!
原redux2里的filter是用来筛选数组元素(决定整个对象要不要留在数组里),而不是用来修改单个对象的结构。内层的filter返回的是符合条件的键数组,只要数组不为空就会被判定为true,所以所有对象都被保留,但对象本身的字段完全没变化,age自然还在。
修复后的redux2
我们只需要把filter换成map,用转换对象结构的逻辑替换筛选逻辑即可:
function redux2(data) { const reduced = data.map(person => Object.fromEntries(keys_to_keep.map(key => [key, person[key]])) ); console.log(reduced); return reduced; }
现在调用redux2(data),返回的每个对象就只会包含name和city字段,age被成功移除了。
测试数据:
var data = [ {name: 'John', city: 'London', age: 42}, {name: 'Mike', city: 'Warsaw', age: 18}, {name: 'Jim', city: 'New York', age: 22}, {name: 'Celine', city: 'Tokyo', age: 54}, ] var keys_to_keep = ['name', 'city']
内容的提问来源于stack exchange,提问作者barciewicz
相关产品推荐
相关产品推荐

