有人在 Emacs Lisp 中实现了自然顺序排序吗?我知道这不难写,但借用别人的作品更容易。
(是的,我无法相信我刚刚搜索了一个 Emacs 函数却找不到它。)
最佳答案
此代码提供了一个可用于排序算法的'dictionary-lessp
。到目前为止,似乎在我的测试中有效:
(defun dictionary-lessp (str1 str2)
"return t if STR1 is < STR2 when doing a dictionary compare
(splitting the string at numbers and doing numeric compare with them)"
(let ((str1-components (dict-split str1))
(str2-components (dict-split str2)))
(dict-lessp str1-components str2-components)))
(defun dict-lessp (slist1 slist2)
"compare the two lists of strings & numbers"
(cond ((null slist1)
(not (null slist2)))
((null slist2)
nil)
((and (numberp (car slist1))
(stringp (car slist2)))
t)
((and (numberp (car slist2))
(stringp (car slist1)))
nil)
((and (numberp (car slist1))
(numberp (car slist2)))
(or (< (car slist1) (car slist2))
(and (= (car slist1) (car slist2))
(dict-lessp (cdr slist1) (cdr slist2)))))
(t
(or (string-lessp (car slist1) (car slist2))
(and (string-equal (car slist1) (car slist2))
(dict-lessp (cdr slist1) (cdr slist2)))))))
(defun dict-split (str)
"split a string into a list of number and non-number components"
(save-match-data
(let ((res nil))
(while (and str (not (string-equal "" str)))
(let ((p (string-match "[0-9]*\\.?[0-9]+" str)))
(cond ((null p)
(setq res (cons str res))
(setq str nil))
((= p 0)
(setq res (cons (string-to-number (match-string 0 str)) res))
(setq str (substring str (match-end 0))))
(t
(setq res (cons (substring str 0 (match-beginning 0)) res))
(setq str (substring str (match-beginning 0)))))))
(reverse res))))
这是我的测试:
(and (dictionary-lessp "a" "b")
(null (dictionary-lessp "b" "a"))
(null (dictionary-lessp "a" "a"))
(dictionary-lessp "1" "2")
(null (dictionary-lessp "2" "1"))
(null (dictionary-lessp "1" "1"))
(dictionary-lessp "1" "a")
(null (dictionary-lessp "a" "1"))
(dictionary-lessp "" "a")
(null (dictionary-lessp "a" ""))
(dictionary-lessp "ab12" "ab34")
(dictionary-lessp "ab12" "ab123")
(dictionary-lessp "ab12" "ab12d")
(dictionary-lessp "ab132" "ab132z")
(dictionary-lessp "132zzzzz" "ab132z")
(null (dictionary-lessp "1.32" "1ab")))
示例用法是:
(sort '("b" "a" "1" "f19" "f" "f2" "f1can") 'dictionary-lessp)
产量
("1" "a" "b" "f" "f1can" "f2" "f19")
关于emacs - Emacs Lisp 的自然顺序排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1942045/