映射指的是把函数应用到序列的每个元素上,从而产生一个新序列。
用 mapcar 函数可以轻松地对列表完成这件事。
假设有一个函数 double,它把实参乘以 2:
(mapcar #'double '(1 2 3 4)) ; => (2 4 6 8)
注意,第一个实参是要调用的函数。#' 是一种特殊的引用语法,用于指定函数。
double 先以第一个元素调用,然后以第二个元素调用,依此类推。
结果被收集到一个列表中,这个列表就是该表达式求值得到的值。
过滤是指从另一个序列创建新序列的过程:复制原序列中的元素,但排除其中某些元素。 至于把哪些元素纳入新序列,可以由谓词函数(求值为布尔值的函数)来决定,也可以由是否与某个特定对象相等来决定。
remove-if 接受一个谓词函数和一个序列作为实参,返回一个序列,其中只包含那些谓词求值为假值的元素。
换句话说,它会“移除”序列中所有令谓词求值为真的元素。不过要注意,这个函数不会修改原序列!
它返回的是一个去掉了相应元素的新序列。如果谓词对所有值都为真,则返回一个空序列。
(remove-if #'evenp '(1 2 3 4 5)) ; => (1 3 5)
(remove-if #'oddp '(1 3 5)) ; => ()
如果想从序列中移除某个特定的元素,可以使用 remove,它接受要移除的元素和一个序列。
序列中所有不等于该元素的值都会被返回。
注意:默认使用eql通用相等谓词来检查是否相等。
(remove 1 '(1 2 1 3 1 4)) ; => (2 3 4)
(remove #\l "hello") ; => "heo"
Lisp 外星人 Lucy 喜欢数字,认为其中一些数字“很了不起”。
Lucy 请你帮忙写一些函数,让数字变得更了不起。
Lucy 觉得一个数字怎样才算了不起,这一点是会变的,所以这些函数需要足够灵活。
要把一个数字数组变成更了不起的数字数组,你需要写一个函数make-magnificent-maybe,它接受一个要应用于这些数字的函数,以及一个数字数组。
它应该求值为一个数字数组,其中的数字更了不起(根据所提供的函数)。
(make-magnificent-maybe #'square '(1 2 3)) ; => (1 4 9)
(make-magnificent-maybe #'1+ '(1 2 3)) ; => (2 3 4)
在(希望如此)让数字变得更了不起之后,Lucy 只想看到真正了不起的数字。
Lucy 很清楚 1 永远 都算不上了不起,所以你只需要把它去掉。
但除此之外,Lucy 有时会改变主意,所以还会再给你一个函数,用来判断一个数字是否了不起。
你需要写一个函数only-the-best,它接受一个函数和一个数字数组,并且只返回最好的数字(不包括1,也不包括函数对其求值为 true 的数字)。
(only-the-best #'evenp '(1 2 3 4 5)) ; => (3 5)
(only-the-best #'oddp '(1 3 5)) ; => ()