【问题标题】:when to use reduce and reduceRight?什么时候使用reduce和reduceRight?
【发布时间】:2013-12-24 01:12:55
【问题描述】:

你能帮我描述一下吗?

var arr, total;
arr = [1, 2, 3, 4, 5];
total = arr.reduce(function(previous, current) {
return previous + current;
});
// total is 15

【问题讨论】:

标签: javascript


【解决方案1】:

reduce的顺序是从左到右,reduceRight是从右到左,如下代码所示:

var arr = ["1", "2", "3", "4", "5"];

total1 = arr.reduce(function(prev, cur) {
    return prev + cur;
});

total2 = arr.reduceRight(function(prev, cur) {
    return prev + cur;
});

console.log(total1); // => 12345
console.log(total2); // => 54321

【讨论】:

  • 很好的例子。
【解决方案2】:

在某些情况下,reducereduceRight 之间的区别确实很重要:

但是,因为在 JavaScript 中添加两个整数是 commutative,所以在您的示例中并不重要,就像数学中的 1 + 2 等于 2 + 1 一样。

var arr = ["A", "B", "C", "D", "E"];

console.log(  arr.reduce((previous, current)      => previous + current)  )
console.log(  arr.reduceRight((previous, current) => previous + current)  )

【讨论】:

  • 对不起,但我认为这是一个不好的例子,因为它不够健壮,而且不是一个现实的例子。任何将 totalLeft 或 totalRight 实现为方法的人都会在函数中强制使用 Number 类型,这会使您的用例变得无关紧要。
  • @EliseChant:这取决于您的用例。如果你正在做一些有副作用的事情,比如使用 Promise 按顺序获取文件列表,那么顺序显然很重要。如果传递的函数没有副作用,那么这只是函数是否关联的问题。
  • @EliseChant 你在抱怨变量名total.. 这不是示例的重点,而是处理事物的顺序。这与最佳答案相同,但在它之前按时间顺序回答。 竖起大拇指
【解决方案3】:

Array.reduceRight() 在以下情况下很棒:

  • 您需要遍历一个项目数组来创建 HTML
  • 并且需要 HTML 中的计数器之前项目

.

var bands = {
    Beatles: [
        {name: "John", instruments: "Guitar"},
        {name: "Paul", instruments: "Guitar"},
        {name: "George", instruments: "Guitar"},
        {name: "Ringo", instruments: "Drums"}]
};
function listBandplayers(bandname, instrument) {
    var bandmembers = bands[bandname];
    var arr = [  "<B>" , 0 , ` of ${bandmembers.length} ${bandname} play ` , instrument , "</B>",
                "\n<UL>" , ...bandmembers , "\n</UL>" ];
    var countidx = 1;
    return arr.reduceRight((html, item, idx, _array) => {
            if (typeof item === 'object') {
                if (item.instruments.contains(instrument)) _array[countidx]++;
                item = `\n\t<LI data-instruments="${item.instruments}">` + item.name + "</LI>";
            }
            return item + html;
    });
}
console.log( listBandplayers('Beatles', 'Drums') );
/*
<B>1 of 4 Beatles play Drums</B>
<UL>
    <LI data-instruments="Guitar">John</LI>
    <LI data-instruments="Guitar">Paul</LI>
    <LI data-instruments="Guitar">George</LI>
    <LI data-instruments="Drums">Ringo</LI>
</UL>
*/
console.log( listBandplayers('Beatles', 'Guitar') );
/*
<B>3 of 4 Beatles play Guitar</B>
<UL>
    <LI data-instruments="Guitar">John</LI>
    <LI data-instruments="Guitar">Paul</LI>
    <LI data-instruments="Guitar">George</LI>
    <LI data-instruments="Drums">Ringo</LI>
</UL>
*/

【讨论】:

  • 我认为我花了更长的时间来弄清楚这段代码在做什么,而不是让我理解reduceRight
【解决方案4】:

如果我错了,请纠正我;

我的理解是,仅在 Array 的上下文中,reducereduceRight 之间的根本区别——不仅仅是方向——是在过去的历史时刻(在浏览器优化等之前),编译器会从10倒数到0(arr.reduceRight - right-to-left),比从0倒数到10(arr.reduce - left-to-right)快很多。

从右边减少意味着编译器可以从10 开始,而迭代器只能到达0。这意味着编译器在每个 迭代中必须检查当前 迭代是否大于0。轻松愉快。

但是,当从左侧减少 (arr.reduce - left-to-right) 时,集合的长度可能会发生变化,因此编译器必须在每次迭代时重新计算 arr.length

例如,如果您有一个使用 Array(10)10 数组,并且您使用了 arr.reduce() - left-to-right,则编译器必须检查以确保在缩减期间没有其他任何内容被推送到集合中,在为了确定它的位置 - 在每次迭代中。

我希望这对某人有帮助:)

【讨论】:

  • 我不知道这是否正确。但有道理,想说谢谢你的回复。我正在研究为什么有 reduce 和 reduceRight。在功能库中,reduce is = to reduceRight 所以我很好奇其中的区别
  • 这对我来说很有意义。
【解决方案5】:

ReduceRight 与 reduce 方法不同,它从右到左开始计算值。

参考:http://www.thesstech.com/javascript/array_redcueright_method

减少示例:

<!doctype html>
<html>
 <head>
 <script>
   var arr = [1,2,3];
   document.write(arr.reduce(function(x,y){return x*y;},4));
 </script>
 </head>
</html>

从左到右:1*2 = 2*3 = 6 * 4 = 24

参考:http://www.thesstech.com/tryme?filename=javascript_array_reduce_method

ReduceRight 示例

<!doctype html>
<html>
 <head>
 <script>
   var arr = [4,256];
   document.write(arr.reduceRight(function(x,y){return x/y;},1024));
 </script>
 </head>
</html>

从右到左开始:1024/256 = 4/4 = 1

参考:http://www.thesstech.com/tryme?filename=javascript_array_reduceright_method

【讨论】:

  • 如果您将 reduce 示例显示为 4*1 = 4 * 2 = 8 * 3 = 24 而不是最后乘以初始值,这对人们会有所帮助
【解决方案6】:

唯一的事情是计算顺序。 Reduce 是“从左到右”,reduceRight 是“从右到左”。请参阅以下示例:

<html>

<head></head> 

<body> 

<script>

var a = [200, 100, 2];
var c = a.reduce(function(previousVal, currentVal){ 
previousVal = previousVal / currentVal; 
return previousVal;  
});
var c = a.reduceRight(function(previousVal, currentVal){ 
previousVal = previousVal / currentVal; 
return previousVal;  
});
alert(c);

</script> 

</body> 

</html> 
</html> 

【讨论】:

    【解决方案7】:

    相反的顺序很重要,例如在 Angular 中处理 HTTP 拦截器时。然后你希望最后一个拦截器成为链中第一个被执行的拦截器。我在 GitHub 上搜索了“.reduceRight”,发现总共有 20 个 JS repos 使用它。所以基本上,你可能不需要使用它。

    https://medium.com/dev-proto/how-it-works-array-reduceright-f7dfbd32cc59

    【讨论】:

      【解决方案8】:

      从左到右减少工作。并从右到左减少右工作。

      var arr = ["1", "2", "3", "4", "5", "6"];
      let total1 = arr.reduce(arrReduce);
      let total2 = arr.reduceRight(arrReduce);
      function arrReduce(prevValue, currentValue) {
          return prevValue + currentValue;
      }
      function reduceRight(prevValue, currentValue) {
          return prevValue + currentValue;
      }
      console.log(total1);//return 123456
      console.log(total2);//return 654321

      【讨论】:

      • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 1970-01-01
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-04
      • 2017-09-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多