Sordid Details, of a sort

May 25, 2006 | In RTML |

The following post from Sheridan Rawlins, Yahoo! Small Business engineer, outlines two often misunderstood RTML operators, SORT, and INDEXED-SORT. The post is intended for Yahoo! Store Developers or merchants with an advanced understanding of RTML. Learn more about RTML.

Some time ago we released the SORT operator in response to the difficulty and tedium of writing a sorting template directly in the RTML language. I would like to shed some light on how it works, describe the differences in the two flavors of sort (SORT & INDEXED-SORT), and describe more advanced sorting, such as sorting on a secondary property when the first property is equivalent.

Both the SORT and INDEXED-SORT operators expect 2 variable names (var1 & var2), a sequence, and a body. The elements of sequence are examined 2 elements at a time by setting the two variables and evaluating the body to determine whether var1 is less than the var2. A copy of the sequence in sorted order is returned.

The body allows full customization of the sort order subject to some conventions which should be followed: return-style consistency, and comparison consistency.

Return-style consistency

We support two styles of body’s return value – one of the following styles should be chosen and stay consistent for a given instance of SORT or INDEXED-SORT:

  1. strcmp-like: a number, which is
    1. -1 if var1 < var2
    2. 0 if var1 = var2
    3. +1 if var1 > var2
  2. Binary Predicate: a symbol which is
    1. T if A < B
    2. NIL if A >= B

Comparison Consistency

The comparison must obey the following “StrictWeakOrdering” properties:

  • Irreflexive: when (var1=A, var2=A), body must return 0 or NIL
  • Antisemetric: when (var1=A, var2=B) returns -1 or T, then (var1=B, var2=A) must return +1 or NIL
  • Transitive: when (var1=A, var2=B) returns -1 or T, and (var1=B, var2=C) returns -1 or T, then (var1=A, var2=C) must return -1 or T as well.

When to use SORT vs. INDEXED-SORT

SORT is useful when sequence directly describes the elements to be sorted.

INDEXED-SORT is useful when “expensive” lookups must be performed against each element in sequence to determine the index to sort on. The best example of this is when you have a sequence of ids (i.e. @contents) and you wish to sort on the @name property of each element.

INDEXED-SORT’s extra parameter: getindex

INDEXED-SORT first iterates across sequence setting var1 for each element and evaluating getindex. Then, it evaluates body much like sort but sets var1, and var2 to these indices. A copy of the sorted sequence is returned (indices are discarded).

I hope this helps describe the basic principles of the sort and comparison operators. I’ll provide examples and other sorting tidbits in a companion post.

Sheridan Rawlins
Yahoo! Small Business

Edit 01/11/07

In order to reverse the sort order you need to tweak the body of the INDEXED-SORT.

The current implementation of sort-item-by-price has something like the following:

sort-items-by-price (items nilgreater)

INDEXED-SORT var1 var1
             var2 var2
             getindex WITH-OBJECT var1
                        ELEMENT position 0
                                sequence @price
             sequence items
  CALL :<=>-nil.
    var1
    var2
    nilgreater

To reverse the sort you would would switch the arguments and the boolean in the call to <=>-nil. — Something like:

sort-items-by-price (items nilgreater)

INDEXED-SORT var1 var1
             var2 var2
             getindex WITH-OBJECT var1
                        ELEMENT position 0
                                sequence @price
             sequence items
  CALL :<=>-nil.
    var2
    var1
    NOT nilgreater

I hope this helps!–SCR


5 Comments »

RSS feed for comments on this post.

  1. Wow! Thanks for the great info.

    Comment by Jed — May 27, 2006 #

  2. Thanks for the information.

    How can the sort-item-by-price template be tweaked to sort price from highest-to-lowest (it defaults as lowest to highest)?

    Thanks for the help.

    Comment by Mattison — January 10, 2007 #

  3. In order to reverse the sort order you need to tweak the body of the INDEXED-SORT to switch the arguments and the boolean in the call to -nil. I have added example code above.

    Comment by Sheridan Rawlins — January 11, 2007 #

  4. Thanks for the information.

    I also found — looking through the various RTML tags — that if you put the REVERSE tag on the INDEXED-SORT, you get the reverse sort order.

    One other question:
    When I use the sort-item-by-price template, can I ask the INDEXED-SORT to exclude all ids without prices?

    Right now, if I reverse the sort by price, so highest to lowest, it lists all ids without price first.

    Of course, if sort by price, lowest to highest, all ids without price appear at the end of the list.

    One final off-topic question:
    Is there any easy RTML way to paginate section pages, say 12 or 15 items per page?

    Thanks again for the help.

    Comment by Mattison — January 15, 2007 #

  5. Mattison, I doubt you are still checking this thread, but just in case anyone else reads this post and has a similar question…

    I would suggest using the FIND-ALL operator to sort only the ids that have a price. I don’t know the back end programming for RTML, but FIND-ALL should be a O(n) operation at the most. Thus cutting out undesirable ids from your sequence first should have the additional benefit of shaving a bit of overhead off the sort as well.

    Also, using the REVERSE operator will certainly work, but why run an additional operation on the list? Sheridan’s solution is more proper.

    Comment by Jacob Swartwood — August 25, 2007 #

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

Disclaimer and Reminder. The opinions expressed here are not necessarily the opinions of Yahoo! and we assume no responsibility for such content. Yahoo! may, in our sole discretion, remove comments that are off topic, inappropriate or otherwise violate our Terms of Service. Please do not post any private information unless you want it to be available publicly and never assume that you are completely anonymous and cannot be identified by your comments.

Copyright © 2006 Yahoo! Inc. All rights reserved. Privacy Policy - Terms of Service

Powered by WordPress on Yahoo! Web Hosting.
Copyright © 2006 Yahoo! Inc. All rights reserved. Privacy Policy - Terms of Service