繁花落叶 发表于 2012-10-25 21:51:03

apply和mapcar的用法

下面是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)))

longcashman 发表于 2014-4-1 11:58:19

重慶崽兒 发表于 2014-1-25 22:22 static/image/common/back.gif
(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 23))=> (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)

llsheng_73 发表于 4 天前

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 ...)差不多

yarp 发表于 2012-10-25 23:27:30

这是那位牛人写的代码哎,又学一招。

feng582304 发表于 2012-10-25 23:47:46

太妙了。。。

Gu_xl 发表于 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))

zyhandw 发表于 2012-10-26 08:28:55

确实牛哎,顶!!

Andyhon 发表于 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的解释。

cable2004 发表于 2012-10-26 19:59:15

谢谢Gu_xl 和Andyhon的解释

bzhjl 发表于 2014-1-22 15:28:08

高手!谢谢Gu_xl 和Andyhon的解析~!

重慶崽兒 发表于 2014-1-25 22:22:19

Andyhon 发表于 2012-10-26 08:52 static/image/common/back.gif
以 plist 内有四个点为例
(apply 'mapcar (cons 'min plist))
展开 ==>


(apply ’function list)
参数

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

其中,mapcar就是其中的函数,而(cons 'min plist)就是其中的list,想问下大大,为什么mapcar的函数会是“min”呢,还有就是mapcar中的list参数又是什么呢?还请大大解答!谢谢!
页: [1] 2 3
查看完整版本: apply和mapcar的用法