ForEach in the “new array” does not do what I expect

I am just learning how to use higher order JS functions (map, forEach, reduce, etc.) and stumbled into confusion. I am trying to write a simple "range" function, but it doesn't seem to populate my output array. This is the goal:

range(1, 4) // [1, 2, 3, 4] 

I get this:

 [undefined × 4] 

Here is my code:

  function range(num1, num2) { var rangeArr = new Array((num2 + 1) - num1); return rangeArr.map(function(e, i, arr) {return arr[i] = num1 + i}); } 

What am I missing here? As far as I can tell, the problem seems to be related to how I use the "new array", but beyond that I am lost.

Oh, and here is the part that really bothers me. This works great:

 function bleck() { var blah = [1, 2, 3, 4]; var x = 'wtf'; return blah.map(function(e, i, arr) {return arr[i] = x}) } ["wtf", "wtf", "wtf", "wtf"] 

Thanks!!

+6
source share
4 answers

The forEach method forEach over the indexes of the array . Interestingly, when creating a new array through new Array(n) it does not contain indexes at all. Instead, it simply sets the .length property.

 > var a = new Array(3); > console.info(a) [] > console.info([undefined, undefined, undefined]) [undefined, undefined, undefined] 

MDN describes forEach and specifically indicates:

forEach performs the provided callback once for each element of the array with the assigned value. It is not used for indexes that have been deleted or deleted .

It uses a neat technique to get an array with empty but existing indexes.

 var a = Array.apply(null, Array(3)); 

This works because .apply "extends" the rejected elements into the correct arguments, and the results end up roughly like Array(undefined, undefined, undefined) .

+4
source

An array is defined with 4, each of which is undefined.

The card will not go through undefined, it passes them.

callback is called only for array indices that are assigned values; it is not called for undefined indexes that have been deleted or have never been assigned values.

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

+1
source

When you create new Array(x) , a so-called sparse array is created that can behave differently, as you can see, some browsers will say [undefined x 20,"foo", undefined x 5] if you just set one value, and I believe that he does not iterate over these values.

+1
source

The problem is that map does not iterate over undefined (*) records.

I suggest using the for loop instead:

 var rangeArr = new Array((num2 + 1) - num1); for(var i=0; i<=num2-num1; ++i) rangeArr[i] = num1 + i; return rangeArr; 

(*) With undefined elements, I mean rangeArr.hasOwnProperty(i) === false , so as not to be confused with rangeArr[i] === void 0 .

0
source

All Articles