Custom-Sorting Arrays for Dummies

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

Custom-Sorting Arrays for Dummies

Martin Marris

Here is how to do a SortSparseArrayCustom, explained in elementary terms. (It is also applicable to custom-sorting old-fashioned non-sparse arrays too, except that they can only handle numbers and strings.)


The ingredients of the recipe are:

--utils.SortSparseArrayCustom (or its non-sparse equivalent utils.SortArrayCustom)

--utils.QuickSortSparse (or its non-sparse equivalent utils.QuickSort)




If you are still using Sibelius 6 and you want to sort Sparse Arrays, the first two of those methods will be missing from your shipping "utils" plugin -- so you will have to open the utils method in Sibelius 7 and carefully copy/paste the contents of those methods, and their parameter fields, across to the utils method in Sibelius 6. Or if you are feeling reckless, I suppose you could delete the entire “utils” method-file from Sib6 and replace it with the one from Sib7, but I didn’t try that.


The syntax for utils.SortSparseArrayCustom is:


utils.SortArrayCustom(arr, show progress, plug-in name, method)


The first two variables are obvious. The last two pertain to a special method that you will be using to "tell" SortArrayCustom how to sort array arr. I will call this the "custom-sort method."

--plug-in name is the name of the plugin that contains the custom-sort method

--method is the name of the custom-sort method


You don't actually have to write the custom-sort method yourself because Sibelius comes with two boilerplate custom-sort methods:

--utils.StringLess which will sort in string order; or

--utils.Numberless which will sort in numeric order.


So let’s say you have a really boring, single-level Sparse Array called MyArray that contains nothing except a list of numbers. You could sort the array like this:

--utils.SortArrayCustom(MyArray, false, “utils”, “NumberLess”)


To sort in string order, you would do exactly the same except for using “StringLess” as the fourth value.


I know the above seems really simple but it took me a very long time to figure it out, even with Bob’s help. The rest is all downhill skiing!


Now for something much more interesting. Let’s say we have a large Sparse Array containing thousands of elements. These elements are, themselves, arrays – which I will call “sub-arrays.” Each sub-array has a first element consisting of a numeric string (this is element “0” of the sub-array) and then a variable quantity of long text strings for the rest of the elements (element “1”, “2”, “3”…..).


I need to do a numeric sort keyed on field “zero” in each sub-array, such that the sub-arrays will be re-ordered within the main array (while maintaining the content of each sub-array in its original order).


So let’s take a look at the shipping version of NumberLess:



Obviously this code is not “sub-array aware.” Strangely enough, under some circumstances it will actually “work” even if you pass it sub-arrays, but that’s only because it “flattens” each sub-array into a very long single-string item and, as it happens, my numeric sorting key happens to be the first item of this long string. But even if it gives the right results, it will run slowly – about 30 seconds for an array that contains a thousand sub-arrays, for instance – presumably because it is evaluating the entire contents of the interminable text strings.


So looking at Hans and Bob’s code, you see that it takes incoming strA and strB and returns a sort token. But we know that in the current case, the incoming objects are not strings, but arrays. So we can write a “sub-array-aware” custom method of our own:



The incoming arsA[0] and arsB[0] are the sub-arrays’ numeric sorting key. I added the “plus zero” just to enforce the number type although perhaps it wasn’t needed.


Now save the new custom-sort method. Insert its plugin/name information into the SortSparseArray variables. That’s it.


Remember I said that the “non-customized” sort took about 30 seconds? Well, the customized one did its work in 160 milliseconds. This was for an array that contained about 1,200 sub-arrays, with each sub-array containing about twelve lines of string data.


I hope plugin writers will find this explanation useful. Many thanks to Hans-Christoph and Bob for coming up with this amazing stuff in the first place!


(It seems that some cool sorting can also be done using Dictionaries and I’m looking forward to that, too.)


Best regards,




Plugin-dev mailing list
[hidden email]