Attached is a plugin that shows some general ways to use a dictionary more
or less as an array. Forget the way the documentation talks about them for
the most part,
and just think of a dictionary as a fancy array.
In Run(), I create a global dictionary gd_dictNotes, so I can access it in
a dialog callback. Global dictionaries are not saved in the file, so you
have to recreate it each time the plugin runs, or at least once per Sibelius
I gather up all the notes in the selection, and from each note extract a key
that will uniquely identify it, and let me sort by location in the score:
The key is built so it can be compared as a unit for sorting. See
KeyForNoteInDict() for details.
I put each note into the dict, indexed by the key. Note that unison notes
will be overwritten so only 1 shows. You can fix that if it is important. I
did not care in this case. Dicts are useful for cleaning up duplicates.
I want the dialog to have a list of keys sorted by location in the score, so
I build an array by walking the keys in the dict:
for each Name name in dict...
The array becomes the list for a list box in the dialog. Not real user
friendly but this is just a demo.
In DoSelectNote(), I access the dictionary using the selected entry in the
dialog list as the key. This is very fast - no lookup needed.
>From the key I got the note in the dict.
So I never needed a sparse array at all. I often think of a dictionary as an
array indexed by key. If I want to iterate through the dictionary, I just
iterate on the key.
Observe that I did not need to sort explicitly, and I did not have to
lookup up the item. This is all much faster than the way I used to do
I might need to figure out a more user friendly key for the dialog, but I
could, for example, store a sparse array or a dict in the dict, rather than
the note if I needed more info.
Anyway, hope this is helpful. Feel free to reuse any of the code.
This is very useful. Probably my first implementation will be for deleting duplicate text items. I have a large batch of customer files with a lot of figured bass, and for some reason about one in 20 of them is a duplicate, placed exactly on top of the original.
Meanwhile I finally figured out a way to sort a sparse array containing objects, keyed on on a variable of the object. Or rather, I analyzed what I had done last summer and finally figured out how I did it back then. The trick is to make an array of arrays. The sub-arrays contain one object each, and in another field of the same sub-array you can store the obj.Variable as a string.
Once you've done that, you use SortSparseArrayCustom to sort the top-level array, and you use a sort method that looks something like this:
In this case, the variable I am sorting on is stored in field ars of the sub-arrays (the object itself is in field ).
This works very well, and last summer I wrote a large “symbol collection analyzer” that used it extensively.
Yes, it is a convoluted idea. In the implementation I wrote today, I even had to work with sub-sub-arrays because the sort was on two successive keys (first, sort on obj.Dy; then, within the results that have the same obj.Dy, sort on obj.Dx).
I am looking forward to seeing whether dictionaries can handle this kind of thing in a less complex way.