I have the strong feeling that the functionality of the following two functions should already be provided by some standard macro or function in emacs. It would be nice if someone could give me a pointer to those.
(defun classify (classifier list &rest key-values)
"Maps the LIST entries through CLASSIFIER to class denotators.
Returns the alist of equivalence classes. Each equivalence class
is a cons whose `car' is the class denotator and the cdr is the
list of members.
Keywords supported: :test"
(let ((test (or (plist-get key-values :test) 'equal)))
(let (classify-res)
(dolist (classify-li list)
(let* ((classify-key (funcall classifier classify-li))
(classify-class (cl-assoc classify-key classify-res :test test)))
(if classify-class
(setcdr classify-class (cons classify-li (cdr classify-class)))
(setq classify-res (cons (list classify-key classify-li) classify-res)))))
classify-res)))
(defun max-el (list &rest key-values)
"Return maximal element.
Keywords supported: :test"
(let ((max-el-max (car-safe list))
(max-el-test (or (plist-get key-values :test) '>)))
(setq list (cdr list))
(while list
(when (funcall max-el-test (car list) max-el-max)
(setq max-el-max (car list)))
(setq list (cdr list)))
max-el-max))
Example:
(setq classes (classify 'file-name-extension
'("first.txt" "second.txt"
"script1.el" "script2.el" "script3.el")))
gives
(("el" "script3.el" "script2.el" "script1.el") ("txt" "second.txt" "first.txt"))
and
(max-el classes :test (lambda (c1 c2) (> (length c1) (length c2))))
gives
("el" "script3.el" "script2.el" "script1.el")
Note, that I did not care very much about the efficiency of the function definitions above since I assume that there is already an efficient standard version. These definitions are just listed here to show which behavior I need.
-max-by
and-group-by
.