【问题标题】:Is `Array.prototype.reduceRight` identical to `reverse` followed by `reduce`?`Array.prototype.reduceRight` 是否与 `reverse` 后跟 `reduce` 相同?
【发布时间】:2020-06-28 12:15:01
【问题描述】:

Array.prototype.reduceRight 将数组缩减为单个值,从右到左(即从数组末尾开始)。

调用reduceRight 与调用reverse 后跟reduce 完全相同吗?如果有,为什么reduceRight 存在?

【问题讨论】:

  • 就不一样了,reverse把数组原地反转,而reduceRight不会改变原来的。
  • Reverse 是就地方法,而 reduceRight 不是

标签: javascript arrays functional-programming reduce


【解决方案1】:

正如已经提到的,它是不一样的。以下是另外两个用例,这两个版本的行为不同:

  • 所有基于索引(reducereduceRight 调用的回调函数的第三个参数)的行为可能不同。

  • 在修改 原始 数组时经常使用反向循环。根据具体的用例,这可能适用于reduceRight,但会与reduce 中断。

【讨论】:

  • 我没有想到两者之间的索引不同,但你是绝对正确的。这本身就足以使reduceRight()reverse().reduce() 完全不兼容,即使reverse 在不修改原始数组的情况下生成了一个新数组。
【解决方案2】:

已经提到.reverse()修改了初始数组,

另外,根据规范:

https://tc39.es/ecma262/#sec-array.prototype.reduce

https://tc39.es/ecma262/#sec-array.prototype.reduceright

实现有点不同。

让我允许与.push().unshift() 进行类比 - 它们也完全相同,在数组中插入一个元素,我们经常使用 push,很少使用 unshift,但有时会有一些完美的时刻unshiftreduceright

【讨论】:

    【解决方案3】:

    Array#reduceRight Array#reverse() -> Array#reduce() 相同。这里是关键区别.reduce()/.reduceRight()不要修改起始数组:

    const arr = ["a", "b", "c"];
    
    const combine = arr.reduceRight((a, b) => a+b, "");
    
    console.log(combine);
    console.log(arr);

    但是,.reverse() 会:

    const arr = ["a", "b", "c"];
    
    const combine = arr.reverse().reduce((a, b) => a+b, "");
    
    console.log(combine);
    console.log(arr);

    还有一个性能问题——.reverse 将产生额外的O(n) 处理以就地反转数组,这是在已经在O(n) 上运行的.reduce() 之上。是的,最终的复杂度仍然是O(n)(我们忽略了常量),但是单次遍历数组会更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-12
      • 1970-01-01
      • 2010-09-13
      • 2011-01-28
      • 2013-06-21
      • 1970-01-01
      相关资源
      最近更新 更多