connectedpixel.com

actionscript, web development

Array.sortOn does not work with MovieClips

Submitted by joelmay on 2 October, 2006 - 1:57pm.

This problem drove me crazy. I'd thought I'd get it in the google-verse so anyone else who runs into it can benefit from my pain.

Array.sortOn() does not seem to work when the array elements are objects derived from MovieClip. The following code demonstrates.

Simple class. "zz" property will be used to sort an array of these objects.

Same as above, but derived from MovieClip.

This code goes in frame 1 of the fla. It assumes there is a symbol in the library called "SortOnTest" which is linked to McThing.

Here's the trace output:

As you can see, the array of movieclip-derived objects is not sorted.

Even stranger: if I rearrange the second array (swap elements), then call sortOn, it forces the order to its original (incorrect) order. Weird.

If I am doing anything wrong, please let me know.

BTW, this is Flash 8. I haven't tried this in any other version.

Anonymous (not verified) Says:

arr1 = arr1.sortOn("zz",

3 October, 2006 - 6:05am

arr1 = arr1.sortOn("zz", Array.NUMERIC);
arr2 = arr2.sortOn("zz", Array.NUMERIC);

that's how I use it and guess what: it works!

joelmay Says:

Still seeing the same problem

3 October, 2006 - 10:21am

I just tried that, and I'm getting the same erroneous behavior. Maybe there is something extremely stupid that I'm doing elsewhere in the code. If you're a glutton for fixing boring problems, you can download the source files.

You can see the bug in execution here.

I tried running in in Win Firefox and IE and Mac Safari. Also tried it with Flash player 7, 8 and 9.

Chris (not verified) Says:

it's normal behaviour

3 October, 2006 - 12:06pm

Hi!

sortOn works only for indexed arrays. When you push a movie clip in an array, actually only a reference of the movie is placed in the array, and not the movie clip itself; the movieclips are placed in the parent movieclip, which is not an indexed array.

I think it's normal behaviour.

When dealing with sorting movieclips, I'm using a custom dataprovider which is on Array of Object. I sort the array and then, attach or (re)position the clips.

joelmay Says:

Still does not make sense to me

3 October, 2006 - 1:19pm

What you're saying is probably correct because it is in fact behaving that way. But it still does not make sense to me.

I understand that the array elements are references to the movieclips, not the movieclips themselves. All non-primitive objects in ActionScript are accessed via references. Array.sortOn is specifically designed to work with array elements that are objects (i.e. references). A given object reference can be in any number of arrays, each sorted differently.

Furthermore, I'm free to write my own sort function and it will work fine. Here it is:

Here it is in action. And here are the source files.

This bubble sort function is a reasonable substitute, but if the array is large, it will be slow. It would be better if the the native Array.sortOn function had the same behavior. It does not make sense to me that the output of Array.sortOn should be different from this bubbleSort.

It appears that somehow a movieclip reference is different from a non-movieclip reference. But only in such a way that it does not work with sortOn but does work with bubbleSort.

My mental model of how the Flash virtual machine works is broken. I'm in pain.

Chris (not verified) Says:

My advice...

3 October, 2006 - 1:50pm

UI logic must be in one place and app logic in other.. do not mix them in that way that you must sort the movie clips.

What's the point in sorting the an array of movieclips? All the data that comes from a server, config file, runtime engine must be stored in an data provider.

Sort the data provider and then work with (or update) the user interface.

Joshua Mostafa (not verified) Says:

What nonsense. You could

21 November, 2006 - 11:37pm

What nonsense. You could have any number of reasons for sorting the movieclips. I am doing it myself and it is for pure UI purposes; to make sure I put the data (sorted elsewhere in the app) into the right places on the UI.

Stuart (not verified) Says:

Ran into this problem as well

21 December, 2006 - 6:56pm

Yep I feel for you. I just ran into this problem. I solved it by encapsulating the subclassed mc inside a sub of object. That finally let my order by _x!!!!!1112@!!!@ Thank yOu flash! However it still doesn't like using my get accessor function. I haven't tried this with as3, but I'm assuming its fixed

joelmay Says:

That's a good work around

22 December, 2006 - 9:13am

Making an adjustment to your algorithm like that is the best solution. Your algorithm still uses the native sortOn rather than an AS based bubble sort, so its performance should be good.

Working around problems like this is not really difficult once you understand where the problem is. Finding the source of the problem in the first place can make you tear your hair out.

Anonymous (not verified) Says:

When you push a movie clip

17 October, 2006 - 1:42am

When you push a movie clip in an array, actually only a reference of the movie is placed in the array, and not the movie clip itself; the movieclips are placed in the parent movieclip, which is not an indexed array.

Ha I agree.

Anonymous (not verified) Says:

So, you've never sorted an

8 January, 2007 - 1:36pm

So, you've never sorted an array of pointers? Thats usually the quickest, and best way to do a sort, is to sort the references, and not the actual data. This is a pretty silly statement imo...

Sorting (copying around) actual data is EXTREMELY slow, and should be avoided at all costs. Thats one of the reasons why he wanted to use the internal sortOn statement...

Emma Petrie (not verified) Says:

Bless you

9 January, 2007 - 2:02am

Gosh....I was working on this for HOURS....
Whew! I thought I was going CRAZEEEEYYYY!
Thank you so much for this post!!!!!!!!

=)

Steve (not verified) Says:

Thanks Anonymous for the

3 September, 2007 - 3:04pm

Thanks Anonymous for the Array.NUMERIC post, that was the issue with my sorting problem.

mugurm (not verified) Says:

Lack of quotes causing problem

5 December, 2007 - 1:59pm

I had this problem too, trying to sort on x position in AS3
turns out the problem was my lack of quotes "x"

//WRONG
myArray.sortOn(x, Array.NUMERIC);

//CORRECT
myArray.sortOn("x", Array.NUMERIC);

Scott (not verified) Says:

Just wanted to say thanks

23 January, 2008 - 1:20am

I fought with this for almost an hour before I figured out it wasn't me, did some googling, and found your site confirming that I wasn't having a seizure. Thanks for posting your experience and saving me yet another hour.

Tom Callahan (not verified) Says:

thank you

26 March, 2008 - 11:17am

Thank you! This post will probably get renewed interest as people working in AS3 with its better sortOn are forced to work on AS2 projects.

I've been doing AS3 exclusively the past few months and had to do an AS2 project and tried to back-port some utility code I had written in AS3 to AS2 and ran into this issue. No error, no warning, it just randomly re-sorted my mcs based on who knows what (seemingly random).

One note for anyone that uses the solution posted above, it only works on numeric properties (but the native sortOn appears to be working fine when sorting by string properties (e.g. "_name") ). And to reverse the sort order just change the > in

if (arr[i-1][prop] > arr[i][prop]){

to a <.

David Hartono (not verified) Says:

my solution

28 March, 2008 - 9:39am

I ran into the same problem, and I made a function to solve it. work fine for me

here it is

public static function sortMovieClipString(arraySorted:Array , sortId:String):Array{
var n_Array:Number = arraySorted.length;
var k:Number;

//create a new dummy array as a array that we are going to sort with sort on
var newArray = new Array();

//create a dummy object with:
// - original id = where the original movieclip object is located in the source array
// - sortValue = the string value we want to sort
for (k=0;k