I agree with John. Superb explanation. Thanks again Tony. It does
appear that vl-sort has a fatal flaw. Thanks for the detailed analysis.
I tested it also on strings and found the same behavior.
Thanks also for the answer to the mult-key sort question. I appreciate
the time you took.
Regards,
Doug
"John Uhden" wrote in message news:98FB03E84D8B377BD760F78667F26A48@in.WebX.maYIadrTaRb...
> Tony:
>
> You've outdone even yourself this time. Nice get! Thanks for taking the time
> to explain.
>
> --
> John Uhden, Cadlantic/formerly CADvantage
> http://www.cadlantic.com
> Sea Girt, NJ
>
>
> "Tony Tanzillo" wrote in message
> news:26B310A0EDBB66E0BEBF8704A6406508@in.WebX.maYIadrTaRb...
> > "Doug Broad" wrote in message
> > news:505BC882E60EB2F966998DB3BF3A4FE8@in.WebX.maYIadrTaRb...
> > > Tony,
> >
> > > My comments regarding deletion of elements were concerning ACAD's version
> > > of vl-sort, not on your compare-elements subroutine, which seems to always
> > > delete duplicates.
> >
> > It's not my code that's deleting the elements, it's
> > AutoCAD's (VL-SORT) function (which is called by the
> > one of the two versions of (complex-sort)).
> >
> > Here is a verbatim transcript straight from the command line:
> >
> > Command: (setq alist '((1 2 3) (4 5 6) (7 8 9)))
> > ((1 2 3) (4 5 6) (7 8 9))
> >
> > Command: (repeat 3 (setq alist (append alist alist)))
> > ((1 2 3) (4 5 6) (7 8 9) (1 2 3) (4 5 6) (7 8 9) (1 2 3) (4 5 6) (7 8 9) (1
> > 2
> > 3) (4 5 6) (7 8 9) (1 2 3) (4 5 6) (7 8 9) (1 2 3) (4 5 6) (7 8 9) (1 2 3)
> > (4 5
> > 6) (7 8 9) (1 2 3) (4 5 6) (7 8 9))
> >
> > Command: (vl-sort alist '(lambda (x y) (> (car x) (car y))))
> > ((7 8 9) (4 5 6) (1 2 3))
> >
> > The reason why this is happening is because of how
> > the list is constructed (using append), and in fact,
> > the list 'alist' in the above, only contains three
> > unique elements. The remaining elements are merely
> > copies of one of those three unique elements, as can
> > be seen here:
> >
> > Command: (setq foo '(1 2 3))
> > (1 2 3)
> >
> > Command: (setq list1 (list foo foo))
> > ((1 2 3) (1 2 3))
> >
> > Command: (setq list2 (list foo '(1 2 3)))
> > ((1 2 3) (1 2 3))
> >
> > Command: (equal list1 list2)
> > T
> >
> > So list1 and list2 are the same, right?
> > Well, no not really:
> >
> > Command: (eq (car list1) (cadr list1))
> > T
> >
> > Command: (eq (car list2) (cadr list2))
> > nil
> >
> > Notice that even though list1 and list2 *appear* to
> > be identical (and equal says they are), in fact they
> > are very different. As the (eq) function discloses,
> > list1 contains two *copies* of the same list (the same
> > list that is assigned to 'foo'), while list2 contains
> > two completely different lists. In fact, list1 consumes
> > only half the memory consumed by list2.
> >
> > This is why (vl-sort) can sometimes remove lists, namely
> > in cases where they are actually the same list (and I
> > believe this is a bug).
> >
> > And because it is entirely unpredicable as to whether a
> > given list may contain multiple copies of the same element,
> > you should *never* use (vl-sort) for complex list sorting.
> >
> >
> > > My question regarding indexing was not how it could be done on a single
> > > sort but how it could accomplish a mult-level sort.
> >
> > If a 'multi-level sort' means to sort on multiple keys,
> > doing that does not require multiple sorts.
> >
> > > Lets say that the list is to be first sorted by one key
> > > and then by another key and then by a third key.
> >
> > Yes, that's exactly what (complex-sort) does. It sorts on
> > multiple keys, but it doesn't have to sort the list more
> > than once to do that.
> >
> > A multi-key sort or index can be performed by a single sort
> > or indexing operation. the trick is in how the comparison is
> > done. The comparison function (compare-elements) takes two
> > lists that it must compare. To do that, it first looks at the
> > first (or 'primary') sort key's value for each list, and if
> > they're equal then it looks at the next sort key's values and
> > if they're equal then it looks at the next sort key's values,
> > ad infinitum.
> >
> > If any sort key's values are not equal then there is no
> > need to compare any further sort key values for the same
> > two elements because the relative order of the two elements
> > being compared has been determined.
> >
> > Given (compare-elements), this is all you need to index a
> > list on multiple keys:
> >
> > (defun complex-index (lst sortspec)
> > (vl-sort-i lst
> > '(lambda (a b)
> > (compare-elements a b sortspec)
> > )
> > )
> > )
> >
> >
> >
> >
> >
> >
>