Why you should pass in the initial value with arrayreduce even through it’s optional
I was playing with some code that used arrayReduce to sum the values in an array. Not terribly exciting, here it is:
function sumReducer(accumulator, el) { return accumulator + el; } function assert(actual, expected) { if (actual==expected) { writeOutput("PASS"); } else { writeOutput("FAIL: expected: `#expected#` got `#actual#`"); } } data = [1,2,3,4,5]; actual = data.reduce(sumReducer, 0); assert(actual, 15);
This does what you’d expect. However, as CFML supports default value for arguments, I decided to see if I could do that instead of passing the initial value of 0
as the 2nd argument of reduce like so:
function sumReducer(accumulator=0, el) { return accumulator + el; } function assert(actual, expected) { if (actual==expected) { writeOutput("PASS"); } else { writeOutput("FAIL: expected: `#expected#` got `#actual#`"); } } data = [1,2,3,4,5]; actual = data.reduce(sumReducer); // don't do this! assert(actual, 15);
I ran it and it passed. I was quite pleased with myself, however I was fooling myself. Turns out, you shouldn’t use the 2nd version. Why? If the data array is empty, then the callback function sumReducer
isn’t called so you’ll get an Variable ACTUAL is undefined
error.
To sum up, always pass in the initial value even through it’s optional.
You must be logged in to post a comment.