wlsonf
wlsonf

Reputation: 51

ES6: .reduce function

I'm trying to sum the value of object inside Array. Here's my array:

"seasons":[
  {
    "id": "1",
    "name": "Season 1"
    "stocks":[
        {
          "size": "s",
          "stock": "5"
        },
        {
          "size": "m",
          "stock": "5"
        },
        {
          "size": "l",
          "stock": "5"
        }
     ]
   }
], ...

Here's where I want to implement it

      <tbody>
            {seasons.length ? 
              seasons.map(seasons => (
                <React.Fragment>
                    {seasons.items.length ? 
                        seasons.items.map(season=> (
                            <tr onClick={()=>this.handleClick(season.id)}>
                              <td>{season.stocks.reduce((stock)=>stock, 0)}
                            </tr>
                            ))
                        :
                        <React.Fragment/>
                    }
                </React.Fragment>
              ))
              : 
              <React.Fragment/>
            }
     </tbody>

I know .reduce needs at least 2 arguments, but i can't think of any way to do this. I tried mapping it first

{season.stocks.length ? season.stock.map(stock=>(
  stock.reduce()
)):<div/>}

and of course it fails because once i mapped it, it is no longer an array. Is there anyway i can sum the value the total of "stock"? Thanks!

Upvotes: 0

Views: 1770

Answers (1)

nbokmans
nbokmans

Reputation: 5747

Your reduce function is missing an accumulator value (which holds the "reduced" value, i.e. the second value you are talking about).

To give you a simpler reduce example so you can understand what the accumulator does:

const totalOfArray = [1, 2, 3, 4, 5].reduce((total, value) => total += value, 0); //1 + 2 + 3 + 4 + 5 = 15 

The accumulator value is stored in variable total. reduce iterates over the array and every loop, value is added on to total.

Now we can translate this to your use case, which is getting the total stock value. I think what you are trying to do here

<td>
    { season.stock.reduce((totalStock, stockItem) => totalStock += parseInt(stockItem.stock), 0) }
</td>

Notice the parseInt, in your data array the stock is a string and not a number. If you reduce a string you end up with a concatenated string rather than the total stock number. We can demonstrate this by running a simple test in our browser console:

const totalOfArray = ['1', '2', '3', '4', '5'].reduce((total, value) => total += value, ''); //12345 

And that is why you have to do the parseInt.

Check out the documentation on Array#reduce here

Upvotes: 2

Related Questions