When we went into the guts of reduce() to see how the method works, we considered a simple example: that of summing a list/array of numbers. In that example, we got the same result both when we assigned an initialValue or ini and when we didn't.

Of course, we saw that in the former case, there were three iterations by reduce() compared to two in the latter. And, yes, having a starting point, what the ini helps with, makes your reduce() call more predictable. It can also prevent you from having unexpected results. As the example in today's post will demonstrate, ini kind of defines how your reduce() function might progress and what sort of result you ought to get.

Needless to say, that's kind of why you're using reduce() array method anyway - to ensure that the return value (the result) is up to you.

Using reduce() to sum up values in an object array

Consider the following example from the MDN doc:

    var ini = 0;
    var sum = [{x: 1}, {x: 2}, {x: 3}].reduce((acc, cur) => acc + cur.x, ini)

    console.log(sum) // logs 6

To make the sum function closer to the orginal reduce() signature, and, perhaps, a little cleaner, we could write our code like so:

        ini = 0,
        rdc = (acc, cur) => acc + cur.x,
        arr = [{x: 1}, {x: 2}, {x: 3}],
        sum = arr.reduce(rdc, ini)

    sum // Logs 6

I deliberately omit console.log() since I imagine you might copy and paste this in the console to test. Also, a reminder that in my examples, I prefer var keyword to const so I could overwrite my variables for test cases. Then again, my style of declaring variables with one var then a comma for a subsequent declaration, is just my style - you use what you find comfortable.

If we were to omit ini and have our sum function like so:

        rdc = (acc, cur) => acc + cur.x,
        arr = [{x: 1}, {x: 2}, {x: 3}],
        sum = arr.reduce(rdc)

    sum // Logs "[object Object]23"

Do you see the problem? You wanted to sum the values of objects in an array but ended up getting some weird concatenation. Why?

The pitfall of not supplying an initial value

Remember that as reduce() starts, if an initial value is supplied, it will assign that value to the accumulator, and then give the value of the first element in the array to cur. Remember? But if not, it will assign the first item to acc and the second to cur.

Now, what's happened here when we don't supply an ini is that the acc is now {x: 1}, which is an object. And by JavaScript style that becomes [Object Object]. Then cur.x is executed on {x: 2}, the second element, and therefore cur is 2.

By now, JavaScript is already seeing your + operator as a "concatenator", not an "adder", so it joins these values instead of sums them. It does so because the "types" are mixed - acc is the String [Object Object], whereas, cur is the Number 2. You get the idea...

However, with an ini value supplied, and in this case, the Number 0, the acc becomes 0. Thus, the cur is 1 on the first call, which you know why, right? The value of key x in object {x: 1} as cur on this call is the first element. You know that each time, cur.x evaluates to the value of the x key in each object index in the array, right? Cool.

Now JS can do your math and each call can be an "adder" like so:

    first call
        acc             0 (because ini = 0)
        cur             1 (because the value of x at the current element 1 from `cur.x`)
        return value    1 (because 0 + 1)
    second call
        acc             1 (previous return value)
        cur             2 (the value of x at the current element 2 from `cur.x`)
        return value    3 (1 + 2)
    third call
        acc             3 (last return value)
        cur             3 (the value of x at the current element 3 from `cur.x`)
        return value    6 (3 + 3)

    And, you've run out of `cur`'s, so no more calls.

Make sense?

The flexibility of the reduce() method, that it can return anything you want it to, really, really depends on your passing in a and what type of initialValue you supply. In today's example, you've seen how we could arrive at a Number result by initiating with a number, 0. You'll see from more examples coming that we can get any type of value we want - String, Object, or another Arrray. Do stay tuned to reduce().