views:

83

answers:

3

I'm using Firefox 3.5.7 and within Firebug I'm trying to test the array.reduceRight function, it works for simple arrays but when I try something like that I get a NaN. Why?

>>> var details = [{score : 1}, {score: 2}, {score: 3}];
>>> details
[Object score=1, Object score=2, Object score=3]
>>> details.reduceRight(function(x, y) {return x.score + y.score;}, 0)
NaN

I also tried map and at least I can see the .score component of each element:

>>> details.map(function(x) {console.log (x.score);})
1
2
3
[undefined, undefined, undefined]

I read the documentation at https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight but apparently I can't get it work to sum up all the score values in my details array. Why?

+3  A: 

try this (will convert to numbers as side effect)

details.reduceRight(function(previousValue, currentValue, index, array) {
  return previousValue + currentValue.score;
}, 0)

or this

details.reduceRight(function(previousValue, currentValue, index, array) {
  var ret = { 'score' : previousValue.score + currentValue.score} ;
  return ret;
}, { 'score' : 0 })

Thanks to @sepp2k for pointing out how { 'score' : 0 } was needed as a parameter.

Hogan
A: 

The reduce function should combine two objects with a property "score" into a new object with a property "score." You're combining them into a number.

Willis Blackburn
The function should combine an object of type a and an object of type b (where a is the type of the initial value and b is the element type of the array) into an object of type a. a and b don't have to be the same type.
sepp2k
Yeah, I realize that. I mostly use Scala, in which the reduce operation always produces a value with the same type as the input list. In Scala the operation that accumulates the values from a list into a value of another type is called fold.
Willis Blackburn
+4  A: 

The first argument given to the function is the accumulated value. So the first call to the function will look like f(0, {score: 1}). So when doing x.score, you're actually doing 0.score which doesn't work of course. In other words you want x + y.score.

sepp2k
So basically when you pass the initial value to reduceRight, it behaves as a fold. I didn't realize that.
Willis Blackburn
I'm enlightened! Thanks.
Emre Sevinç