Why .reduce() caused me so much confusion over the past 2 days.
Tags: javascript, challenge
Published: 2020-08-30 19:03:22

---
title: Why .reduce() caused me so much confusion over the past 2 days.
published: true
description: .reduce() does not always work like you think. In this post I will go over the scenario in which I found it to be a hindrance. 
tags: javascript, challenge
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/lxexxq4ohg9uts58qdzu.jpg

---
This month I started doing coding katas to improve my JavaScript skills. I do puzzles and quizzes on my phone a lot anyway, and coding is not that far off solving puzzles. 

I am using [Code Wars](https://www.codewars.com/) - the site is free, you can see other folks' solutions and there is a level system to see you progress. It also encourages you to participate in the community, which is a great mindset to install in people. 

I found it to be a great tool, even though the interface can be a lot and I had to familiarise myself with the ranks.
 
I was doing a simple kata of [adding arrays](https://www.codewars.com/kata/5715eaedb436cf5606000381/train/javascript). The kata requested that, given an array of items, I had to return a sum of all positive values in the array. 

Initially, and I thought that adding all items in the array would be an easy task, as this can be done using the .reduce() function. But not all of the tests were passing.

```javascript
function positiveSum(arr) {
  return arr.length > 0 ? arr.reduce(addAll) : value;
}

function addAll(total, value) {
  return value > 0 ?  total + value : total;
}

```
When the input arrays started with a negative values, my tests failed. In a test where an array had all negative values, I would expect the value of 0 to be returned as no values would be added. However, I would be finishing up with the arr[0] value instead.

Unfortunately, I have wrongly assumed that the total value (also known in js land as the *accumulator*) started at 0. This is not the case - the accumulator starts as the first value in the array. AND the first loop starts on the 2nd item in the array (arr[1]). For example:

```javascript
function positiveSum(arr) {
  return arr.length > 0 ? arr.reduce(addAll) : value; 
}

function addAll(total, value) {
  console.log('Total is ' + total + ' and current value is ' + 
  value) 
  return value > 0 ?  total + value : total;
}

let testArray = [-1,-2,-3,-4,-5]; //we expect 0 as all are negative values

positiveSum(testArray); //we get -1

//Output
//Total is -1 and current value is -2
//Total is -1 and current value is -3
//Total is -1 and current value is -4
//Total is -1 and current value is -5
```
So, as you can see, the function is only called 4 times, with -1 being the initial accumulator value. This meant that the arrays which were starting with a negative value, would have incorrect totals.

In addition to the above, when arrays were empty, I had to put in a safety check for that as well.

Defeated, I have used a simple .forEach() to finish my kata - which, admittedly,  worked like a charm.

#BUT PLOT TWIST! 

When I have looked at solutions for my fellow coders, I have realised that .reduce() method can, in fact, take an initial accumulator value!

The only thing I had to correct was adding a 0 as an argument in  my reduce() function : 

```javascript
 return arr.reduce(addAll,0);
```

What does this do to iterations? Well, there is now an iteration per element in the array, starting at the 1st element (arr[0]). 

The problem of reductions on empty arrays was also solved this way! 

The final solution is as follows: 
```Javascript
function positiveSum(arr) {
  return arr.reduce(addAll, 0); 
}

function addAll(total, value) {
  return value > 0 ?  total + value : total;
}

```

So moral of the story is.... Always look for improvements to your solutions :)  

##Doc
[MDN docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)