Jef! 发表于 2022-7-5 23:22:39

试图将函数lambda化

标题说明了一切。有两个函数(由Peter Jamtgaard创建),它们完全满足我的需要。
函数fix1永远不会在fixblks之外使用,我试图将其放入lambda中,但没有成功。我读了很多关于lambda的书,即使我认为我理解lambda函数,理解教程/帮助文件中给出的常见简单示例,但收到的错误消息善意地提醒我,我没有理解。(哈哈哈)
 
 
我知道有时lambda可以单独使用,有时与apply或mapcar函数配合使用。。。但我甚至不确定应该使用哪一个,因为我必须给它提供一个参数(fix1指的是它自己)。下一步是以编程方式而不是通过entsel来填充块Ename,但在我的第一次尝试中,我遇到了类似“错误:没有函数定义:BNAM”的错误。
 
 
我不会发布我失败的尝试,但这里有两个工作功能。
 
 
(defun C:FIXBLKS (/ ELST ENAM ESEL BNAM FLST)
(vl-load-com)
(setq ESEL (entsel "\nSelect block: ")
ENAM (car ESEL)
ELST (entget ENAM)
BNAM (cdr (assoc 2 ELST))
FLST nil
)
(fix1 BNAM)
(vl-cmdf "regen")
(prin1)
)

 
 
(defun FIX1 (BNAM / BENAM)
(if (not (member BNAM FLST))
(progn
(setq FLST(cons BNAM FLST)
BENAM (tblobjname "block" BNAM)
)
(while (setq BENAM (entnext BENAM))
(print (entget BENAM))
(if (= (cdr (assoc 0 (entget BENAM))) "INSERT")
(fix1 (cdr (assoc 2 (entget BENAM))))
(vla-put-color (vlax-ename->vla-object BENAM) 256)
)
)
)
)
)
 
 
有人能帮我把fix1换成lambda吗?通过这个具体的例子,我认为我对lambda的理解将大大提高。
谢谢大家,干杯,
杰夫!

cwake 发表于 2022-7-5 23:42:28

回答你的问题,杰夫!
 
(defun C:FixBlks ( / elst enam esel bnam flst )
(vl-load-com)
(setq esel (entsel "\nSelect block: ")
       enam (car esel)
       elst (entget enam)
       bnam (cdr (assoc 2 elst))
       flst nil
       )
((lambda ( func )
    (func bnam)
    )
   (lambda ( bnam / benam )
   (if (not (member bnam flst))
       (progn
         (setq flst(cons bnam flst)
               benam (tblobjname "block" bnam)
               )
         (while (setq benam (entnext benam))
         (print (entget benam))
         (if (= (cdr (assoc 0 (entget benam))) "INSERT")
             (func (cdr (assoc 2 (entget benam))))
             (vla-put-color (vlax-ename->vla-object benam) 256)
             )
         )
         )
       )
   )
   )
(vl-cmdf "regen")
(prin1)
)

我还在试着决定我自己是否会这样使用它。。。如果FIXBLKS是从主例程调用的子函数,我当然会这么做。。。我还没有决定何时从命令行调用FIXBLKS。
不管怎样,希望能有所帮助。

Jef! 发表于 2022-7-5 23:43:59

嗨,克林特!
 
 
我不能说我永远不会将其用作命令,但我的计划是将其用作子功能并针对特定的块,而不是使用entsel。由于我已经完成了块的所有实体,我完成了许多步骤,现在我已经添加了一些行来更改属性文本样式,以符合我们的标准,如果我在块内发现任何其他需要修改的内容,我将添加更多。
 
 
希望对你有帮助?一如既往,您的意见确实非常有帮助,我们对此表示感谢。
 
 
我昨晚花了一部分时间思考这个问题,我的结论是,由于fix1引用了自身,所以不可能将其转换为lambda函数。
我必须说你完全是玻璃纤维的。。寓言凝视。。flabler。。用2个嵌入式Lambda征服了我(哈哈)。有一件事我想不通。
如果你有一个函数xyz
(defun functionXYZ(args/var1 var2)
...)
您必须为其参数提供个值。。。(函数XYZ值)。lambda类似于函数。如果lambda与apply或mapcar函数配对,则它们位于其前面的lambda之外,参数位于其后面的lambda之外。我明白了。。。但我完全不确定传递给“独立”lambda的参数来自哪里。根据我的理解(可能我错了),在你之前的帖子中,第二个lambda是第一个lambda的参数(func)?
如果是这样的话,我想不出会传递什么作为第二个lambda的参数(bnam),因为lambda右括号后没有任何内容。
另一件我不太明白的事情是,为什么在第一个括号之前有第二个开括号,并将两个lambda括起来。
 
 
我向自己保证,只要我不完全理解lisp的工作原理,就永远不会使用任何给定的lisp部分/函数。。。但是这一个,即使我完全理解(非常好的)Peter Jamtgaard函数是如何工作的,并且看到工作的lambda版本,我也不知道它是如何工作的。从我的角度来看,lady Lambda仍然很神秘,我自己永远也无法将其解释清楚。克林特,让我告诉你:你很好!=)

cwake 发表于 2022-7-5 23:54:20

嗨,杰夫!
哈哈哈。我承认这是我第一次看到它做得一样好时的反应。所以我像大家一样把它藏在工具箱里。
谢谢你的感谢之词。
 
我将尝试解释它是如何工作的——看看它是否有帮助。为了澄清“独立”lambda函数会发生什么情况,请将其视为普通函数。使用cons作为正常函数示例。。。我们知道它有两个论点。所以它的语法是

(                      ;open parenthesis
cons                  ;the name of the function to invoke - defined elsewhere
"item1"            ;argument 1
"item2"            ;argument 2
)                  ;close parenthesis

对于“独立”lambda,情况相同。

(                      ;open parenthesis
(lambda ( a b )
(cons (substr a 3) (substr b 3))
)                   ;the lambda function - defined in place
"item1"            ;argument 1
"item2"            ;argument 2
)                  ;close parenthesis

可能需要注意的是,lambda函数有自己的括号(就像defun一样)。在这些括号内发生的一切都是“函数”。然后还有另一组括号(与任何其他函数一样),将函数的参数与函数本身分组。也许这可以回答你的问题,为什么有两个括号?
 
记住这一点,第二个lambda作为变量传递给第一个lambda是正确的。因此在第一个lambda中,它变成了一个变量名为“func”的函数。当处理第一个lambda函数时,它调用(func-bnam)-事实上,它只做这些。这与原始函数调用(fix1 bnam)相同。这是如何调用第二个lambda并将参数“bnam”传递给它的。然后,由于第二个lambda函数作为第一个lambda函数内的函数运行,因此函数“func”仍然可以在第二个lambda内递归调用。
当“func”的递归完成时,由于没有更多的命令要处理,我们退出第一个lambda。一旦发生这种情况,函数“func”就不再可用。
希望这有帮助。

pBe 发表于 2022-7-6 00:09:49

 
这让我崩溃了

Jef! 发表于 2022-7-6 00:19:18

哦,我的上帝!我就像一个刚刚有了第一眼视力的盲人!非常感谢你的慷慨解释,我完全理解。连接现在建立起来了,拼图的每一部分都到位了。这套套路值得称道(就其所做的和教育而言)。我甚至可以说这是一部杰作。
 
 
 
 
当func从1rst lambda启动时,它开始遍历块的实体,在找到的第一个插入类型实体(嵌套块)时,它跳转1级到递归。由于Benam是局部的,递归扫描嵌套块的实体,更改任何非插入实体的颜色,如果发现任何插入类型,则跳入更深的递归。如果没有找到,当递归完成时,它会跳回以恢复之前的递归。此时,如果同一嵌套块有其他实例,则会跳过这些实例(因为bnam将是flst列表的成员)。如果找到任何其他插入,它会跳入递归,当func的第一个实例完成时(完成“entnex ing”原始选定块的所有实体),我们会退出第一个lambda。
简单但又很聪明。令人惊叹的
 
 
你的解释价格更低!一再感谢。
 
 
@pBe,我希望你会喜欢我的“entnex ing”

cwake 发表于 2022-7-6 00:26:44

很高兴我能帮助杰夫!
页: [1]
查看完整版本: 试图将函数lambda化