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

时间:2014-05-28 06:43:18

标签: functional-programming lisp common-lisp

我在Lisp做了一个小练习:

  

使用参数test-deltadelta编写一个函数lst   检查lst中连续元素之间的差异是否小于   delta。以两种方式编写函数:

     
      
  • 递归地
  •   
  • 使用映射函数
  •   

我以递归方式编写该函数没有问题,但我不知道应该使用哪个映射函数。所有标准映射函数一次只能使用列表中的一个元素。 reduce也不能使用,因为我没有在连续元素之间使用某些操作。我在这里使用 的功能是什么?

2 个答案:

答案 0 :(得分:3)

  

所有标准功能一次只能使用一个元素。

     

减少功能也不能使用   因为我没有在元素之间使用某些操作。

uselpa已经an answer显示您可以使用reduce执行此操作,但我感到有点尴尬地将reduce弯曲到这种情况。

在我看来,更自然地认识到标准映射函数实际上允许您使用多个列表。我首先会显示mapcarloop,然后会every,我认为这是真正的赢家。最后,为了完整起见,我还提到了maplist

mapcar

标准mapcar可以使用多个列表,这意味着您可以同时从两个不同的列表中获取元素。特别值得注意的是,它可能需要list(rest list)。例如,

(let ((list '(1 2 3 4 5 6)))
  (mapcar 'cons
          list
          (rest list)))

;=> ((1 . 2) (2 . 3) (3 . 4) (4 . 5) (5 . 6))

您可以使用loop执行相同的操作:

(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))

您可以使用loop上的其他一些变体,但其中一些变体的结果较少。例如,你可以循环(a b) on list,但是你得到一个(可能)意外的变量最终绑定:

(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将为您提供的内容。

每个

我认为这里真正的赢家将会成为every, some, notevery, and notany职能部门。与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

MAPLIST

您也可以使用maplist执行此操作,该6 NIL适用于列表的连续 tails ,这意味着您可以访问每个元素以及后面的元素。尽管如此,第二个loop解决方案最终会有(maplist (lambda (tail) (list (first tail) (second tail))) '(1 2 3 4 5 6)) ;=> ((1 2) (2 3) (3 4) (4 5) (5 6) (6 NIL)) 。 E.g:

{{1}}

答案 1 :(得分:1)

reduce 可以使用:

(defun testdelta (delta lst)
  (reduce
   (lambda (r e)
     (if (< (abs (- r e)) delta)
       e
       (return-from testdelta nil)))
   lst)
  t)

或者,没有return-from(但可能更慢):

(defun testdelta (delta lst)
  (and
   (reduce
    (lambda (r e) 
      (and r (if (< (abs (- r e)) delta) e nil)))
    lst)
   t))