Functional programming 使用标准映射函数处理列表中的连续元素对?
我有一个Lisp小练习: 使用参数Functional programming 使用标准映射函数处理列表中的连续元素对?,functional-programming,lisp,common-lisp,Functional Programming,Lisp,Common Lisp,我有一个Lisp小练习: 使用参数delta和lst编写一个函数testdelta,该函数将 检查lst中连续元素之间的差值是否小于 delta。以两种方式编写函数: 递归地 使用映射函数 我可以递归地编写该函数,但我不知道应该使用哪个映射函数。所有标准映射函数一次只处理列表中的一个元素reduce也不能使用,因为在连续元素之间没有要使用的操作。我可以在这里使用什么功能?reduce可以使用: reduce可用于: 所有标准函数一次只能使用一个元素 Reduce函数也不能使用 因为我没有在t
delta
和lst
编写一个函数testdelta
,该函数将
检查lst
中连续元素之间的差值是否小于
delta
。以两种方式编写函数:
- 递归地
- 使用映射函数
reduce
也不能使用,因为在连续元素之间没有要使用的操作。我可以在这里使用什么功能?reduce
可以使用:
reduce
可用于:
所有标准函数一次只能使用一个元素
Reduce函数也不能使用
因为我没有在to元素之间使用的一些操作
uselpa已经显示了你可以用reduce
来实现这一点,但是我觉得把reduce
放在这种情况下有点尴尬
在我看来,认识到标准映射函数实际上允许您处理多个列表更为自然。我将首先显示mapcar
和loop
,然后显示every
,我认为这才是真正的赢家。最后,为了完整起见,我还包括了maplist
地图车
标准的mapcar
可以获取多个列表,这意味着您可以同时从两个不同的列表中获取元素。需要特别注意的是,它可能需要一个列表
和(rest列表)
。例如:
(let ((list '(1 2 3 4 5 6)))
(mapcar 'cons
list
(rest list)))
;=> ((1 . 2) (2 . 3) (3 . 4) (4 . 5) (5 . 6))
环
您可以使用循环
执行相同的操作:
(loop
with l = '(1 2 3 4 5 6)
for a in l
for b in (rest l)
collect (cons a b))
;=> ((1 . 2) (2 . 3) (3 . 4) (4 . 5) (5 . 6))
您可以使用循环
上的其他一些变体,但其中一些变体的结果不太常见。例如,您可以循环列表上的(a b)
,但随后您会得到(可能)意外的变量最终绑定:
(loop for (a b) on '(1 2 3 4 5 6)
collect (list a b))
;=> ((1 2) (2 3) (3 4) (4 5) (5 6) (6 NIL))
这与maplist
将提供的内容类似
每一个
不过,我认为这里真正的赢家将是功能。这些,如mapcar
可以将多个列表作为参数。这意味着您的问题可能只是:
(let ((delta 4)
(lst '(1 2 4 7 9)))
(every (lambda (x y)
(< (abs (- x y)) delta))
lst
(rest lst)))
;=> T
(let ((delta 2)
(lst '(1 2 4 7 9)))
(every (lambda (x y)
(< (abs (- x y)) delta))
lst
(rest lst)))
;=> NIL
所有标准函数一次只能使用一个元素
Reduce函数也不能使用
因为我没有在to元素之间使用的一些操作
uselpa已经显示了你可以用reduce
来实现这一点,但是我觉得把reduce
放在这种情况下有点尴尬
在我看来,认识到标准映射函数实际上允许您处理多个列表更为自然。我将首先显示mapcar
和loop
,然后显示every
,我认为这才是真正的赢家。最后,为了完整起见,我还包括了maplist
地图车
标准的mapcar
可以获取多个列表,这意味着您可以同时从两个不同的列表中获取元素。需要特别注意的是,它可能需要一个列表
和(rest列表)
。例如:
(let ((list '(1 2 3 4 5 6)))
(mapcar 'cons
list
(rest list)))
;=> ((1 . 2) (2 . 3) (3 . 4) (4 . 5) (5 . 6))
环
您可以使用循环
执行相同的操作:
(loop
with l = '(1 2 3 4 5 6)
for a in l
for b in (rest l)
collect (cons a b))
;=> ((1 . 2) (2 . 3) (3 . 4) (4 . 5) (5 . 6))
您可以使用循环
上的其他一些变体,但其中一些变体的结果不太常见。例如,您可以循环列表上的(a b)
,但随后您会得到(可能)意外的变量最终绑定:
(loop for (a b) on '(1 2 3 4 5 6)
collect (list a b))
;=> ((1 2) (2 3) (3 4) (4 5) (5 6) (6 NIL))
这与maplist
将提供的内容类似
每一个
不过,我认为这里真正的赢家将是功能。这些,如mapcar
可以将多个列表作为参数。这意味着您的问题可能只是:
(let ((delta 4)
(lst '(1 2 4 7 9)))
(every (lambda (x y)
(< (abs (- x y)) delta))
lst
(rest lst)))
;=> T
(let ((delta 2)
(lst '(1 2 4 7 9)))
(every (lambda (x y)
(< (abs (- x y)) delta))
lst
(rest lst)))
;=> NIL
嗯,很好。谢谢,我不想用return from嗯,很好。谢谢,我不想使用return from,您可以在这里使用reduce,但是使用
(mapcar fn lst(rest lst))
可能更容易,因为mapcar
可以处理多个列表。这为您提供了一种对每个元素及其后续元素使用二进制谓词的简单方法。更好的是,由于它包含了您所需的大部分逻辑,因此可以使用each
函数,该函数还可以包含多个列表。然后您只需要(每个差值小于delta lst(rest lst))
。我已经添加了。您可以在这里使用reduce,但是使用(mapcar fn lst(rest lst))
可能更容易,因为mapcar
可以处理多个列表。这为您提供了一种对每个元素及其后续元素使用二进制谓词的简单方法。更好的是,由于它包含了您所需的大部分逻辑,因此可以使用each
函数,该函数还可以包含多个列表。然后您只需要(每个差值小于delta lst(rest lst))
。我补充说。