本帖最后由 llsheng_73 于 2022-9-19 17:55 编辑
对一维表排序简单,(vl-sort l '<)
对二维表复杂点,通常写法(vl-sort l'(lambda(x y)(if(=(car x)(car y))(<(cadr x)(cadr y)(<(car x)(car y)))
那么对于三维甚至多维呢?难道象二维表那样一直套下去?
当然不是不行,但存在的问题很明显,一是不能通用,二是代码很长,多维应该能把自己先搞晕。
如果反过来,对排序参数x,y先去除相同的,再对它们进行排序是不是就可以通用了呢?
有想法就上码,经测试想法是正确的
- (defun sortn(l fun)
- (vl-sort l'(lambda(x y)(while(and(=(car x)(car y))(cdr x)(cdr y))(setq x(cdr x)y(cdr y)))(fun(car x)(car y)))))
这样虽然解决了二维到多维的问题,但明显不支持一维表排序了
- (defun sortn(l fun)
- (or(listp(car l))(setq l(mapcar'list l)))
- (vl-sort l'(lambda(x y)(while(and(=(car x)(car y))(cdr x)(cdr y))(setq x(cdr x)y(cdr y)))(fun(car x)(car y)))))
但缺点同样明显,所有维数的排序依据都是相同的,如果要按指定维数指定依据的话,首先应该按维数给定排序依据,即 fun应该为funs
- (defun sortn(l funs)
- (or(listp(car l))(setq l(mapcar'list l)))
- (or(listp funs)(setq funs(list funs)))
- (while(<(length funs)(length(car l)))
- (setq funs(cons(car funs)funs)))
- (vl-sort l'(lambda(x y / n)(setq n 0)
- (while(and(=(car x)(car y))(cdr x)(cdr y))(setq x(cdr x)y(cdr y)n(1+ n)))((nth n funs)(car x)(car y)))))
对于菜卷鱼提出的很关键的一个问题,先排序第几维,另外根据masterlong的思路,增加容差,并修改为只排序指定维数
再增加一个自定义序列支持,让就它彻底成为EXCEL的排序吧,感觉白折腾了
- (defun sortn(l keys funs fuzz / n mposition);;;keys关键字列号要么为nil要么为表,funs各个关键字的排序方式,通常为<或>,也可以为自定义序列,比如'("张三""李四")
- (defun mposition(e l / i)(if(setq i(vl-position e l))i(length l)))
- (or(listp(car l))(setq l(mapcar'list l)))
- (or(listp funs)(setq funs(list funs)))
- (if(zerop(setq n(length keys)))(setq n(length(car l))))
- (while(<(length funs)n)(setq funs(cons(car funs)funs)))
- (mapcar(function(lambda(x)(nth x l)))
- (vl-sort-i(if keys(mapcar(function(lambda(x)(mapcar'(lambda(y)(nth y x))keys)))l)l)
- (function(lambda(x y / n )(setq n 0)
- (while(and(equal(car x)(car y)fuzz)(cdr x)(cdr y))(setq x(cdr x)y(cdr y)n(1+ n)))
- (if(listp(setq n(nth n funs)))
- (<(mposition(car x)n)(mposition(car y)n))
- (n(car x)(car y))))))))
对于需要排序的表比较大的情况,是否可以考虑直接调用EXCEL来排序?
(SORTN '((2 2 3 4)(1 1 1 7)(2 2 1 5)(1 1 0 4))'(1 3)(list > <)0)
((2 2 3 4) (2 2 1 5) (1 1 0 4) (1 1 1 7))
(SORTN'(("上海""崇明区")("北京""朝阳区")("上海""静安区")("北京""房山区")("重庆""酉阳")("四川""成都"))nil'(("北京""上海")("静安区""朝阳区""房山区""崇明区""成都""酉阳"))0)
(("北京" "朝阳区") ("北京" "房山区") ("上海" "静安区") ("上海" "崇明区") ("四川" "成都") ("重庆" "酉阳"))
|