views:

54

answers:

4

For example I have two ArrayCollection's - firstAC and secondAC. If I do secondAC = firstAC, and than I make changes to secondAC (prehaps put a filterfunction on it) it somehow propagates to firstAC, would anyone tell me why that happens in Flex or Actionscript 3?

What can I do if I only want secondAC to get all data from firstAC but then when I make changes to secondAC it does not show in firstAC?

Thanxs a bunch for answers! Ladislav

+5  A: 

When you write secondAC = firstAC, you simply state that secondAC and firstAC are references to the same array collection.

What you want is to clone the first collection (as in, copy all elements one by one).

You should be able to do it with something like :

secondAC = new ArrayCollection();
secondAC.addAll(firstAC);
phtrivier
Thank you very much for explaining what is going on
Ladislav
+1  A: 

I have no idea of Flex or Actionscript, but looks like firstAC and secondAC point to the same array, therefore that's expected.

What you should do is just create another array, copy members, and they will be two real different entities.

Ariel
+1  A: 

Instead of secondAC = firstAC, you can try secondAC.addAll(firstAC).

Wesley Petrowski
A: 

In ECMAScript languages (AS1-3, JavaScript, et al.), when you use

var foo = //some value which is not a String or a Number

what you are really saying is "foo now points to the same object as that other variable." This means that in this situation, both arrays will be the same value:

var foo:Array = [ 1, 2, 3 ];
foo = bar;
bar.push( 4 );
trace( foo ); // 1, 2, 3, 4

This also works for functions:

var foo:Array = [ 1, 2, 3 ];
adder( foo );
function adder( bar:Array ):void {
    bar.push( 4 );
}

trace( foo ); // 1, 2, 3, 4

and it even works with XML:

var xml:XML = <root><foo/></root>;
var bar:XML = xml;
bar.children()[ 0 ].@bar = 1;
trace( xml.toXMLString() ); // <root><foo bar="1"/></root>

This is called "passing by reference" instead of "passing by value" or "passing by copy". It means that every time that an item is referenced, each variable will point to the same object.

There are many ways to get around this, and most of them depend on your context. For arrays, my favorite is Array.concat(), which returns a literal clone of the array. This means that anything I do to the returned value will not effect the original in any way. If I'm dealing with XML, however, I will do something like: var xml2:XML = XML( xml.toXMLString() );.

In your case, I would actually recommend that you use:

var secondAC:ArrayCollection = new ArrayCollection( firstAC.source.concat() );

This has the major benefits of not only being faster (it relies on compiled code instead of Flex SDK code and it also does not first instantiate a new array and then re-populate it), but it also has the distinct benefit of being available in older versions of Flex 3's SDK -- it is entirely backwards compatible.

Christopher W. Allen-Poole
Thank you very much for this answer, very nice examples...thanx for your time!Ladislav
Ladislav