至于Mapcar和Lambda,我最近写了一篇关于它们的教程,但这篇文章尚未在常见问题解答中发布,这里是一个复制/粘贴版本:
什么是Mapcar&如何使用Lambda函数?
主要作者:李·麦克唐纳
上次更新日期:2009年6月13日[初稿]
根据我的经验,mapcar和lambda函数是AutoLISP编程语言中理解最少的两个函数,但是,如果正确理解和使用,它们可以替换多余的代码,并且是处理列表的强大函数。
Mapcar函数
简而言之,mapcar将对列表(或多个列表)的每个成员应用一个函数,并返回应用该函数的结果列表。
Mapcar使用以下格式调用:
其中是要应用的函数,并且。。。列表的数量等于函数所需的参数数量。因此,如果提供了采用单个参数的函数(例如strcase),则只需要一个列表。
为了用一个例子来澄清这个解释,假设我们有一个字符串列表:
假设我们需要将这些字符串中的每一个转换为大写字母(大写)。我们可以通过多种方式完成此任务,例如,使用foreach函数在列表中乱序,并创建一个新的字符串列表:
上述将变量nlist设置为:
然而,使用mapcar功能,可以用更少的编码来完成相同的任务:
上述内容将返回:
请注意,mapcar提供了函数strcase,它使用了撇号,这样就不会计算strcase,而是将其视为参数。此外,我们知道strcase函数接受一个参数,即字符串,因此我们只需要提供一个列表——我们的字符串列表。
如图所示,返回的是一个大写字符串列表,就好像我们在列表的每个成员上都使用了strcase函数一样。
具有多个参数的函数
在上面的示例中,演示了strcase函数,并且只需要一个列表,因为strcase只需要一个参数,但是如果我们想要使用一个需要多个参数的函数呢?
假设我们有一个数字列表:
让我们假设要将上述列表中的每个数字添加到列表中的每个数字:
同样,我们可以使用foreach函数来实现这一点,但使用mapcar所需的代码要少得多:
在这里,我们为mapcar提供了“+”函数,该函数接受任意数量的数值参数并将它们相加。在上述示例中,mapcar将对每个列表的每个成员应用“+”函数,并返回结果列表:
与之前一样,撇号用于将函数“+”声明为参数,以防止对其求值并导致错误。这也可以通过使用报价功能来实现:
Lambda函数
回到原始字符串列表:
假设我们要转换每个字符串,使第一个字母大写,因此:
我们可以再次使用使用foreach的方法,并洗牌我们的列表:
但是我们也可以使用mapcar来节省一些代码。然而,LISP中没有允许我们大写单词首字母的函数,那么我们如何为mapcar提供一个要应用的函数呢?
我们可以自己定义一个函数并提供它:
在这里,我们定义了一个新函数(cap),它接受一个参数(str),并对该参数执行操作,在这种情况下,将第一个字母转换为大写字母。
但这意味着我们的代码中有一个额外的函数定义,它只能使用一次。完成此任务的更好方法是使用lambda函数。
lambda函数定义了一个匿名函数,并在定义新函数的开销不合理时使用,就像我们的例子一样。
因此,我们的代码可以修改为包含lambda函数:
上面,我们使用了lambda表达式来代替我们定义的函数(cap)。它接受一个参数(str)并在该字符串上执行操作,就像我们定义的函数一样-唯一的例外是,在mapcar函数完成其操作后,不再定义lambda函数,从而为问题提供了更整洁的解决方案。 |