本帖最后由 st788796 于 2013-10-11 23:39 编辑
首先阐述一下这种算法:
当应用中需要对某些实体进行分组统计时, 动态变量构造是一种高效和简化代码的选择, 当然还有其它算法另述。
该算法的一般写法是构造一个表用于动态构造反映实体特征的字串格式索引,然后用 set read 对这个字串所代
表的变量构造一个相同实体表,以达到分组目的,实现思路如下
循环
取实体特征
将这个特征构造一个字串(一般可以加一个前缀,因为Lisp对变量名称有限制,比如 read 后为数字就不能做变量名)
在变量收集表中搜索是否已有
有,对这个字串代表的变量求值,将该实体加入这个表
否,将这个字串加入收集表同时把实体加入该字串代表的变量表
直至循环结束完成实体分组
以钢筋为例
首先分析该钢筋分类是以编号为主,相同的钢筋是一个编号,那就构造一个表 ("XD1" "XD2" "XD3" ....)
其中 XD 作为前缀Read后能够形成变量 XD1 XD2 XD3 ... 每个变量代表该编号的所有实体,这样就可以达到统计目的
以下代码说明以XDAPI为例,纯Lisp的可以参照这个自己实现,论坛有很多实例
 - (if (setq ss (ssget '((2 . "ATTUS"))));_首先要过滤选择出需要的块
- (progn
- (xdrx_setsstodb ss 0);_将选择集放入 0 数据库
- (while (setq e (xdrx_getentdata 0));_取出实体,指针自动递增,比 repeat 更方便
- (setq atts (xdrx_getpropertyvalue e "AttributeEntities");_一次把取出所有的属性实体
- (mapcar '(lambda (x)
- (if (= (xdrx_getpropertyvalue x "Tag") "C");_只取编号的 TagString
- (if (member (strcat "XD" (xdrx_getpropertyvalue x "Textstring")) nl);_取出标号值,Nl就是收集的一个总表
- (set (read (strcat "XD" (xdrx_getpropertyvalue x "Textstring"));_read 出该变量
- (cons e (read (strcat "XD" (xdrx_getpropertyvalue x "Textstring")));_对该变量
- )
- (progn
- (setq nl (cons (strcat "XD" (xdrx_getpropertyvalue x "Textstring") nl));_把该类加入 nl 变量 "XD1" ...
- (set (read (strcat "XD" (xdrx_getpropertyvalue x "Textstring")) (list x));_还要给变量 XD1 赋值
- )
- )
- );_if 只判断编号,其它属性不处理
- )
- atts
- );_mapcar 对 e 实体完成分组
- );_结束 while 后就完成了对选择集的分组
- ;;完成选择集处理后就形成了 nl 变量,这个变量内是 ("XD1" "XD2" "XD3 ...)对应各个钢筋编号组
- ;;同时 XD1 XD2 XD3 ... 变量也是一个个表,包括了选择的对应该编号的所有实体,后面只要用 Mapcar 或 foreach 对 nl 处理
- )
- )
- (mapcar '(lambda (x) (set (read x) nil)) nl);_这一句必须 把对应的 XD1 XD2 XD3 .... 等变量置空,不留垃圾变量
关于钢筋统计详细程序参见http://bbs.xdcad.net/forum.php?mod=redirect&goto=findpost&ptid=670988&pid=3490834
对这个算法应用以后会再找论坛其它实例进行讲解, 请继续关注本帖.
|