Doing return element++; means you return the ORIGINAL VALUE of the value of the element.
That's what POST-INCREMENT means. "Get the value before the increment as the value of the expression, *then* do the increment."
Because you are incrementing a LOCAL COPY of element, that effectively means you are just throwing away the incremented value;
You will get *EXACTLY* the same results doing
Code:
function addOne(element, index, array)
{
return element;
}
And because *ONLY* the first element of the array has a value of zero, *THAT* element is the only one that is seen as "false" by JavaScript as the result of the call to the filter function.
Try this, instead:
Code:
function addOne(element, index, array) { return (element++); }
var Aarr = [0,1,0,3,4,5,0,7,0,9];
var Barr = Aarr.filter(addOne);
alert('Orig: \n'+Aarr+'\n\nadd 1: \n'+Barr);
Your filter is saying "filter out all the elements that have a value of zero." Nohthing more.
What were you *expecting* to happen??
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
function addOne(element, index, array)
{
++array[index];
return true; // just in case the element was -1 !!!
}
var Aarr = [0,1,2,3,4,5,6,7,8,9];
var temp = Aarr.filter(addOne);
var Barr = Aarr;
Aarr = temp;
alert(Aarr + "\n" + Barr);
No?
But, really, it would be more sensible to maybe do this:
Code:
Array.prototype.addOne = function( )
{
var ar = [];
for ( var i = 0; i < this.length; ++i )
{
ar[i] = this[i] + 1;
}
return ar;
}
var Aarr = [0,1,2,3,4,5,6,7,8,9];
var Barr = Aarr.addOne();
*SOMEWHERE* there has to be a loop through the elements. Granted, with filter() the loop is in native code, not JS, but then the call to the filter method for *each* element has to be tons slower than a simple loop in JS code. I would bet it would be an order of magnitude slower, in fact.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
<script type="text/javascript">
Array.prototype.forEach = function( callback )
{
var ar = [];
for ( var i = 0; i < this.length; ++i )
{
ar[i] = ( callback == null ) ? this[i] : callback( this[i] );
}
return ar;
}
var Aarr = [0,1,2,3,4,5,6,7,8,9];
var Barr = Aarr.forEach( function(element) { return element + 17; } );
var Carr = Barr.forEach( );
alert(Aarr + "\n" + Barr + "\n" + Carr);
</script>
See it? Now you have a forEach method that in turn takes a function that allows you to mangle each element, one at a time, as you wish.
As demonstrated with the var Carr = line, if you omit the callback function then forEach turns into a simple array copy. (Not efficient, but better than crashing when the callback is omitted.)
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
<script type="text/javascript">
Array.prototype.forEach = function( callback )
{
var ar = [];
for ( var i = 0; i < this.length; ++i )
{
ar[i] = ( callback == null ) ? this[i] : callback( this[i], this, i );
}
return ar;
}
var Aarr = [0,1,2,3,4,5,6,7,8,9];
var Barr = Aarr.forEach(
function(element, array, index)
{
array[index] *= 100;
return element + 17;
}
);
var Carr = Barr.forEach( );
alert(Aarr + "\n" + Barr + "\n" + Carr);
</script>
So that the caller of forEach could (as demonstrated) optionally modify the original array at the same time he/she returns a value for the new array. Taking a lead from how filter( ) works.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Well, you've managed to confuse the fool out of me.
I started out trying to figure out the .filter() function,
but have abandoned that because I thought I understood your Array.prototype function.
Now I don't understand what's happening with your latest modification with the 'callback' addition.
Here is the test code I am using to try to understand the working.
In the comment section at the end, I list what I expected and what is displayed.
??? indicates that I don't understand the results.
If you have the time, now that you have fogged my prior clarity, could you explain the
difference between what I thought I know and what is really happening?
(I may be testing your mind reading skills with that last statement).
Code:
<script type="text/javascript">
Array.prototype.forEach = function( callback ) {
var ar = [];
for ( var i = 0; i < this.length; ++i ) {
ar[i] = ( callback == null ) ? this[i] : callback( this[i], this, i );
}
return ar;
}
var Aarr = [0,1,2,3,4,5,6,7,8,9];
var Barr = Aarr.forEach( function(element) { return element + 1; } );
var BBarr = Aarr.forEach( function(element, array, index) { array[index] += 1; return element; } );
var Carr = Barr.forEach( );
var Darr = Aarr.forEach( );
var Earr = Aarr.forEach( function(element, array, index) { array[index] *= 100; return element; } );
alert('A : '+Aarr + "\nB : "+Barr +'\nBB: '+BBarr + "\nC : "+Carr + "\nD : "+Darr + "\nE : "+Earr +"\nA : "+Aarr);
/*
Expected to see:
A : 0,1,2,3,4,5,6,7,8,9
B : 1,2,3,4,5,6,7,8,9,10
BB: 1,2,3,4,5,6,7,8,9,10
C : 1,2,3,4,5,6,7,8,9,10
D : 0,1,2,3,4,5,6,7,8,9
E : 0,100,200,300,400,500,600,700,800,900
A : 0,1,2,3,4,5,6,7,8,9
Actual display:
A : 100,200,300,400,500,600,700,800,900,1000 ???
B : 1,2,3,4,5,6,7,8,9,10
BB: 0,1,2,3,4,5,6,7,8,9 ???
C : 1,2,3,4,5,6,7,8,9,10
D : 1,2,3,4,5,6,7,8,9,10 ???
E : 1,2,3,4,5,6,7,8,9,10 ???
A : 100,200,300,400,500,600,700,800,900,1000 ???
*/
</script>
First of all, understand this: Whatever the callback function *RETURNS* for each element it is called for is what ends up in the OUTPUT array. Anything the function does to the *ORIGINAL* array has *NO IMPACT AT ALL* on what happens to the output array.
SO;
Code:
var Barr = Aarr.forEach( function(element) { return element + 1; } )
You are not changing any elements of the Aaar array; you are returning each element + 1. So each element of Barr will be one greater than Aarr.
Great. That's what you expected. That's what you got.
*********
You are changing each element of the input array. But you are returning the *original* element value. So the output array (BBarr) will get a copy of the original array while, at the same time, each element of the original array is incremented by 1.
Remember: the value of element *IS* the ORIGINAL value of the element. Changing the element value inside the current (thiis) array does *NOT* impact the value of element.
Do you see the *HUGE* difference that makes? Here, you IGNORE the original value of element and go fetch it again as the return value. You could have also written this as
Same thing as with BBarr. You are modifying the input (this) array but returning the ORIGINAL element value, so Earr gets a copy of the input array before the modifications.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
If you do NOT want to modify the input (this) array, then do *NOT* use the array or index arguments that are passed to the callback! Simple as that.
What you expected could have been produced via
Code:
var Aarr = [0,1,2,3,4,5,6,7,8,9];
var Barr = Aarr.forEach( function(element) { return element + 1; } );
var BBarr = Aarr.forEach( function(element) { return ++element; /* same as element + 1 */ } );
var Carr = Barr.forEach( );
var Darr = Aarr.forEach( );
var Earr = Aarr.forEach( function(element) { return element * 100; } );
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Maybe if we look at the forEach method it will be clearer. It truly is simple.
First of all, let me simplify it to *require* that the callback function be supplied:
Code:
Array.prototype.forEach = function( callback ) {
// we build the new array here:
var ar = [];
// we loop through every element of the old array:
for ( var i = 0; i < this.length; ++i ) {
// and we put the RESULT of calling the callback function into
// the corresponding element of the new array:
ar[i] = callback( this[i], this, i );
}
// finally returning the new array:
return ar;
}
So the only thing to really need to understand is this line:
Code:
ar[i] = callback( this[i], this, i );
The assignment into the new array is hopefully obvious. So let's look at *HOW* the callback function is called:
Code:
callback(
this[i], /* the *VALUE* of the current (i-th) element of the array */
this, /* the *ENTIRE* current array */
i /* the element number */
);
So you can see that in your callback function:
Code:
// using one of your example:
function(element, array, index)
{
// remember: element is the *VALUE* of array[index]
// but it was *ALREADY* fetched out of the array in the forEach method/function
// so when we do this, we are indeed changing the element number index in the
// original array...
array[index] += 1;
// but that in no way affects the value of element:
return element;
}
Did you perhaps forget that arrays are passed to functions *BY REFERENCE*? So the variable array in your callback function is 100% the same *OBJECT* as the array referred to by this in the forEach method.
Clearer?
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.