11 Replies Latest reply on Jan 29, 2007 11:47 AM by Hugo_Core

    Clone ArrayCollection

    Hugo_Core
      Hi ALL []

      I decided to create a new topic to resolve a problem in another one...nevermind :P

      Simple Question

      I got a myOriginal (ArrayCollection), want to clone/replic this one and call the new : myCloned (ArrayCollection).

      myOriginal can NOT be update any more.

      This is my code so far but, it stills update the Original Collection. I prove that by loop and trace the Original Collection.


      [Bindable] private var myData:ArrayCollection;
      [Bindable] private var myCloned:ArrayCollection;

      private function resultHandler(event:ResultEvent):void {
      myData = event.result.db.data; // Original Data
      cloneOriginal(); // Execute the cloning
      myData.disableAutoUpdate(); // This is fake.. in the "core" still is updating..i think..
      }


      private function cloneOriginal():void {
      var myCloned:ArrayCollection = new ArrayCollection();
      for(var c:int=0; c < myData.length; c++) {
      myCloned.addItem(myData[c]);
      }


      Thank's in Advance.. ;)
      Core out..
        • 1. Re: Clone ArrayCollection
          ur_dtrain Level 1
          Use ObjectUtil.copy()
          • 2. Re: Clone ArrayCollection
            Hugo_Core Level 1
            hi ur_dtrain

            I already tried but copy() only work for objects right ?

            Here's my test..

            var myCloned:* = mx.utils.ObjectUtil.copy(myData);
            hList2.dataProvider = myCloned;

            Error : Cannot access a property or method of a null object reference.

            hope for some respond..
            • 3. Re: Clone ArrayCollection
              ur_dtrain Level 1
              First thing I noticed after taking a look at your code is that you are referring to an array collection item using brackets myData[c], wich is a no no: use getItemAt instead myData.getItemAt (c).

              If that fails you may have to create a custom deepCopy function at the object level:

              function deepCopy(oldObj:Object):Object{
              var newObj:Object = new Object();
              for each(var item:Object in oldObject){
              newObj[item] = oldObj[item];
              }
              return newObj;
              }

              for(var c:int=0; c < myData.length; c++) {
              myCloned.addItem(deepCopy(myData.getItemAt(c));
              }
              • 4. Clone ArrayCollection
                schjlatah
                I had a similar issue when I started coding in AS3. The problem is that composite data types do not get copied by value, but a reference is made to their location in memory. You can just copy int values and other primitive data types like that, those are copied by value, but not objects and things of the like. The response I got that addressed this issue was to create a ByteArray and copy all the data into it, like this:

                public function objectCopier(toAdd:Object):Object
                {
                var addME:Object = clone (toAdd);
                addME.mx_internal_uid = UIDUtil.createUID();
                return addME;
                }

                public function clone(source:Object):* // The asterisk declares the function of Variable type. How it works for anything.
                {
                var myBA:ByteArray = new ByteArray();
                myBA.writeObject(source);
                myBA.position = 0;
                return myBA.readObject();
                }

                then tell the SWF player that the new byte array is a new variable and give it a new ID in memory.
                I know its kinda convoluted, but it works like a charm and works on any type of data. I wish I could take credit for it, but someone else sent it to me.
                BlakeBarrett.net
                • 5. Re: Clone ArrayCollection
                  Hugo_Core Level 1
                  private function cloneOriginal():void {
                  for(var c:int=0; c<myData.length; c++) {
                  myCloned.addItem(myData.getItemAt(c));
                  }
                  hList2.dataProvider = myCloned;
                  Alert.show("The Original Array has been clonend");
                  }

                  Nope...Still Updating :(

                  private function deepCopy(oldObj:Object):Object{
                  var newObj:Object = new Object();
                  for each(var item:Object in oldObj){
                  newObj[item] = oldObj[item];
                  }
                  return newObj;
                  }

                  private function cloneOriginal():void {
                  var myCloned:ArrayCollection = new ArrayCollection;
                  for(var c:int=0; c < myData.length; c++) {
                  myCloned.addItem(deepCopy(myData.getItemAt(c)));
                  }
                  hList2.dataProvider = myCloned;
                  Alert.show("The Original Array has been clonend");
                  }

                  dataGrid Result Empty..:S

                  I change something on your second solution, flex reports a error in "for each(var item:Object in oldObject){" i switch oldObject to oldObj..

                  Hope for same feedback.. [[]]
                  Core
                  • 6. Re: Clone ArrayCollection
                    Hugo_Core Level 1
                    private function cloneOriginal():void {
                    for(var c:int=0; c<myData.length; c++) {
                    myCloned.addItem(myData.getItemAt(c));
                    }
                    hList2.dataProvider = myCloned;
                    Alert.show("The Original Array has been clonend");
                    }

                    Nope...Still Updating :(

                    private function deepCopy(oldObj:Object):Object{
                    var newObj:Object = new Object();
                    for each(var item:Object in oldObj){
                    newObj[item] = oldObj[item];
                    }
                    return newObj;
                    }

                    private function cloneOriginal():void {
                    var myCloned:ArrayCollection = new ArrayCollection;
                    for(var c:int=0; c < myData.length; c++) {
                    myCloned.addItem(deepCopy(myData.getItemAt(c)));
                    }
                    hList2.dataProvider = myCloned;
                    Alert.show("The Original Array has been clonend");
                    }

                    dataGrid Result Empty..:S

                    I change something on your second solution, flex reports a error in "for each(var item:Object in oldObject){" i switch oldObject to oldObj..

                    Hope for same feedback.. [[]]
                    Core
                    • 7. Clone ArrayCollection
                      schjlatah Level 1
                      I'm tellin' ya man, it is with the way the Flash Player handles Composite and Primitive data types. Anytime you loop through the Array, ArrayCollection, or Object you will get an issue of some kind. I had the same problem, try the ByteArray. Just copy and paste these two methods. It'll work. Let me know if it doesn't.

                      public function objectCopier(toAdd:Object):Object
                      {
                      var addME:Object = clone (toAdd);
                      addME.mx_internal_uid = UIDUtil.createUID();
                      return addME;
                      }

                      public function clone(source:Object):*

                      /* The asterisk declares the function of Variable type. How it works for anything.*/
                      {
                      var myBA:ByteArray = new ByteArray();
                      myBA.writeObject(source);
                      myBA.position = 0;
                      return myBA.readObject();
                      }
                      • 8. Clone ArrayCollection
                        Hugo_Core Level 1
                        Hey Nice Code!

                        I alredy accomplish to cloned.. We almost there!

                        For some reason, after the cloning function terminate, i can't access to the array again... why .. ? Code:

                        [Bindable] public var myOriginal:ArrayCollection;
                        [Bindable] public var myCloned:ArrayCollection = new ArrayCollection();
                        [Bindable] public var matches:ArrayCollection = new ArrayCollection();

                        public function objectCopier(toAdd:Object):Object {
                        var addME:Object = clone (toAdd);
                        addME.mx_internal_uid = UIDUtil.createUID();
                        return addME;
                        }

                        public function clone(source:Object):* {
                        var myBA:ByteArray = new ByteArray();
                        myBA.writeObject(source);
                        myBA.position = 0;
                        return myBA.readObject();
                        }

                        public function resultHandler(event:ResultEvent):void {
                        myOriginal = event.result.db.data;
                        var myCloned:ArrayCollection = clone(myOriginal);

                        hList.dataProvider = myOriginal; // Stay forever with this data
                        hList2.dataProvider = myCloned; // Array to work on it
                        }

                        public function datagridToXML():void {


                        var i:Number = 0;
                        var f:Number = myCloned.length;

                        var temp:* = myCloned.length;
                        Alert.show(temp); // !RETURNS 0!

                        but if the Alert is inside the resultHandler() works fine :S

                        Waiting for some feedback..
                        Core Thanks..
                        • 9. Re: Clone ArrayCollection
                          Hugo_Core Level 1
                          why can´t i access the ArrayCollection after function is over ?

                          it just what is messing..
                          • 10. Re: Clone ArrayCollection
                            Cheree Singal Level 1
                            That is because myCloned is also declared inside the function resultHandler(). It is a variable local to that function. You are making changes to it and not to the one that is declared globally. Whereaa you are accessing the global myCloned. Hope it helps:-)

                            Cheree
                            • 11. Clone ArrayCollection
                              Hugo_Core Level 1
                              Thank You for the help Cheree, after a While i made the correction:)

                              Final Code, thanks to anyone involve [[[]]]:

                              "-How Can I Clone a ArrayCollection"

                              import mx.utils.UIDUtil;
                              import mx.collections.ArrayCollection;
                              import mx.rpc.events.ResultEvent;

                              [Bindable] public var myOriginal:ArrayCollection;
                              [Bindable] public var myCloned:ArrayCollection = new ArrayCollection();

                              //FLEX THINGS..
                              public function objectCopier(toAdd:Object):Object {
                              var addME:Object = clone (toAdd);
                              addME.mx_internal_uid = UIDUtil.createUID();
                              return addME;
                              }

                              public function clone(source:Object):* {
                              var myBA:ByteArray = new ByteArray();
                              myBA.writeObject(source);
                              myBA.position = 0;
                              return myBA.readObject();
                              }
                              // END

                              public function resultHandler(event:ResultEvent):void { // Result of an HTTPService..Per example of course..
                              myOriginal = event.result.db.data;
                              myCloned = clone(myOriginal); // THE ACTION IS HERE

                              hList.dataProvider = myOriginal; // Stay forever with this data
                              hList2.dataProvider = myCloned; // Array to work on it
                              }