Assgarth 发表于 2022-7-6 08:50:38

[LISP]多级排序

你好
 
我有以下功能:
(defun zk:LST_SS->List (sel / % l)
(repeat
        (setq % (sslength sel))
        (setq % (1- %)
                  l (cons (ssname sel %) l)
        )
)
)
 
(defun zk:SortLstXYEnt->Lst (lstEnt mode / lstPkt lstMode lstOut lstSgn)

(cond
        ((= mode "-Y(X)")(setq lstMode (list cadadr caadr) lstSgn (list > <)))
        ((= mode "-Y(-X)") (setq lstMode (list cadadr caadr) lstSgn (list > >)))
        ((= mode "Y(X)")   (setq lstMode (list cadadr caadr) lstSgn (list < <)))
        ((= mode "Y(-X)")(setq lstMode (list cadadr caadr) lstSgn (list < >)))
        ((= mode "X(Y)")   (setq lstMode (list caadr cadadr) lstSgn (list < <)))
        ((= mode "X(-Y)")(setq lstMode (list caadr cadadr) lstSgn (list < >)))
        ((= mode "-X(Y)")(setq lstMode (list caadr cadadr) lstSgn (list > <)))
        ((= mode "-X(-Y)") (setq lstMode (list caadr cadadr) lstSgn (list > >)))
)

(foreach ent lstEnt (setq lstPkt (cons (cons ent (list (cdr(assoc 10 (entget ent))))) lstPkt)))                       
(setq lstPkt (zk:SortFunction lstPkt > lstMode))

)
 

;;---------------------------------=={ zk:SortFunction }==---------------------------------;;
;; multi-level sorting                                                         ;;
;;-----------------------------------------------------------------------------------------;;
;; Lst - list np. ((<entity name> '(10 20 0)) (<entity name> '(20 30 0)))...       ;;
;; Sgn [+/-]- sort direction indicator                                             ;;
;; Col - list of columns, after which they followed another sort                ;;
;;-----------------------------------------------------------------------------------------;;
;; ex. Col: (list caadr cadadr)                                                            ;;
;;-----------------------------------------------------------------------------------------;;
(defun zk:SortFunction (Lst Sgn Col)
(member Sgn (list < >))
(mapcar
        '(lambda (%)
                (setq Lst
                        (vl-sort Lst
                                (function
                                        (lambda (e1 e2)
                                                (Sgn
                                                        ((eval %) e1)
                                                        ((eval %) e2)
                                                )
                                        )
                                )
                        )
                )
        )
        Col
)
Lst
)
 
运行:

(setq ssGroup (ssget (list (cons 0 "TEXT"))))
(zk:LST_SS->List ssGroup)
 
现在我想更改“zk:SortFunction”,以便根据列表ex进行排序:
(setq lstSgn(列表>>))
附件中是所有组合。现在我只有第八名的4名;签署“>”或“
 
有人能帮我吗?
打招呼
分类图纸

irneb 发表于 2022-7-6 09:14:21

你的代码中有一些奇怪的地方,例如,你的排序函数只返回列表中的最后一项——或者至少我是这么理解的。
 
无论如何,你所附的图纸与示例文本有轻微的偏差。E、 g.第一组(-Y+X)“1”的Y插入值为3368.7494,但“同一”线上的“3”的Y为3368.7503。因此,“3”将排序在“1”之前,因为它“更高”-甚至仅按0.0009排序。
 
因此,我建议添加一个模糊因素:
注意,此功能可能会变得更简单和/或更有效。但它显示了总体思路。下面是我用来测试它的代码:
(defun c:TestXYSort (/ ss order fuzz lst)
(if (and (setq ss (ssget (list (cons 0 "TEXT"))))
          (progn
            (initget "XY X-Y -XY -X-Y YX Y-X -YX -Y-X")
            (setq order (getkword "Select order : "))
          )
          (or (setq fuzz (getreal "Fuzz factor <1.0>: "))
            (setq fuzz 1.)
          )
   )
   (progn
   (setq lst (zk:LST_SS->List ss))
   (setq lst (sort-XY lst (read order) fuzz))
   (prin1 (mapcar '(lambda (item) (cdr (assoc 1 (entget item)))) lst))
   )
)
(princ)
)

Assgarth 发表于 2022-7-6 09:31:33

嗨,irneb,
 
谢谢你的帮助和一个例子
我检查了一下,发现了两个错误(查看dwg.file-红色“NO OKEY”)。
 
打招呼
图纸4.dwg

irneb 发表于 2022-7-6 09:56:24

好的,再试一次。我使用了一个更字面的比较,而不是依赖or。使comp的参数更符合顺序-更具可读性。并改为使用car和cdr而不是nth。通过将entget移到排序比较之外,并使用索引排序列表从原始列表中检索,也提高了效率。还将所有内部defuns合并为一个:
我还注意到,您最初的排序中有一些项目。x/y关闭超过1.0的dwg。因此,我更新了测试函数,改为使用10.0的模糊距离。还添加了一个测试,以查看根据文本值排序是否正确。
7
页: [1]
查看完整版本: [LISP]多级排序