5 Replies Latest reply on Jun 16, 2016 12:10 PM by K.Daube

    Arrays are objects - really?

    K.Daube Level 1

      Dear experts and gurus,

      The more I read the more I am confused. Every now and then the talk is "JS Arrays are objects and hence they are passed by reference". However, simple experiments leave my puzzled: It's the same as with light (depending on the view it behaves as waves or as particles):

       

      gaSomething = ["a","b", "c"];
      Update (gaSomething);
      alert (gaSomething.join("\n"));         // the global array has changed
      
      DeleteItem (gaSomething, "7");
      alert (gaSomething.join("\n"));         // the global array has not changed
      
      function Update (array) {
        for (var j= 0; j < 9; j++) {
          array.push(j+1); 
        }
      }
      
      function DeleteItem (array, item) {
        var index = IsInArray (array, item);
        var lower = array.slice (0, index);   // lower part
        var upper = array.slice (index+1);    // upper part
        var locArray    = lower.concat(upper);
        array = locArray;                     // transfer data
      alert ("in DeleteItem:\n" + array.join("\n"));
      }
      


      The only safe assumption is that JS arrays are not treated as objects and hence are passed by value. This makes it difficult to set up functions to delete items from various arrays - for each array a distinct function is needed!

       

      Any ideas for a general DeleteItem function ?

        • 1. Re: Arrays are objects - really?
          Klaus Göbel Level 3

          Hi Klaus,

           

          to delete several items in an array, you have to go backward:

           

          1. for (var j=9 ; j > 5; j --) { 
          2.     array.slice(j);  
          3.   } 

           

          In an arry with 10 items: if you delete item 9 the array now has 9 items. Item 10 doesn't exist any more.It is now item 9

          If  you delete item 9 NEXT you delete the former item 10 (the last original item).

          • 2. Re: Arrays are objects - really?
            K.Daube Level 1

            Thanks Klaus, for Your answer.

            However, I want to delete an item within the array. Unfortunately the splice function does not exist in ES...

            Looking at my example script:

             

            • At line 05 gaSomething is a,b,c,1,2,3,4,5,6,7,8,9
            • Lines 16 and 17 do not change argument array: a,b,c,1,2,3,4,5,6,7,8,9
            • At line 19 array is a,b,c,1,2,3,4,5,6,8,9 - the item with value 7 has been removed.
            • But this is all within the function - obviously not on the global array gaSomething
            • which is after the function call: a,b,c,1,2,3,4,5,6,7,8,9

            Again I read  (O'Reilly: JavaScript: The Good Parts, 2013 - BTW written with FM 5.5.6)

            that «In JavaScript, arrays are objects, functions are objects, regular expressions are objects, and, of course, objects are objects.»
            Hence I tried this:

             

            gaSomething = ["one","two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
            gaSomething.sort();
            
            Console (gaSomething);                  // eight,five,four,nine,one,seven,six,ten,three,two
            DeleteItem3 (gaSomething, 7);
            Console (gaSomething);                  // eight,five,four,nine,one,seven,six,three,two,
            
            function DeleteItem2 (array, index) {
              var locArray = array;
              delete locArray[index];                    // ...six,,three...
              locArray.sort();                            // six,three,two,
              array= locArray.slice(0,locArray.length-1); // six,three,two <- no last undefined
            Console ("array within function\n" + array);
            }
            
            function DeleteItem3 (array, index) {
              delete array[index];                    // ...six,,three...
              array.sort();                            // six,three,two,
              array= array.slice(0,array.length-1);    // six,three,two <- no last undefined
            Console ("array within function\n" + array);
            }
            

            Whether I use DelteItem2 or ...3 in line 05, the results are the same: outside of the function the global array still has it's last undefined item (indicated by the last comma in the console log - or alert).
            How to get rid of this?

            • 3. Re: Arrays are objects - really?
              K.Daube Level 1

              Ah, the length property is writable...

               

              function DeleteItem (array, index) {
                delete array[index];                    // ...six,,three...
                array.sort();                            // six,three,two,
                array.length = array.length-1
              }
              

              This works as intended. Outside the function the global arry is now

              eight,five,four,nine,one,seven,six,three,two

               

              So "arrays are objects" is really true.

              Thanks all for the discussion

               

              Addendum:

              If there is already an undefined item in the array, the final array will contain this at its last item.

              • 4. Re: Arrays are objects - really?
                Klaus Göbel Level 3

                Hi Klaus,

                That is very dangerous !!!

                 

                1. array.length = array.length-1 means: delete the last item in an array

                array.length = array.length-5 deletes the last 5 items in an array

                 

                delete array[index] only deletes the VALUE of the item !!!!!

                When you sort it, it's at the end of the array and so you succeeded to delete that.

                 

                My code in my last post IS WRONG:

                It must be :

                1. for (var j=9 ; j > 5; j --) { 
                2.     array.slice(j,1); 
                3.   }

                 

                However, I want to delete an item within the array. Unfortunately the splice function does not exist in ES...

                It is slice - not splice !!

                 

                You really have to delete Items reverse.

                 

                Just try this function. It deletes items 3 and 2

                function DeleteItem (array, index)
                {
                 $.writeln(array);
                 for (var j=3 ; j > 1; j --)
                    { 
                    $.writeln("delete: " + array[j]);
                    array.splice(j,1);  
                    $.writeln(array);
                    }  
                   
                }
                
                • 5. Re: Arrays are objects - really?
                  K.Daube Level 1

                  Dear Klaus Göbel,

                  Yes, I know the difference between slice and splice - but only after testing Your sample I found that splice exists in ES - up to now I was convinced that it does not exist (as indexOf does not exist for arrays).

                  With splice the task will be simple and will not require sorting.

                  My code uses the length-1 to get rid of the undefined item which occurs after the deletion somewhere in the middle of the array:

                  delete array[index];               // ...six,,three...  five has been deleted
                  array.sort();                      // six,three,two,    moves the undefined item to the end
                  
                  array.length = array.length-1      // get rid of last (undefined item)
                  

                   

                  But with splice thing become sooo easy:

                  «splice: Removes num elements from the array beginning with index, start. Optionally insert new elements beginning at index start. To ensure contiguity, elements are moved up to fill in any gaps. Returns a new array containing any elements deleted from the original array.»

                  gArray= ["one","two", "three", "four", "five", "six", "zz", "seven", "eight", "nine", "ten"];
                  Console ("array before function DeleteItem=\n" + gArray);
                  DeleteItem (gArray, 6);    // removing item "zz"
                  Console ("array after function DeleteItem=\n" + gArray);
                  
                  function DeleteItem (array, index)  {  
                          array.splice(index,1);    
                  } 
                  

                   

                  Thank You Klaus for putting me back on the correct road