映射

映射 属于 Common Lisp

12 个练习

关于 映射

映射指的是把一个函数应用到序列的每个元素上,从而得到一个新的序列。

可以用mapcar把一个函数映射到一个对象列表上:

(mapcar #'double '(1 2 3 4)) ; => (2 4 6 8)

注意,第一个实参是要调用的函数。 #'是一种特殊的引用语法,用来指定一个函数。 (这里也可以用'double,但使用#'更符合习惯,而且可以说“更正确”。)

多个列表

映射并不局限于把函数应用到一个序列上,也可以作用于多个序列。 如果提供了N个序列,那么函数必须接受N个实参。

(mapcar #'list '(1 2) '(a b) '("foo" "bar")) ; => ((1 a "foo") (2 b "bar"))

其他映射函数

除了mapcar,还有其他用于在列表上映射的函数。 mapcar无疑是最常用的,不过了解一下其他函数也很有好处。

maplist的用法与mapcar类似,但它作用的是依次递进的子列表,而不是元素。 先是整个列表,然后是它的cdr,再然后是那个cdr的cdr,依此类推:

(maplist #'identity '(a b c)) ; => ((A B C) (B C) (C))

mapc和mapl分别类似于mapcar和maplist,但它们不收集结果,而是返回第一个列表。 这类函数用于产生副作用的操作。

mapcan和mapcon类似于mapcar和maplist,但结果会借助nconc展平。nconc类似于append,但它对除最后一个实参以外的所有实参都具有破坏性。

在其他序列上映射

映射并不局限于列表。任何序列(在另一个概念中介绍)都可以被映射。 对于非列表的序列,则使用map函数。

map接受 3 个或更多实参:

  • 第一个是结果序列的类型
  • 第二个是要应用的函数
  • 第三个及之后的实参是要操作的序列。
(map 'list #'double '(1 2 3))        ; => (2 4 6)
(map 'string #'char-upcase "foobar") ; => "FOOBAR"

作为一种特殊情况,如果把nil作为结果序列的类型,那么返回的就是nil。 这种用法(和上面的mapc、mapl一样)是为了产生副作用。

通过 GitHub 编辑 该链接会在新窗口或标签页中打开

学习 映射

练习已锁定

再解锁 8 个练习即可练习 映射