* doc/lispref/lists.texi (Functions that Rearrange Lists): Remove
description of sort ... * doc/lispref/sequences.texi (Sequence Functions): ... and generalize it for sequences. Add an example. * src/fns.c (Fsort): Use more natural Qsequencep error. * test/automated/fns-tests.el (fns-tests-sort): Minor style rewrite.
This commit is contained in:
parent
f0e709846e
commit
dd958fb246
5 changed files with 102 additions and 71 deletions
|
@ -1,3 +1,10 @@
|
|||
2014-08-29 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
||||
* lists.texi (Functions that Rearrange Lists): Remove
|
||||
description of sort ...
|
||||
* sequences.texi (Sequence Functions): ... and generalize
|
||||
it for sequences. Add an example.
|
||||
|
||||
2014-08-28 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* display.texi (Bidirectional Display): Update the Emacs's class
|
||||
|
|
|
@ -1124,74 +1124,6 @@ each time you run it! Here is what happens:
|
|||
@end smallexample
|
||||
@end defun
|
||||
|
||||
@defun sort list predicate
|
||||
@cindex stable sort
|
||||
@cindex sorting lists
|
||||
This function sorts @var{list} stably, though destructively, and
|
||||
returns the sorted list. It compares elements using @var{predicate}. A
|
||||
stable sort is one in which elements with equal sort keys maintain their
|
||||
relative order before and after the sort. Stability is important when
|
||||
successive sorts are used to order elements according to different
|
||||
criteria.
|
||||
|
||||
The argument @var{predicate} must be a function that accepts two
|
||||
arguments. It is called with two elements of @var{list}. To get an
|
||||
increasing order sort, the @var{predicate} should return non-@code{nil} if the
|
||||
first element is ``less than'' the second, or @code{nil} if not.
|
||||
|
||||
The comparison function @var{predicate} must give reliable results for
|
||||
any given pair of arguments, at least within a single call to
|
||||
@code{sort}. It must be @dfn{antisymmetric}; that is, if @var{a} is
|
||||
less than @var{b}, @var{b} must not be less than @var{a}. It must be
|
||||
@dfn{transitive}---that is, if @var{a} is less than @var{b}, and @var{b}
|
||||
is less than @var{c}, then @var{a} must be less than @var{c}. If you
|
||||
use a comparison function which does not meet these requirements, the
|
||||
result of @code{sort} is unpredictable.
|
||||
|
||||
The destructive aspect of @code{sort} is that it rearranges the cons
|
||||
cells forming @var{list} by changing @sc{cdr}s. A nondestructive sort
|
||||
function would create new cons cells to store the elements in their
|
||||
sorted order. If you wish to make a sorted copy without destroying the
|
||||
original, copy it first with @code{copy-sequence} and then sort.
|
||||
|
||||
Sorting does not change the @sc{car}s of the cons cells in @var{list};
|
||||
the cons cell that originally contained the element @code{a} in
|
||||
@var{list} still has @code{a} in its @sc{car} after sorting, but it now
|
||||
appears in a different position in the list due to the change of
|
||||
@sc{cdr}s. For example:
|
||||
|
||||
@example
|
||||
@group
|
||||
(setq nums '(1 3 2 6 5 4 0))
|
||||
@result{} (1 3 2 6 5 4 0)
|
||||
@end group
|
||||
@group
|
||||
(sort nums '<)
|
||||
@result{} (0 1 2 3 4 5 6)
|
||||
@end group
|
||||
@group
|
||||
nums
|
||||
@result{} (1 2 3 4 5 6)
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
@strong{Warning}: Note that the list in @code{nums} no longer contains
|
||||
0; this is the same cons cell that it was before, but it is no longer
|
||||
the first one in the list. Don't assume a variable that formerly held
|
||||
the argument now holds the entire sorted list! Instead, save the result
|
||||
of @code{sort} and use that. Most often we store the result back into
|
||||
the variable that held the original list:
|
||||
|
||||
@example
|
||||
(setq nums (sort nums '<))
|
||||
@end example
|
||||
|
||||
@xref{Sorting}, for more functions that perform sorting.
|
||||
See @code{documentation} in @ref{Accessing Documentation}, for a
|
||||
useful example of @code{sort}.
|
||||
@end defun
|
||||
|
||||
@node Sets And Lists
|
||||
@section Using Lists as Sets
|
||||
@cindex lists as sets
|
||||
|
|
|
@ -327,6 +327,98 @@ encouraged to treat strings as immutable.
|
|||
|
||||
@end defun
|
||||
|
||||
@defun sort sequence predicate
|
||||
@cindex stable sort
|
||||
@cindex sorting lists
|
||||
@cindex sorting vectors
|
||||
This function sorts @var{sequence} stably. Note that this function doesn't work
|
||||
for all sequences; it may be used only for lists and vectors. If @var{sequence}
|
||||
is a list, it is modified destructively. This functions returns the sorted
|
||||
@var{sequence} and compares elements using @var{predicate}. A stable sort is
|
||||
one in which elements with equal sort keys maintain their relative order before
|
||||
and after the sort. Stability is important when successive sorts are used to
|
||||
order elements according to different criteria.
|
||||
|
||||
The argument @var{predicate} must be a function that accepts two
|
||||
arguments. It is called with two elements of @var{sequence}. To get an
|
||||
increasing order sort, the @var{predicate} should return non-@code{nil} if the
|
||||
first element is ``less than'' the second, or @code{nil} if not.
|
||||
|
||||
The comparison function @var{predicate} must give reliable results for
|
||||
any given pair of arguments, at least within a single call to
|
||||
@code{sort}. It must be @dfn{antisymmetric}; that is, if @var{a} is
|
||||
less than @var{b}, @var{b} must not be less than @var{a}. It must be
|
||||
@dfn{transitive}---that is, if @var{a} is less than @var{b}, and @var{b}
|
||||
is less than @var{c}, then @var{a} must be less than @var{c}. If you
|
||||
use a comparison function which does not meet these requirements, the
|
||||
result of @code{sort} is unpredictable.
|
||||
|
||||
The destructive aspect of @code{sort} for lists is that it rearranges the
|
||||
cons cells forming @var{sequence} by changing @sc{cdr}s. A nondestructive
|
||||
sort function would create new cons cells to store the elements in their
|
||||
sorted order. If you wish to make a sorted copy without destroying the
|
||||
original, copy it first with @code{copy-sequence} and then sort.
|
||||
|
||||
Sorting does not change the @sc{car}s of the cons cells in @var{sequence};
|
||||
the cons cell that originally contained the element @code{a} in
|
||||
@var{sequence} still has @code{a} in its @sc{car} after sorting, but it now
|
||||
appears in a different position in the list due to the change of
|
||||
@sc{cdr}s. For example:
|
||||
|
||||
@example
|
||||
@group
|
||||
(setq nums '(1 3 2 6 5 4 0))
|
||||
@result{} (1 3 2 6 5 4 0)
|
||||
@end group
|
||||
@group
|
||||
(sort nums '<)
|
||||
@result{} (0 1 2 3 4 5 6)
|
||||
@end group
|
||||
@group
|
||||
nums
|
||||
@result{} (1 2 3 4 5 6)
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
@strong{Warning}: Note that the list in @code{nums} no longer contains
|
||||
0; this is the same cons cell that it was before, but it is no longer
|
||||
the first one in the list. Don't assume a variable that formerly held
|
||||
the argument now holds the entire sorted list! Instead, save the result
|
||||
of @code{sort} and use that. Most often we store the result back into
|
||||
the variable that held the original list:
|
||||
|
||||
@example
|
||||
(setq nums (sort nums '<))
|
||||
@end example
|
||||
|
||||
For the better understanding of what stable sort is, consider the following
|
||||
vector example. After sorting, all items whose @code{car} is 8 are grouped
|
||||
at the beginning of @code{vector}, but their relative order is preserved.
|
||||
All items whose @code{car} is 9 are grouped at the end of @code{vector},
|
||||
but their relative order is also preserved:
|
||||
|
||||
@example
|
||||
@group
|
||||
(setq
|
||||
vector
|
||||
(vector '(8 . "xxx") '(9 . "aaa") '(8 . "bbb") '(9 . "zzz")
|
||||
'(9 . "ppp") '(8 . "ttt") '(8 . "eee") '(9 . "fff")))
|
||||
@result{} [(8 . "xxx") (9 . "aaa") (8 . "bbb") (9 . "zzz")
|
||||
(9 . "ppp") (8 . "ttt") (8 . "eee") (9 . "fff")]
|
||||
@end group
|
||||
@group
|
||||
(sort vector (lambda (x y) (< (car x) (car y))))
|
||||
@result{} [(8 . "xxx") (8 . "bbb") (8 . "ttt") (8 . "eee")
|
||||
(9 . "aaa") (9 . "zzz") (9 . "ppp") (9 . "fff")]
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@xref{Sorting}, for more functions that perform sorting.
|
||||
See @code{documentation} in @ref{Accessing Documentation}, for a
|
||||
useful example of @code{sort}.
|
||||
@end defun
|
||||
|
||||
@node Arrays
|
||||
@section Arrays
|
||||
@cindex array
|
||||
|
|
|
@ -1958,7 +1958,7 @@ if the first element should sort before the second. */)
|
|||
else if (VECTORP (seq))
|
||||
seq = sort_vector (seq, predicate);
|
||||
else if (!NILP (seq))
|
||||
wrong_type_argument (Qarrayp, seq);
|
||||
wrong_type_argument (Qsequencep, seq);
|
||||
return seq;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,8 +113,8 @@
|
|||
(should (equal
|
||||
(sort
|
||||
(vector
|
||||
(cons 8 "xxx") (cons 9 "aaa") (cons 8 "bbb") (cons 9 "zzz")
|
||||
(cons 9 "ppp") (cons 8 "ttt") (cons 8 "eee") (cons 9 "fff"))
|
||||
'(8 . "xxx") '(9 . "aaa") '(8 . "bbb") '(9 . "zzz")
|
||||
'(9 . "ppp") '(8 . "ttt") '(8 . "eee") '(9 . "fff"))
|
||||
(lambda (x y) (< (car x) (car y))))
|
||||
[(8 . "xxx") (8 . "bbb") (8 . "ttt") (8 . "eee")
|
||||
(9 . "aaa") (9 . "zzz") (9 . "ppp") (9 . "fff")])))
|
||||
|
|
Loading…
Add table
Reference in a new issue