Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Page 2 of 2 FirstFirst 12
Results 16 to 24 of 24
  1. #16
    Senior Coder Logic Ali's Avatar
    Join Date
    Sep 2010
    Location
    London
    Posts
    1,028
    Thanks
    0
    Thanked 207 Times in 202 Posts
    Quote Originally Posted by jmrker View Post
    I was trying to add 1 to each element of the original array
    And see that the new array had values all incremented by one.

    I thought I could avoid a for...loop with a filter() command.
    During execution, filter won't give you access to the array it generates, but forEach lets you specify the object treated as this:

    Code:
    <script type="text/javascript">
    
    var arr = [ -1, 0, 1, 2 ],
        bumpedArray = [];
    
    arr.forEach( function( elem ){ this.push( elem + 1 ); }, bumpedArray );
    
    alert( bumpedArray );
    
    </script>

  2. #17
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,536
    Thanks
    80
    Thanked 4,490 Times in 4,454 Posts
    That is, of course, not the same forEach that I created.

    I don't like the built in forEach very much. It just doesn't make intuitive sense that the this in the callback function has to refer to the second argument of the method.

    It makes it feel like the callback is a method *ON* that second argument. Which I guess it is. But it's just weird.
    Last edited by Old Pedant; 01-05-2013 at 04:00 AM.
    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.

  3. #18
    Senior Coder Logic Ali's Avatar
    Join Date
    Sep 2010
    Location
    London
    Posts
    1,028
    Thanks
    0
    Thanked 207 Times in 202 Posts
    Quote Originally Posted by Old Pedant View Post
    It just doesn't make intuitive sense that the this in the callback function has to refer to the second argument of the method.
    The second parameter is optional.

  4. #19
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,536
    Thanks
    80
    Thanked 4,490 Times in 4,454 Posts
    Quote Originally Posted by Logic Ali View Post
    The second parameter is optional.
    Yes, but if it is omitted then this in the callback refers to the window! About as useless a choice as possible, methinks.
    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.

  5. #20
    Senior Coder Logic Ali's Avatar
    Join Date
    Sep 2010
    Location
    London
    Posts
    1,028
    Thanks
    0
    Thanked 207 Times in 202 Posts
    Quote Originally Posted by Old Pedant View Post
    Yes, but if it is omitted then this in the callback refers to the window! About as useless a choice as possible, methinks.
    It was probably considered to provide more versatility, especially as a reference to the array is still provided via one of the parameters passed to the callback.

  6. #21
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    Isn't this in forEach potentially useful though? For example, to multiply two arrays, perhaps in reverse order:

    Code:
    function multReverse(element, index, array) {
        var theEnd = theEnd || this.length - 1;
        this[theEnd - index] *= element;
    }
    var a = [ 2, 5, 9 ], b = [ 3, 4, 5 ];
    a.forEach(multReverse, b);
    console.log(a); // [ 2, 5, 9 ]
    console.log(b); // [ 27, 20, 10 ]
    But this could also be an object. Perhaps even a NodeList . Perhaps we could use it to store a NodeList in an array and do array-like things with it(?).
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  7. #22
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    We could use it to create list and dictionary comprehensions . Or our own slice() method:

    Code:
    function listSlice(element, index, array) {
        if (!this[2]) this[2] = array.length - 1;
        if (index >= this[1] && index <= this[2]) {
            this[0].push(element);
        }
    }
    var a = [ 2, 5, 9, 8, 6 ], b = [];
    a.forEach(listSlice, [b, 2]);
    
    
    console.log(a); // [ 2, 5, 9, 8, 6 ]
    console.log(b); // [ 9, 8, 6 ]
    Last edited by AndrewGSW; 01-06-2013 at 12:50 AM.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  8. #23
    Senior Coder jmrker's Avatar
    Join Date
    Aug 2006
    Location
    FL
    Posts
    3,097
    Thanks
    38
    Thanked 498 Times in 492 Posts

    Lightbulb

    While I agree that the .forEach as defined by 'Old Pedant' has a bunch of potential,
    it appears for the simple action I wanted, it is a bit of overkill.

    On my machine the following pseudo execution speed test favors the simple function,
    just as 'Old Pedant' predicted.
    ---------------------------------
    execution speed test:

    .forEach: 425
    incrementArray: 16
    ---------------------------------
    Code:
    <!DOCTYPE html>
    <html lang="en">
    <meta charset="utf-8" />
    <title> .forEach prototype vs array function </title>
    </head>
    <body>
    <div id="debugger" style="font-family:monospace"></div>
    
    <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;
    }
    Array.prototype.createStrArray = function(n) {
      return Object.keys(Object(Array(n)+"r")).map(Number);   // creates [0,1,2,...,(n-1)]
    }
    function incrementArray(arr) { for (var i=0; i<arr.length; i++) { arr[i]++; } return arr; }
    
    // Execution speed test
    var str = 'execution speed test:';
    var arr = [].createStrArray(100);
    
    var start1 = new Date();
    for (var i=0; i<100000; i++) { var Barr = arr.forEach( function(element) { return element + 1; } ); }
    var end1 = new Date();
    
    var start2 = new Date();
    for (var i=0; i<100000; i++) { var Barr = incrementArray(arr); }
    var end2 = new Date();
    
    str += '<p>.forEach: '+(end1 - start1)+'<br>incrementArray: '+(end2 - start2);
    
    document.getElementById('debugger').innerHTML = str;
    
    </script>
    </body>
    </html>

  9. #24
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,399
    Thanks
    11
    Thanked 595 Times in 575 Posts
    Quote Originally Posted by Logic Ali View Post
    During execution, filter won't give you access to the array it generates, but forEach lets you specify the object treated as this:
    so does filter and map ...

    Quote Originally Posted by jmrker;
    I was trying to add 1 to each element of the original array
    And see that the new array had values all incremented by one.

    I thought I could avoid a for...loop with a filter() command.
    then simply use .map() instead of .filter(). if your array has a name, you can name it in arguments[1] on the map() call so that it's called "this" within the function, or as arguments[2] inside the function...
    Last edited by rnd me; 01-07-2013 at 09:49 AM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%


 
Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •