[Zope] dtml-in sort by generic function

Dieter Maurer dieter@handshake.de
Wed, 14 Mar 2001 19:57:26 +0100 (CET)


Oleg Broytmann writes:
 >    Thank you for stepping in!
I like good ideas. They must be supported...

 > >   *  "dtml-in" supports multiple sort keys.
 > >      I would expect to have a comparison function for
 > >      each sort key, with the global comparison function
 > >      a composition of that for the sort keys.
 > >
 > >      Thus, you can combine a locale sensitive sort with
 > >      (e.g.) a date sort.
 > 
 >    But of course. Or simulating SQL "ORDER BY date DESC, title ASC" :)
 > 
 >    But I do not see a way to do it in generic fashion. I can write a
 > specific comparison function for every specific case, but how I can combine
 > few comparison functions into one in a generic way? Imagine a have a string
 > comparison str_cmp, and date comparison date_cmp functions. Now I need to
 > pass to dtml-in a combined function. Should it be a Python Script that just
 > calls str_cmp and date_cmp in turn, something like
I am not yet clear about a good syntax. It
should be something, that pairs the attribute with the sorting
function essential for this attribute: something like:

	 sort="attr1[cmp1],attr2,attr3[cmp3],...."

This should mean, use "cmp1" for "attr1", the default comparison
for "attr2" (i.e. cmp) and "cmp3" for "attr3" (and so on).

Each "cmp" is looked up in the namespace and if not found there,
in a standard set of comparison function, such that it is
easy to get "locale_asc", "locale_desc", "case_insensitive_asc", ....

This way, you get a tuple of comparison functions of the same
length as the tuple of values.

Now we define:
  def lexicographicCompare(values1,values2,functions):
    '''*values1*, *values2* and *functions* are all tuples of the
    same length with "functions[i]" capable of comparing
    "value1[i]" and "values2[i]".
    The result is the lexicographic comparison of the tuples.'''
    for v1,v2,cmp in map(None,value1,value2,functions):
      c= cmp(v1,v2) # maybe we should do something, if this raises an exception
      if c: return c
    return 0



Dieter