From 2946344a231a915d5143017b70e91a9a7a9b11aa Mon Sep 17 00:00:00 2001 From: Nicolas Petton Date: Tue, 29 Mar 2016 09:19:32 +0200 Subject: [PATCH] New function seq-sort-by in seq.el * lisp/emacs-lisp/seq.el (seq-sort-by): New function. * test/lisp/emacs-lisp/seq-tests.el: New test for seq-sort-by. * doc/lispref/sequences.texi: Add documentation for seq-sort-by. --- doc/lispref/sequences.texi | 12 ++++++++++++ lisp/emacs-lisp/seq.el | 12 +++++++++++- test/lisp/emacs-lisp/seq-tests.el | 5 +++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index f7d26e54d0..08e5e3ae35 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -763,6 +763,18 @@ according to @var{function}, a function of two arguments that returns non-@code{nil} if the first argument should sort before the second. @end defun +@defun seq-sort-by function predicate sequence + This function is similar to @code{seq-sort}, but the elements of +@var{sequence} are transformed by applying @var{function} on them +before being sorted. @var{function} is a function of one argument. + +@example +(seq-sort-by #'seq-length #'> ["a" "ab" "abc"]) +@result{} ["abc" "ab" "a"] +@end example +@end defun + + @defun seq-contains sequence elt &optional function This function returns the first element in @var{sequence} that is equal to @var{elt}. If the optional argument @var{function} is non-@code{nil}, diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 8b7b594f5e..89fad43742 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -4,7 +4,7 @@ ;; Author: Nicolas Petton ;; Keywords: sequences -;; Version: 2.3 +;; Version: 2.14 ;; Package: seq ;; Maintainer: emacs-devel@gnu.org @@ -218,6 +218,16 @@ The result is a sequence of the same type as SEQUENCE." (cl-defmethod seq-sort (pred (list list)) (sort (seq-copy list) pred)) +(defun seq-sort-by (function pred sequence) + "Sort SEQUENCE using PRED as a comparison function. +Elements of SEQUENCE are transformed by FUNCTION before being +sorted. FUNCTION must be a function of one argument." + (seq-sort (lambda (a b) + (funcall pred + (funcall function a) + (funcall function b))) + sequence)) + (cl-defgeneric seq-reverse (sequence) "Return a sequence with elements of SEQUENCE in reverse order." (let ((result '())) diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index c9219b51d0..50543de8ad 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el @@ -347,5 +347,10 @@ Evaluate BODY for each created sequence. (should (= (seq-position seq 'a #'eq) 0)) (should (null (seq-position seq (make-symbol "a") #'eq))))) +(ert-deftest test-seq-sort-by () + (let ((seq ["x" "xx" "xxx"])) + (should (equal (seq-sort-by #'seq-length #'> seq) + ["xxx" "xx" "x"])))) + (provide 'seq-tests) ;;; seq-tests.el ends here -- 2.39.2