1

Why doesn't this iterate?

(Array(5)).reduce(function(cur,prv,n,a){alert(n)},'');

I never reached the function body, seemingly ignoring all of the empty values, which is not what I want it to do.

4
  • This throws an error: TypeError: Reduce of empty array with no initial value Commented Oct 23, 2014 at 18:41
  • It's not an empty array, all values in it are of type undefined Commented Oct 23, 2014 at 18:48
  • 2
    Try Array.apply(0, Array(5)).reduce Commented Oct 23, 2014 at 18:49
  • it looks like you're missing closing parens, is that just a typo? Commented Oct 23, 2014 at 18:54

2 Answers 2

1

As far as I understand Array(5) returns an instance of Array Object with a property length (value 5), but without values. One way to be able to use reduce (or other array methods like map) here is:

String(Array(5)).split(',').reduce(function (cur, prv, n, a) { /* ... */ })

An alternative could be:

Array.apply(null,{length: 5}).map( [callback] );
// or
Array.apply(null,Array(5)).map( [callback] );

But that will encounter a maximum call stack error at some point. The string/split method keeps working (albeit a bit slower) for large arrays. Using node.js on my (not so fast) computer mapping Array(1000000) with the string/split-method lasts 0.47 seconds, the array.apply method for the same crashes with a RangeError (Maximum call stack size exceeded).

You can also write a 'static' Array method to create an Array with n values and all usable/applicable Array methods in place:

Array.create = function (n, mapCB, method, initial) {
  method = method in [] ? method : 'map';
  var nwArr = ( function(nn){ while (nn--) this.push(undefined); return this; } )
                .call([], n);
  return mapCB ? nwArr[method](mapCB, initial) : nwArr;
};
// usages
Array.create(5, [callback], 'reduce', '');
Array.create(5).reduce( [callback], '');
Array.create(5).map( [callback] ).reduce( [callback] );
// etc.
Sign up to request clarification or add additional context in comments.

1 Comment

Good solution, but conversion to string and then splitting is quite slow for larger array's. I like my code lean, so I hope someone knows a solution I can use the plain array with reduce, otherwise I'll use a for loop
0

As others have stated, the implementation of reduce causes this to throw a TypeError because the calling array has no initial values. To initialize an array with initial values of undefined and successfully invoke the function, try something like this:

Array.apply(undefined, Array(5)).reduce(function(cur,prv,n,a){alert(n)},'');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.