轨道
/
Common Lisp
Common Lisp
/
练习
/
Lucy 的神奇映射器
Lucy 的神奇映射器

Lucy 的神奇映射器

学习练习

简介

映射

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

用 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 觉得一个数字怎样才算了不起,这一点是会变的,所以这些函数需要足够灵活。

1. 让数字变得了不起

要把一个数字数组变成更了不起的数字数组,你需要写一个函数make-magnificent-maybe,它接受一个要应用于这些数字的函数,以及一个数字数组。 它应该求值为一个数字数组,其中的数字更了不起(根据所提供的函数)。

(make-magnificent-maybe #'square '(1 2 3)) ; => (1 4 9)
(make-magnificent-maybe #'1+ '(1 2 3))     ; => (2 3 4)

2. 只保留最好的

在(希望如此)让数字变得更了不起之后,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))    ; => ()
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Common Lisp Exercism

准备好开始 Lucy 的神奇映射器 了吗?

注册 Exercism,借助 27 个概念92 个练习 和真人导师指导,学习并掌握 Common Lisp,全部免费。