33

Can you describe this for me?

var arr, total;
arr = [1, 2, 3, 4, 5];
total = arr.reduce(function(previous, current) {
return previous + current;
});
// total is 15
Mr.AZ
  • 363
  • 1
  • 3
  • 5
  • 14
    How about https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce? and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight – elclanrs Dec 24 '13 at 01:15

9 Answers9

77

The order for reduce is from left to right, and it's from right to left for reduceRight, as the following piece of code shows:

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
Harry He
  • 1,795
  • 16
  • 12
18

In some cases, the difference between reduce and reduceRight does matter:

However, because adding two integers is commutative in JavaScript, it doesn't matter in your example, just like how 1 + 2 is equal to 2 + 1 in math.

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

console.log(  arr.reduce((previous, current)      => previous + current)  )
console.log(  arr.reduceRight((previous, current) => previous + current)  )
vsync
  • 118,978
  • 58
  • 307
  • 400
Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
  • 6
    Sorry but I think this is a bad example because it is not robust and it is just not a realistic example. Anyone implementing totalLeft or totalRight as methods would coerce Number type within the function, which would make your use case irrelevant. – Elise Chant Feb 22 '15 at 20:05
  • @EliseChant: well it depends on your use case. If you're doing something with side effects like getting a list of files sequentially using promises, the order would obviously matter. If the function passed has no side effects, then it would just be a matter of whether the function is associative or not. – Qantas 94 Heavy Feb 23 '15 at 09:49
  • 1
    @EliseChant you are ranting about the variable name `total..` that's not the point of the example, but the order in which things are processed. this is the same as the top answer, but chronologically was answered before it. **thumbs up** – vsync Jul 09 '18 at 16:47
6

Array.reduceRight() is great when:

  • you need to iterate over an Array of items to create HTML
  • AND need a counter in HTML prior to the items

.

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>
*/
Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49
  • 10
    I think it took me far longer to figure out what this code was doing than it took for me to understand `reduceRight`. – kumarharsh Jun 20 '20 at 14:15
4

ReduceRight is different from reduce method as it starts computation on values from right to left.

Reduce Example:

<!doctype html>
<html>

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

</html>

Starting from left to right: 12 = 23 = 6 * 4 = 24

ReduceRight Example

<!doctype html>
<html>

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

</html>

Starting from right to left: 1024/256 = 4/4 = 1

VLAZ
  • 26,331
  • 9
  • 49
  • 67
Sohail Arif
  • 279
  • 2
  • 9
  • Think it'd help people if you showed the reduce example as 4*1 = 4 * 2 = 8 * 3 = 24 instead of multiplying the initial value last – Gwater17 Sep 11 '16 at 18:51
4

Do correct me if I am wrong;

My understanding is that, solely in the context of Array, the fundamental difference between reduce and reduceRight - other than just the direction - is that in previous moments of history (before browser optimisations etc), compilers would count backwards from 10 to 0, (arr.reduceRight - right-to-left), a lot faster than counting forwards from 0 to 10 (arr.reduce - left-to-right).

Reducing from the right meant that the compiler could start at 10 and the iterator could only ever get to 0. This meant that the compiler, on each iteration, had to check that the current iteration is greater than 0. Easy peasy.

However, when reducing from the left (arr.reduce - left-to-right), the length of the collection could possibly change, and thus the compiler having to re-evaluate arr.length on each iteration.

For an example, if you had an array of 10 using Array(10), and you used arr.reduce() - left-to-right, the compiler would have to check to make sure nothing else is pushed on to the collection during the reduce, in order to determine its position - on each iteration.

I hope this helps someone :)

zivc
  • 323
  • 3
  • 8
  • I don't know if this is correct. But makes sense and wanted to say thank you for this reply. I was looking at why there's reduce and reduceRight. In functional libs reduce is = to reduceRight so i was curious of the difference – pourmesomecode Feb 25 '19 at 12:09
  • 1
    This makes sense to me. – Huan Mar 06 '19 at 18:14
0

The only thing is order of computation. Reduce does it 'left to right', reduceRight does it 'right to left'. See the following example:

<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> 
Deadpool
  • 7,811
  • 9
  • 44
  • 88
0

Reduce work Left to right. And Reduce Right work from Right to Left.

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
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 27 '21 at 04:12
-1

The reverse order is of importance for instance when dealing with HTTP interceptors in Angular. Then you want the last interceptor to be the first in the chain to be executed. I searched for ".reduceRight" on GitHub and found a total of 20 JS repos using it. So basically , You probably don't need to use it.

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

jsaddwater
  • 1,781
  • 2
  • 18
  • 28
-1

The use of reduce() and reduceRight() methods utility is different as the following code shows which is been mentioned in most pages describing the same,

var arr = ["a", "b", "c", "d", "e"];

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

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

console.log(total1); // => abcde
console.log(total2); // => edcbe

The purpose of using these two differs as it depends on the functionality you are working on.

Tried to think about some real-world scenarios but failed to reach a perfect example. :)

zain ul din
  • 1
  • 1
  • 2
  • 23