3 Replies Latest reply on Jun 7, 2010 3:23 AM by Harbs.

    While Loop with Array.pop() Gotcha

    Harbs. Level 6

      Just a bit of a heads up:

       

      A number of us have been using a while(obj=array.pop()){} construct for a while. (I believe Marc was the one to introduce this construct to this forum.)

       

      While this is considerably more efficient than a standard for loop when you don't need the array when the loop ois done, there's a not-so-obvious gotcha:

       

      0 in javascript is evaluated to false, so : while(0) is equivalent to while(false).

       

      If you have an loop like this:

       

      ar = [1,0,8,6];
      while(a=ar.pop()){
          // do your stuff
          }
      

      6 and 8 will resolve true, but 0 will not. The loop will exit when it hits 0, and neither 0 nor 1 will be processed.

       

      This loop is no good either:

       

      ar = [1,0,8,6];
      while(a=ar.pop() != null){
          //do your stuff
          }
      

      because "a" will evaluate to either true or false instead of the value of the array because statements are processed backwards (i.e. a = (ar.pop != null)).

       

      Instead you need (note the extra parenthesis):

       

      ar = [1,0,8,6];
      while((a=ar.pop()) != null){
          //do your stuff
          }
      

       

      HTH,

      Harbs

        • 1. Re: While Loop with Array.pop() Gotcha
          Harbs. Level 6

          Actually, even the last construct is not  safe. If there's a null object in the array it'll exit prematurely as well.

           

          For null objects, this will work:

           

          ar = [1,null,8,6];
          while((a=ar.pop()) !== undefined){
              //do your stuff
          }
          
          

           

          But if you have a non-consecutive array this too will fall flat on its face:

           

          ar = [1,null,8,6];
          ar[6] = 2;
          while((a=ar.pop()) !== undefined){
              //this will only process 2
          }
          

           

          Bottom line, don't use the pop() as the condition of the loop. Do something like this instead:

           

          ar = [1,null,8,6];
          ar[6] = 2;
          while(ar.length){
              a=ar.pop();
              // now we can process all elements of the array!
          }
          

           

          Harbs

          • 2. Re: While Loop with Array.pop() Gotcha
            Marc Autret Level 4

            Good point, Harbs ;-)

             

            That's why I wouldn't recommand using the while( a=ar.pop() ){...} pattern on simple one-dimensional arrays that contain, or could contain primitive types. As a general rule I use this tip on temporary arrays of objects, or on n-dimensional temporary arrays, because I am absolutely sure that none of the elements can be evaluated to false. Then it is a useful shortcut. In other situations the old good index loop is the best although it requires an additional variable.

             

            @+

            Marc

            • 3. Re: While Loop with Array.pop() Gotcha
              Harbs. Level 6

              Hi Marc,

               

              I wasn't blaming you for my mistakes! I just got bitten by using this technique for primitive type arrays, and I figured I should prevent others from making my mistake...

               

              But even for primitive arrays, while(array.length)array.pop() is more efficient than a for loop.

               

              Harbs