NAME

sort_vectors.pl

SORT A GROUP OF EQUALLY-SIZED ARRAYS MAINTAINING THEIR RELATIONSHIP. USAGE: sortVectors([indexonly,] \@sortbylist, \@sortformat [, low , hi], array-refs)


DESCRIPTION

indexonly: scalar value: if true, only return a sorted array of indices, which the user can use to traverse the arrays, without actually changing them. This is faster. If false, arrays are resorted and the sorted array of indices is still returned.

sortbylist: an array of ONE-BASED integers specifying the order each array is to be used in controling the sort, ie. [2, -1, 3] means sort order first by the elements of the 2nd array, then within that by descending order of the elements of the 1st array, then by the elements of the 3rd array (ascending). Negative numbers indicate descending order. Default is [1, 2].

sortformat: an array of values, one for each array to be sorted indicating the format of the sort. 'n', 'N', 1, or any number indicates a numeric sort, any other value not starting with an amprasand indicates a string sort. Default is ascii string sort. A value starting with an apresand represents the name of a user- defined function to perform the sort for the corresponding array.

low, high: specify zero-based starting and ending indices for sorting the arrays, For example if arrays are 10 elements long and one wishes to leave the 1st 3 and the last 2 elements unchanged, one would specify 3 for low and 7 for high. Default for low is zero and high is the length of the arrays - 1 (zero-based).

sortVectorsSimple - simply sorts all arrays based on the 1st array, then by the 2nd array in ascending ascii string order. Same as sortVectors([], [], \@array0, ...) or sortVectors(0, [1, 2], [qw(s s s..))], 0, $#array0, \@array0, ...);


EXAMPLES

        require 'sort_vectors.pl'; 
        @names = ('Doe, John', 'Smith, Richard', 'Jones, Mike'); 
        @phones = ('111-1111', '222-2222', '333-3333'); 
        @ages = (50, 26, 41); 
        @l = &sortVectorsSimple(\@names, \@phones, \@ages);

This sorts and rearranges each array based on the 1st one and sets @l to 0, 2, 1; @names to 'Doe, John', 'Jones, Mike', 'Smith, Richard'; and @ages to 50, 41, 26

        @l = &sortVectorsSimple(1, \@names, \@phones, \@ages);

This simply sets @l to 0, 2, 1; leaving the arrays in their current order.

        &sortVectors([3, -1], [undef, undef, 1], \@names, \@phones, \@ages);

This sorts by '@ages', then by '@names' descending, using a numeric sort for sorting the 3rd array ('@ages'). The '@names' array is sorted alphabetically within a given age. The elements of the format array (2nd argument) can be integers (for numeric (``<=>'') sorts), '&someFn' (name of a custom sort function - starting with an amprasand), or any other string or undef for alphabetic (``cmp'') sorts.

        &sortVectors(0, [3, -1], [undef, undef, 1], \@names, \@phones, \@ages);

This does same as above.

        my @sv = &sortVectors(1, [3, -1], [undef, undef, 1], \@names, \@phones, \@ages);

This does same as above, but does not actually sort the arrays, but rather returns an array of indices such that traversing that array in order using it as the subscripts results in traversing the arrays in sorted order.

For custom sort functions, the ``a'' and ``b'' arguments of the standard Perl ``sort'' function are passed to the function by default as the 1st 2 arguments. If sort is descending, then they are passed in order of: ``b'', ``a''. The function can have other constant values passed to it, and the two sort arguments can be specified as either a single or pair of asterisks, otherwise, the 1st 2 arguments will be passed as described above. The following examples are valid:

        '&sam'
        '&mySortFn()'
        "&main::sortem('a_string', *, 3, *, 'something else')"
        '&sortthis(*,*)'

An example function (that sorts first alphabetically by the 1st character, and then numerically the remainder of the string for values such as 'B1742':

sub mySortFn { return substr($_[0],0,1) cmp substr($_[1],0,1) || substr($_[0],1) <=> substr($_[1],1); }