【问题标题】:Can reduce do everything that map does?reduce 可以做 map 做的所有事情吗?
【发布时间】:2021-03-02 01:50:13
【问题描述】:

我在接受采访时被问到如何使用 JavaScript(一种数组操作)来做到这一点reduce 可以做任何 filtermap 正在做的事情。我说的对吗?

抱歉,我无法重现被问到的问题,但我在这里询问的是 JavaScript 中一般的缩减技术...

【问题讨论】:

  • 就像你可以用鞋子给吐司涂黄油一样,可以,但刀更适合它
  • 是的,reduce可以.map可以做的一切。事实上,所有的数组迭代方法都可以用reduce来表示。这并不意味着您应该对所有这些都使用reduce。除非您使用的是transducers(也为see here),否则您不应该使用正确的习语来表达您的实际意思。更不用说更容易实现了
  • 你总是可以做任何事情,只要你有一个回调,你可以在其中编写任意代码,具有相同的权限。这并不意味着这是一个好主意。

标签: javascript filter functional-programming reduce


【解决方案1】:

答案是:绝对可以!

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

过滤器:

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

地图:

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

话虽如此,如果您需要过滤项目,请使用filter(),如果您需要映射项目,请使用map()

【讨论】:

  • 话虽如此,如果你在求职面试中写了这段代码,你很可能不会被录用。另外,我不知道为什么这种在这些小型 sn-ps 中使用传播的可憎行为变得如此受欢迎,它将所有内容从 O(n) 变为 O(n²) - 不仅在这里,现在已经有一段时间了.
  • 你有证据证明它是 O(n^2) 吗?此外,您多久使用一次包含数千个元素的数组?下面的任何事情都无所谓。
  • 只要抖动不比我预期的聪明很多,并且注意到没有对中间数组的任何引用,因此会重写您的代码 - 您正在复制每一步都有一个数组,1..n 的标准总和有一个 n² 项,是的。你是对的,很多时候这并不重要。这些天我几乎在 SO 上到处都能看到它,我猜有 1-5% 的人使用它会遇到麻烦,甚至不知道为什么。
  • @VLAZ 有什么证据证明它更快吗?
  • 从 O(n) 到 O(n²) 的差异是如此明显,您可以将两者都用于更大的数组,最终,一个会冻结您的浏览器,而另一个会完成以毫秒为单位。
【解决方案2】:

可以,但这并不意味着您应该将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

【讨论】:

    猜你喜欢
    • 2011-02-02
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 2020-06-10
    相关资源
    最近更新 更多