[<< wikibooks] Algorithm Implementation/Sorting/Schwartzian transform
== Perl ==
Perl's compact list-manipulation functions can perform the entire transform in a single statement, although it must be written backwards:

This is a complete Schwartzian Transform, showing a multi-stage sort based on memoized keys of size and modtime.


== Python ==
Python programmers use the transform in sorts where the comparison operation may be expensive.
In this example, f(x) returns a key which is suitable for using for sorting. For instance, it might return the length of x, or it might do a database lookup based on the value of x.

The key function can return a tuple of values if secondary and further sort keys are desired, taking advantage of the fact that tuples are ordered first by the first key, and then by the second key if the first ties, etc. If the default sort for the keys is not enough, a comparator function can be given with an additional keyword argument cmp, for example:

Note that the key function f should do the expensive work as it's called only once for each key whereas the comparator function is called each time the sort algorithm has to compare two elements. A comparator function can no longer be used in Python 3.0; only a key. The function sorted is new in Python 2.4, before that only method sort was available and more than one statement was required. The key function is also new in Python 2.4 so in Python 2.3 one had to spell out the transform in a way similar to the following, taking advantage of the fact that the first element of a tuple will be used for comparison first:

If desired, a comparator function can be given to the sort here as well (Python 2.4; removed in Python 3.0).
The following is a version that is similar to the Perl idiom (except for the extra parentheses at the end), again taking advantage of sorting of tuples by putting the function results first:

The zip built-in can be used instead of the inline lambda function giving:


== Ruby ==
Ruby programmers have their own shortcut.

However, this is not the full Schwartzian Transform, because the comparison of the memoized keys is fixed.  (Though there is a trick for getting around that.)


=== Full Schwartzian Transform ===
A true Schwartzian Transform also spells out how the various memoized keys are compared (as strings, as numbers) including lazy logic that can avoid comparisons in secondary and tertiary keys if distinction in the primary keys suffice.

Note that since collect, sort, etc. are all method calls, that the actions read forwards, rather than backwards as in the original Perl.
And now for the trick to make the shortcut method do everything that the full transform can.  The trick is that in Ruby objects know how to sort themselves, and arrays sort lexicographically (i.e. by comparing the first value, then second value, etc.).  This means that you can construct values that will sort themselves by fairly complex logic.


== Haskell ==
This is the idiomatic Haskell way of comparing by a transformed version of the elements:

Here the "comparing" function takes a function and returns a comparison function based on comparing the results of the function application. It is defined like this:

Here is a version that identically mimicks the traditional Perl idiom:

However, we can take advantage of the fact that tuples are first ordered by their first element, then second, etc., by putting the function results as the first element, and then using the default comparator:

Since the tuple compare requires both element types to be instances of Ord, however, this last implementation has a subtly different type:


== OCaml ==
This is probably the easiest way to do it in OCaml:

Here is a version that identically mimicks the traditional Perl idiom (except for the extra parentheses):

However, we can take advantage of the fact that tuples are first ordered by their first element, then second, etc., by putting the function results as the first element, and then using the default comparator:


== Javascript ==
In modern versions of Javascript (Firefox 1.5, Internet Explorer 9, Opera 9.6, Chrome, Safari 3, etc.; standardized in ECMAScript edition 5), arrays have a map function in their prototype, allowing one to easily write a Schwartzian transform:

Example usage:

For older browsers, a compatibility map prototype function can be used.