16 Replies Latest reply on Mar 6, 2007 11:12 AM by Peter Lorent

    how to get length of array with named elements

    SPGAnne Level 1
      I must be doing something really dumb. I have an array with named elements, but I can't seem to get it's length.
      for example
      var myArray = new Array()
      myArray.item1 = new Array(1,2,3)
      myArray.item2 = new Array(x,y,z)

      trace (myArray.length) // this yields 0 instead of 2

      Thanks in advance for anyone who can help.
        • 1. Re: how to get length of array with named elements
          kglad Adobe Community Professional & MVP
          myArray contains nothing so its length is zero. myArray.item1 should have length 3.

          if you're trying to create an array within an array that's not the way to do it. and myArray.item2 isn't going to contain anything unless x, y and z are defined somewhere.
          • 2. Re: how to get length of array with named elements
            tonyhigham Level 1
            I would setup your array a little differently, but you can still accomplish what you want using a for...each loop.

            var count:Number = 0
            for(e in myArray){
            count++
            }
            trace(count)

            If you give some more information about what data you're storing in the array, maybe we can help you find a better setup.
            • 3. Re: how to get length of array with named elements
              SPGAnne Level 1
              Thanks very much to both of you for your willingness to unscramble my newbie brain and get me back on the right track. I want to create a data structure that will work for the following situation.
              a holder that can hold mutliple sets (e.g. Set1, Set2, Set3) each set contains 3 items, each of those items is a list of subitems. Example:
              SetHolder
              Set1
              itemsA(1,2,3,4)
              itemsB(5,6,7,7)
              itemsC(6,7,8,9)
              Set2
              itemsA(5,6,7,7)
              itemsB(8,8,8,8)
              itemsC(7,6,5,4)
              etc.
              I want to be able to access the sets in the SetHolder by name and the items in the sets by name.

              Thanks again for your patient help.
              • 5. Re: how to get length of array with named elements
                Peter Lorent Level 2
                Anne,
                Since you are working with OOP, maybe I can show you a way to work with datastructures. I've attached some sample code. The example looks at a store but it applies to every object that has a datastructure (which is the case with most objects...). A store has a collection of items. Every item has properties which make up the datastructure -> StoreItem.as. The items are stored in a collection -> StoreItemCollection.as. These classes define a datastructure, nothing else so no visual representation. You define the visual representation with -for instance- StoreItemView.as and StoreItemCollectionView.as. Yes, now you have a nice seperation of your data and the view and the next thing is to use a 'controller' - StoreManager.as - that loads the data (xml), creates the collection (using an instance of StoreItemCollection) and builds the view (using an instance of StoreItemCollectionView). And by using different types of collections you can have different departments in the store. Hope this helps.

                • 6. Re: how to get length of array with named elements
                  SPGAnne Level 1
                  kglad and LuigiL -
                  Thank you both very much for your always ready willingness to help me out. It is so wonderful to know that days and days don't go by being in a quandry. You 2 have come to my rescue so many times. Since by now, you know I'm not the fastest learner, I am going to study both of your answers in relation to my current project. LuigiL I really appreciate you giving me the OOP version, because sometimes I do stumble translating script stuff into well designed classes, so this is a good leg up for me. Thank you again.

                  P.S. If you have a moment, I posted another question a couple days ago still struggling with the finer points of garbage collection. I would again, so much appreciate any pointers you can give me with that.

                  your grateful cyberfan,
                  Anne
                  • 7. Re: how to get length of array with named elements
                    kglad Adobe Community Professional & MVP
                    you're welcome ms. anne.
                    • 8. Re: how to get length of array with named elements
                      SPGAnne Level 1
                      Dear kglad
                      OK. I've done some studying and still don't get it. When I do trace(aa.length) on your sample, I would THINK I should get a length of 2 since there are 2 items in the aa array - namely a and b. a being in the first position and addressed as aa["Set1"] and the b being in the second position and adressed as aa["Set2"]. Similarly when doing a trace(a.length) I would think I should get 3 items in that array, but again get 0.

                      I have found that the following way of writing the code yields exactly the same results as your sample.
                      var aa = new Array();
                      aa.Set1 = new Array();
                      aa.Set1.itemsA = new Array(1,2,3,4);
                      aa.Set1.itemsB = new Array(5,6,7,7);
                      aa.Set1.itemsC = new Array(6,7,8,9);
                      aa.Set2 = new Array();
                      aa.Set2.itemsA = new Array(5,6,7,7);
                      aa.Set2.itemsB = new Array(8,8,8,8);
                      aa.Set2.itemsC = new Array(7,6,5,4);
                      trace (aa.Set2.itemsB);
                      trace(aa.length);

                      However, in both cases if I do NOT use named items and just use numbers(see below) lengths are as I expected. In both cases (using named elements or using numbered elements in the arrays) all the data is stored properly, it's just this length thing that has me totally baffled.

                      a = [ ];
                      b = [ ];
                      aa = [ ];
                      a[0] = [1, 2, 3, 4];
                      a[1] = [5, 6, 7, 7];
                      a[2] = [6, 7, 8, 9];
                      aa[0] = a;
                      b[0] = [5, 6, 7, 7];
                      b[1] = [8, 8, 8, 8];
                      b[2] = [7, 6, 5, 4];
                      aa[1] = b;
                      trace(aa[1][1]);
                      trace(aa.length);
                      trace(a.length);

                      I find for my particular project the named elements more understandable from a code readbility point of view. Things length thing really seems odd since it clearly knows there is data in those spots as you can get at it and use it.
                      • 9. Re: how to get length of array with named elements
                        kglad Adobe Community Professional & MVP
                        i guess the flash length property is not accurate for associative arrays. you can use the lenghtF() method for associative arrays:

                        • 10. Re: how to get length of array with named elements
                          kglad Adobe Community Professional & MVP
                          well here's why:

                          "The Array class should not be used to create associative arrays, which are different data structures that contain named elements instead of numbered elements. You should use the Object class to create associative arrays (also called hashes). Although ActionScript permits you to create associative arrays using the Array class, you can not use any of the Array class methods or properties. At its core, an associative array is an instance of the Object class, and each key-value pair is represented by a property and its value. Another reason to declare an associative array using the Object data type is that you can then use an object literal to populate your associative array (but only at the time you declare it). The following example creates an associative array using an object literal, accesses items using both the dot operator and the array access operator, and then adds a new key-value pair by creating a new property:

                          var myAssocArray:Object = {fname:"John", lname:"Public"};
                          trace(myAssocArray.fname); // Output: John
                          trace(myAssocArray["lname"]); // Output: Public
                          myAssocArray.initial = "Q";
                          trace(myAssocArray.initial); // Output: Q"
                          • 11. Re: how to get length of array with named elements
                            SPGAnne Level 1
                            Again, I am VERY much obliged. As before, I need to digest slowly, ponder and develop a better design for my particular needs using this and LuigiL's suggestions. Thanks!!
                            • 13. Re: how to get length of array with named elements
                              SPGAnne Level 1
                              LuigiL,
                              After pondering kglad and your stuff, although my code was all working fine (with the exception of the length issue) using the semi-illegal (i.e. not recommended) named elements in arrays, I have now implemented a Collection class which is an array and the items in the Collection are now using my Set class which has properities, which include a name and a bunch of arrays for each of the subItems. I have implemented a getSet(name) method for my Collection class, which then iterates through the Collection's array looking for a Set with a poperty name that matches and returns the set. Viola all works fine.

                              I have also implemented a class called Loader which instantiates a Collection and uses xml to read a bunch of set definitions, and instantiates each Set and stores them in the Collection using addSet(set) When it is done, it broadcasts an event (collectionLoaded) saying it's done and passes the collection as an argument with the event. Voila, that all works fine. So here's my question.....

                              The class that instantiates the Loader (lets call it App) and tells Loader to do it's thing has a private var myCollection. The collectionLoaded(c:Collection) method of App then says myCollection = c; so that App has a reference to the new loaded collection. The question I have is do I now have just one collection in memory or do I have 2 (the one in the Loader object and one in my App class?

                              Thanks very much for your help.

                              Anne
                              • 14. Re: how to get length of array with named elements
                                Peter Lorent Level 2
                                >>it broadcasts an event (collectionLoaded) saying it's done and passes the collection as an argument with the event.
                                After you broadcasted the event, delete the data in Loader.... and see what happens. BTW. Have App remove the eventlistener in collectionLoaded() on the Loader instance.
                                If coded correctly (and your description sounds ok), you only have one dataset and code that only references that set.
                                In general, I delete everything in utility classes after they have done their work. So, lets assume the Loader has a property _data, then I would use delete _data; after the event is broadcasted. Then in App (in collectionLoaded), I would delete the Loader instance if it was declared as an instance property but I assume you used a local var in a method...

                                >>it broadcasts an event (collectionLoaded) saying it's done and passes the collection as an argument with the event.
                                Take it one step further and implement the Observer design pattern -> I believe you have the Moock book and he describes that pattern. When an app grows it can become a puzzle to keep track of all events that get broadcasted and the arguments they pass.

                                Last but not least. You will experience that your custom objects (always think of your classes as custom objects, I cannot stress that enough) will need references to one another. Eventually you feel you are behind a giant switchboard. The final step you need to take is implementing the MVC design pattern. Once you have formalized the relationship between the objects, the code becomes really reusable.

                                Another tip (looking at the store example I posted above):
                                At any time you can add information to a store item. For instance, when you want to animate (or drag) a store item, you would need to know in which container (movieclip) the store item lives. But when you create the store item in the dataset you don't know its path yet. When you create the movieclips for the store items, simply add the path to the store item dataset using a setter method in the StoreItem class. Using a getter you can retrieve the path at any time. The same goes for all other info you want to add or retrieve at runtime.
                                • 15. Re: how to get length of array with named elements
                                  SPGAnne Level 1
                                  LuigiL
                                  Thank you again for all the time you take to give me such detailed and good advice. I actually have been using the Observer design pattern for another part of my current project and it works like a champ. I've been doing quite a bit of head scratching about where to implement that whole mvc pattern and when it seems more light weight and straight forward to use events for subcomponents. I also have sort of a cascade of inter-related models in my current project and again am doing head scratching about how to handle all that. I hope I'm substantially on the right path. I guess I'll know for sure when it comes time to make a change/expand the basic design.

                                  Yesterday I burned many hours doing a bunch of experiments to see if I understand what and how things get removed when using delete. I'm still quite baffled by some stuff, but I won't bother you with those questions at this time. I'm going to lose much of today doing some accounting work I have been procrastinating for months. Yuk. :-(
                                  • 16. Re: how to get length of array with named elements
                                    Peter Lorent Level 2
                                    You're welcome.
                                    Well, if you already use the Observer pattern, then it's time to implement the MVC pattern. And it is not that hard to do. The MVC pattern just describes a formal relationship (they store instances of eachother) between the datamodel, the view and the controller that decides what needs to happen in a view when the user clicks something. So, once you have setup a menu in MVC, you can use that menu again in the same project or in a new project. Usually I devide an app in logical parts and program each part in a MVC pattern. When applicable I use the Delegation Event pattern to formalize the event flow. And for the utility classes (like classes that draw basic shapes) I use EventDispatcher (with AS3 we finally have a good event model!).
                                    If you have questions or are in need of assistance, drop me an email.