user7662982
user7662982

Reputation:

Why does reduce not print the first value?

I am trying to learn how to use reduce here and this will log only b,c,d

['a', 'b', 'c', 'd'].reduce(function(acc, cur){
  console.log(cur);
  return cur;
})

I don't understand what the accumulator is either. I have no idea how this works even after reading the documentation.

Current does not appear to be current as 'a' is skipped.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

Edit: here is a better set of test cases:

enter image description here

Upvotes: 12

Views: 5851

Answers (6)

Alnitak
Alnitak

Reputation: 339796

The point of reduce is that it takes each element in turn from the array, performs a binary operation on that element and the output from the previous iteration (the "accumulator"), and then repeats the process until the input array is exhausted.

That is, to say, given [a, b, c, d].reduce(f) it does:

   f(a, b)
-> f(f(a, b), c)
-> f(f(f(a, b), c), d)

You're only logging the second parameter, so your a never appears.

(For convenience, I've ignored the extra index and array parameters that are passed to f)

The optional "initial value" parameter that you have not supplied, is used if you want to use something other than the first element in the array as the first left hand operand. If you do not supply it, then, as you have found, the first values of acc and cur will be "a" and "b"

The reduceRight function takes the arguments from the other end of the array:

   f(c, d)
-> f(b, f(c, d))
-> f(a, f(b, f(c, d)))

Upvotes: 15

Dan Cantir
Dan Cantir

Reputation: 2955

I understand things easier when I see real world examples, so let say we have an array like this:

let products = [
    { label: 'Product 1', price: 5  },
    { label: 'Product 2', price: 15 },
    { label: 'Product 3', price: 20 },
];

Then we want to count the total price:

let totalPrice = products.reduce((acc, product) => {
    return acc + product.price;
}, 0); // 0 - initial value

console.log(totalPrice);

And it does not log a because if no initial value specified, it will take first element as the initial value.

Upvotes: 3

Nina Scholz
Nina Scholz

Reputation: 386560

You need to specify an initialValue, if the accumulatior should not be the first element, according of the API of Array#reduce.

initialValue

[Optional] Value to use as the first argument to the first call of the callback. If no initial value is supplied, the first element in the array will be used. Calling reduce on an empty array without an initial value is an error.

['a', 'b', 'c', 'd'].reduce(function(acc, cur){
    console.log(cur);
    return cur;
}, undefined);
// ^^^^^^^^^

Upvotes: 13

TurtleTread
TurtleTread

Reputation: 1314

For example,

['a', 'b', 'c', 'd'].reduce(function(acc, cur){
  console.log(acc);
  return acc+cur;
})

You will get following:

ab
abc
abcd

array.reduce() takes an one element in the array at a time and produces an output according to the callback function and store it in the accumulator. Therefore for each iteration you'd have the previous result (the accumulator) and the current element to produce the next result. Accumulator value starts with the value of the first element in the array.

Upvotes: 0

Suresh Atta
Suresh Atta

Reputation: 121998

As docs mentioned

The reduce() method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.

That tell clearly that

['a', 'b', 'c', 'd'].reduce(function(acc, cur){
  console.log(cur);
  return cur;
})

reduce gives acc values each time as a,b,c and cur as b,c,d

each time you get the pairs as a,b b,c, c,d

Upvotes: 0

user4074041
user4074041

Reputation:

First parameter in first time is a [0], second is [1].

In second time first param is f([0],[1]), second is [2], etc

Upvotes: 0

Related Questions