166

**Code Vault / a pair function adapters for sort_array**

« **on:**April 17, 2007, 08:53:23 AM »

I wrote a pair of function adapters for sort array which came up in a problem in sorting and displaying list data. The first comparator() converts a binary "greater or equal than" comparison into the 3 value comparison needed by sort_array that returns 1,0, or -1 depending on if the value is greater, equal or less than the respective second value respectively for example to sort a list of integers with this function one would do the following:

sort_array(array_of_ints, comparator( (: $1 >= $2 :) ) )

The second function is for sorting tuples when you have to sort a list of items which consist of lists of data or tuples where each element at a given index is of the same type. i.e. ({"Silenus", 1, "orc", "warrior"}), ({"Cratylus", 1, "human", "mage"}) it creates a comparison function which gives priority to the indexes as ordered. An example usage might be (using the previous data)-

sort_array(array_of_tuples, tuple_comparator( ({ comparator( (: $1 >= $2 :) ), (: strcmp($1,$2) :) }), ({1,0}) ) )

which prioritizes the sort by level and if the levels are found to be equal sorts by name.

Both functions rely on tricks from functional programming in that they both create functions on the fly based on a function or functions passed in. The code might be a bit cryptic to those not use to this style but is illustrative of this approach.

sort_array(array_of_ints, comparator( (: $1 >= $2 :) ) )

The second function is for sorting tuples when you have to sort a list of items which consist of lists of data or tuples where each element at a given index is of the same type. i.e. ({"Silenus", 1, "orc", "warrior"}), ({"Cratylus", 1, "human", "mage"}) it creates a comparison function which gives priority to the indexes as ordered. An example usage might be (using the previous data)-

sort_array(array_of_tuples, tuple_comparator( ({ comparator( (: $1 >= $2 :) ), (: strcmp($1,$2) :) }), ({1,0}) ) )

which prioritizes the sort by level and if the levels are found to be equal sorts by name.

Both functions rely on tricks from functional programming in that they both create functions on the fly based on a function or functions passed in. The code might be a bit cryptic to those not use to this style but is illustrative of this approach.

/* Converts a greator or equal binary comparator into a 3 value comparator */

public function comparator(function f)

{

return (: evaluate($(f), $1, $2) ? ( evaluate($(f), $2, $1) ? 0 : 1) : -1 :);

}

/*

Compares two tuples in the order specified by the indices. If a comparator

applied to an index early in the order results in equality, the next

comparator is used on the next index on the list.

*/

private function tuple_comparator_(function array, int array);

public function tuple_comparator(function array f, int array i)

{

if( sizeof(f) != sizeof(i) ) error("Argument arrays must be of the same size.");

return tuple_comparator_(f,i);

}

private function tuple_comparator_(function array f,int array i)

{

if( sizeof(f) == 0 ) return (: 0 :);

return (: evaluate( $(f[0]), $1[$(i[0])], $2[$(i[0])] ) != 0 ? evaluate( $(f[0]), $1[$(i[0])], $2[$(i[0])] ) : evaluate( $(tuple_comparator_(f[1..],i[1..])), $1, $2 ) :);

}

/* Converts a greator or equal binary comparator into a 3 value comparator */

public function comparator(function f)

{

return (: evaluate($(f), $1, $2) ? ( evaluate($(f), $2, $1) ? 0 : 1) : -1 :);

}

/*

Compares two tuples in the order specified by the indices. If a comparator

applied to an index early in the order results in equality, the next

comparator is used on the next index on the list.

*/

private function tuple_comparator_(function array, int array);

public function tuple_comparator(function array f, int array i)

{

if( sizeof(f) != sizeof(i) ) error("Argument arrays must be of the same size.");

return tuple_comparator_(f,i);

}

private function tuple_comparator_(function array f,int array i)

{

if( sizeof(f) == 0 ) return (: 0 :);

return (: evaluate( $(f[0]), $1[$(i[0])], $2[$(i[0])] ) != 0 ? evaluate( $(f[0]), $1[$(i[0])], $2[$(i[0])] ) : evaluate( $(tuple_comparator_(f[1..],i[1..])), $1, $2 ) :);

}