reduce 可以做 map 做的所有事情吗?

Can reduce do everything that map does?

我在面试时被问到如何使用 JavaScript(一种数组操作)我说我们可以使用 reduce,但面试官说不应该使用 map 但我有点确定 reduce 可以做任何 filtermap 正在做的事情。我对不对?

抱歉,我无法重现我被问到的问题,但我在这里问的是 JavaScript...

中的一般还原技术

答案是:绝对是!

Reduce 实际上可以做任何可以通过单次迭代完成的事情

过滤器:

myArray.reduce(
    (result, item) => [...result, ...(myCallback(item) ? [item] : [])],
    []
)

地图:

myArray.reduce(
    (result, item) => [...result, myCallback(item)],
    []
)

也就是说,如果您需要过滤项目,请使用 filter(),如果您需要映射项目,请使用 map()

是的,它可以,但这并不意味着您应该将 Array#map 换成 Array#reduce 以完成任何单个任务。

如果你想转换数组中的所有项,那么Array#map更实用:

[1,2,3].map(x => x + 10);
//=> [11,12,13]

// vs

[1,2,3].reduce((acc, x) => (acc.push(x + 10), acc), []);
//=> [11,12,13]

Array#reduce 的典型示例是 将列表 缩减为单个值。例如,总结列表中的数字:

[1,2,3].reduce((tot, x) => tot + x, 0);
//=> 6

如果您打算同时转换 过滤器,那么 Array#reduce 可能会有帮助:

[1,true,2,false,3].filter(x => typeof x === 'number').map(x => x + 10);
//=> [11,12,13]

// vs

[1,true,2,false,3].reduce((acc, x) =>
  typeof x === 'number' ? (acc.push(x + 10), acc) : acc, []);
//=> [11,12,13]

从句法上讲,可以说 .filter().map() 方法看起来更漂亮,但它确实比必要的迭代次数更多:.filter() 产生另一个数组供 .map() 使用。

如果您有一个大列表要处理,链式数组操作 ala jQuery 可能效率低下:

[items × 1000].filter(...).map(...).filter(...).map(...).filter(...);
// Depending on what you do at each step this could take a while