# custom_sort

Definition: | sequence s2 = custom_sort(object rid_s, sequence s1, object data={}, integer order=ASCENDING)
Description: | Sort the elements of sequence s1, using the compare function rid_s, which must have been obtained from calling routine_id.
pwa/p2js: | Supported.
Comments: | Alternatively (new in 0.8.0) rid_s can be the actual data to be sorted when s1 is a tagset, in which case a standard compare is used. To use a custom comparison routine in a tag sort, put the actual data to be sorted in data[1] instead (and tags in s1). Prior to 0.8.0 the only way that could be achieved was for the data being sorted to be placed in a file-level variable (see demo\tagsort.exw) that the custom comparison routine would then reference, which was obviously not thread-safe, and not even task-safe should the comparison routine invoke task_yield(), presumably in an attempt to remain responsive during a potentially lengthy sorting operation. The data parameter, if provided, should be a length-1 sequence, or an atom, containing the third parameter to be passed to the comparison routine. If data is left as the default of {}, the comparison routine only recieves two arguments, and in that way legacy code can continue to use custom_sort() without having to be modified. The order parameter can also be DESCENDING, or one of the other aliases, NORMAL_ORDER or REVERSE_ORDER. The compare function should be similar to the builtin compare(), accepting two arguments and returning -1, 0 or +1, or for a custom tag sort (with data!={}) it should have a signature similar to (integer i, j, object user_data), where user_data gets set to data[1], or data itself should it be an atom [eg a tag sort on raw memory].
Auxillary routine: | For compatibility with Euphoria, builtins/sort.e also defines sort_columns(sequence x, sequence column_list) as a specific custom sort. The column list should be an ordered set of integer column indexes, which can be negative to sort that particular column in descending order, eg `table = sort_columns(table,{2,1,-3})`.
Example Program: | demo\tagsort.exw
Implementation: | See builtins\sort.e (an autoinclude) for details of the actual implementation.
See Also: | sort, compare, routine_id, tagset
Technicalia | You can actually return a boolean result from the compare function when sorting in DESCENDING order, false when they should be swapped, or a negated boolean when sorting in ASCENDING order (-true when they should not be swapped), however the [negated] double or triple negative is a little bit confusing and somewhat misleading to say the least, and would break should the sort order be changed, therefore returning a -1/0/+1 result is strongly advised and recommended instead (of a boolean). Be warned that I have seen C++/Go/Lua with a custom comparator which yields a boolean result and would not translate naturally to Phix, plus I have also seen custom comparators in other programming languages that yield/expect all negative numbers to be treated as -1 and all positive ones as +1, which likewise Phix does not honour as things currently stand, and in fact when writing mpfr.e I passed the result from the C mpz_cmp() function through sign() for exactly that reason.