明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 7965|回复: 24

apply和mapcar的用法

  [复制链接]
发表于 2012-10-25 21:51:03 | 显示全部楼层 |阅读模式
下面是apply和mapcar的一段代码,我想求教各位能人,这里面的apply和mapcar各是怎么执行的呢? 希望懂得人指导下,谢谢。

;-------------------------------------------------
;从点列表(point list)得到坐标范围(coordinate extents).
;例如:
(defun GetExtents (plist /)
  (list
    (apply 'mapcar (cons 'min plist))
    (apply 'mapcar (cons 'max plist))
  )
)
(GetExtents '((1 0 0) (2 2 0) (1 2 0) (3 4 0)))
发表于 2014-4-1 11:58:19 | 显示全部楼层
重慶崽兒 发表于 2014-1-25 22:22
(apply ’function list)
参数

第一个问题
mapcar 的参数是( 函数 一系列表)
(min (l1)(l2)(l3)(l4))就是这样的形式

第二个问题
mapcar最让初学者迷惑的地方是因为范例容易让人误解
$ (mapcar '(lambda (x)  (+ x 3) )  '(10 20 30) ) =>(13 23 33)
如果再加一个范例
$ (mapcar '(lambda (x)  (+ x y) )  '(10 20 30) '(1 2  3))=> (11 22 33)
就也许更清楚了
因为mapcar是把所有表的相同位置的元素取出来作为参数交给函数运算然后返回每次结果构成的新表
上例就是(list (+ 10 3)(+ 20 3)(+ 30 3))
而AUDESK的范例容易让人误会仅仅是把表中的每个元素做为参数,交给函数运算然后返回结果构成的表

所以这个(mapcar 'min '(1 0 0) '(2 2 1) '(1 2 1) '(3 4 0))
就是(list (min 1 2 1 3)  (min 0 2 2 4) (min 0 1 1 0))=>(1 0 0)

评分

参与人数 2明经币 +1 金钱 +20 收起 理由
zhaochang71 + 1
bzhjl + 20 赞一个!

查看全部评分

回复 支持 2 反对 0

使用道具 举报

发表于 3 天前 | 显示全部楼层
CLOCK 发表于 2015-5-2 15:05
有木有把lambda apply mapcar 各种用法的帖子啊,记得以前哪看到过的(估计有2年左右了),由浅入深的都有 ...

(mapcar '+  '(10 20 30) '(1 2 3))和(apply'mapcar(cons'+'((10 20 30)(1 2 3))))是一样的
但实际使用起来,适用情况是完全不同的,假如程序运行过程中,得到了有限的几个坐标点,比如正方形或矩形的4个角点坐标,分别用p1,p2,p3,p4存储,现在计算这4个点的坐标和,显然用第一个就行了,但是,如果这4个点在一个坐标点表里边,甚至个数不确定呢?比如pts((0 0 0)(0 5 0)(5 5 0)(5 0 0)),这时apply'mapcar就很必要了,由于pts是一个表,各项分别为一个坐标点,那么+这个操作符需要通过cons给搞到前边,再对它使用apply'mapcar...感觉这样还是不好理解apply'mapcar,得先理解apply,比如(max 1 2 3)和(apply'max '(1 2 3))这里应该有启发了,不过还是需要多想多测试
至于lambda,可以理解为临时定义一个无名函数,因为别的地方不需要它,所以它不需要有名字,什么地方定义它什么地方才能用它,用完就完。经常看到它出现在mapcar,vl-sort等函数内,因为mapcar,vl-sort等函数要进行的处理通常较为复杂,至少无法直接调用系统函数,所以在里边定义一个临时函数显然比较合理,和普通函数一样,它可以有参数,也可以定义局部变量,实际上它可以出现在任何地方而不是某个函数内部,当它单独出现的时候,外边一般需要加一层括号来调用它,否则只定义了它,但又没函数名,其它地方无法调用它,最终定义一个寂寞?
(mapcar '(lambda (x)  (+ x 3) )  '(10 20 30) ) =>(13 23 33)里边的(lambda (x)  (+ x 3) )就是一个临时函数,它只能通过mapCar反复调用它
((lambda(/ a)    这里可以写需要的一切))就是可以在任何地方出现并且能自动运行,这样它除了能定义局部变量外,实际上和(progn ...)差不多
回复 支持 1 反对 0

使用道具 举报

发表于 2012-10-25 23:27:30 | 显示全部楼层
这是那位牛人写的代码哎,又学一招。
发表于 2012-10-25 23:47:46 | 显示全部楼层
太妙了。。。
发表于 2012-10-26 08:10:11 | 显示全部楼层
本帖最后由 Gu_xl 于 2012-10-26 13:43 编辑

(apply 'mapcar (cons 'min '((1 0 0) (2 2 0) (1 2 0) (3 4 0))))
==>
(mapcar 'min '(1 0 0) '(2 2 0) '(1 2 0) '(3 4 0))
==>
(list (min 1 2 1 3) (min 0 2 2 4) (min 0 0 0 0))

点评

G版回复的第一行有误,少了'min,多了个闭括号,应为:(apply 'mapcar (cons 'min '((1 0 0) (2 2 0) (1 2 0) (3 4 0))))  发表于 2012-10-26 09:31
发表于 2012-10-26 08:28:55 | 显示全部楼层
确实牛哎,顶!!
发表于 2012-10-26 08:52:14 | 显示全部楼层
以 plist 内有四个点为例
(apply 'mapcar (cons 'min plist))
展开 ==>
(mapcar 'min (car plist) (cadr plist) (caddr plist) (cadddr plist))

更多点时...
(mapcar 'min (car plist) (cadr plist) (caddr plist) (cadddr plist) ....)

但用 (apply 'mapcar ....) 就免去了展开 plist
 楼主| 发表于 2012-10-26 17:13:08 | 显示全部楼层
明经热心的人挺多的,谢谢Gu_xl 和Andyhon的解释。
发表于 2012-10-26 19:59:15 | 显示全部楼层
谢谢Gu_xl 和Andyhon的解释
发表于 2014-1-22 15:28:08 | 显示全部楼层
高手!谢谢Gu_xl 和Andyhon的解析~!
发表于 2014-1-25 22:22:19 | 显示全部楼层
Andyhon 发表于 2012-10-26 08:52
以 plist 内有四个点为例
(apply 'mapcar (cons 'min plist))
展开 ==>

(apply ’function list)
参数

’function
函数,可以是表示 defun 或 lambda 表达式的符号。
list
表。如果函数不接收参数,则该参数为 nil。


其中,mapcar就是其中的函数,而(cons 'min plist)就是其中的list,想问下大大,为什么mapcar的函数会是“min”呢,还有就是mapcar中的list参数又是什么呢?还请大大解答!谢谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-12-27 10:23 , Processed in 0.194986 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表