Functional programming 使用标准映射函数处理列表中的连续元素对?

Functional programming 使用标准映射函数处理列表中的连续元素对?,functional-programming,lisp,common-lisp,Functional Programming,Lisp,Common Lisp,我有一个Lisp小练习: 使用参数delta和lst编写一个函数testdelta,该函数将 检查lst中连续元素之间的差值是否小于 delta。以两种方式编写函数: 递归地 使用映射函数 我可以递归地编写该函数,但我不知道应该使用哪个映射函数。所有标准映射函数一次只处理列表中的一个元素reduce也不能使用,因为在连续元素之间没有要使用的操作。我可以在这里使用什么功能?reduce可以使用: reduce可用于: 所有标准函数一次只能使用一个元素 Reduce函数也不能使用 因为我没有在t

我有一个Lisp小练习:

使用参数
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))
。我补充说。