Common lisp 公共口齿不清:what';在列表中循环遍历连续对的最佳方式是什么?
有时,我需要在列表中的连续对之间循环。我现在的做法是Common lisp 公共口齿不清:what';在列表中循环遍历连续对的最佳方式是什么?,common-lisp,Common Lisp,有时,我需要在列表中的连续对之间循环。我现在的做法是 (loop for x on lst while (not (null (cdr x))) (do something on (car x) and (cadr x))) 我想知道是否有更好的/内置的方法来做到这一点 我之所以需要它,是因为有时我需要,例如,一些添加连续对的函数 (1 2 3 4 5) ----> (3 5 7 9) 有没有像reduce这样的内置函数可以让我实现这个功能?好吧,没有一个内置函数可以实现
(loop for x on lst while (not (null (cdr x)))
(do something on (car x) and (cadr x)))
我想知道是否有更好的/内置的方法来做到这一点
我之所以需要它,是因为有时我需要,例如,一些添加连续对的函数
(1 2 3 4 5) ----> (3 5 7 9)
有没有像reduce这样的内置函数可以让我实现这个功能?好吧,没有一个内置函数可以实现你想要的功能。你可以试着用
maplist
组合一些东西,但我的第一反应是也要使用loop
不过,只需写几条注释就可以了。首先,(not(null foo))
相当于CL中的foo
,因为非NIL
值通过布尔运算被视为t
。其次,loop
可以解构它的参数,这意味着您可以像
(loop for (a b) on lst while b
collect (+ a b))
maplist
版本看起来像
(maplist
(lambda (rest)
(when (cdr rest)
(+ (first rest) (second rest)))
lst)
我认为不那么可读(这也会返回NIL作为结果的最后一个元素,而不是仅仅在它结束之前)。
< P>我相信保罗·格雷厄姆在OnLisp有一个名为Multuple元组的函数。它可以按cdr、cddr或您喜欢的方式在列表中下移。这里是它的一个评论版本。它使用他的回指if宏aif(defun map-tuple (someList f &optional (by #'cdr))
"(map-tuple someList f &optional (by #'cdr))
f is a function that takes two args, returns one val (maybe)
the map-tuple will collect all non-nil results in a list.
example:
(map-tuple '(1 2 3 4 5 6) (lambda (a b) (format T \"a: ~A b:~A~%\" a b)) #'cdr)
a: 1 b:2
a: 2 b:3
a: 3 b:4
a: 4 b:5
a: 5 b:6
a: 6 b:NIL
(map-tuple '(1 2 3 4 5 6) (lambda (a b) (format T \"a: ~A b:~A~%\" a b)) #'cddr)
a: 1 b:2
a: 3 b:4
a: 5 b:6
"
(cond ((null someList)
nil)
(T
(aif (funcall f (car someList) (cadr someList))
(cons it (map-tuple (funcall by someList) f by))
(map-tuple (funcall by someList) f by)))))
为什么我要在这件事上投反对票?这是一个错误的问题吗?不是我的否决票,但可能是因为你的伪代码没有运行,但看起来很像真实的CL,有人被愚弄了?谢谢,我喜欢你建议的优雅方式。还有,是否可以优雅地枚举所有对或无序对?现在我正在做
?(setf s’(12345))?(成员x s)collect(列表x y)中的x循环(成员x s)collect(列表x y)中的y循环)(11)(12)(13)(14)(15)(22)(23)(24)(25)(33)(34)(35)(35)(4)(4)(4)(5))
这种操作通常会更优雅地处理。在这种特定情况下,我将定义类似于(defun pair with(elem list)(mapcar(lambda(a)(list elem a))list))
,然后调用(mapcon(lambda(rest)(pair with(car rest))s)
。获取所有对看起来非常相似。因此在(ab)@claytontstanley中有一个隐式的“&rest some arg not used”-我认为它比这更复杂,因为您可以在…上执行(a.rest)循环或(a b)循环((12)(3 4)…
。但就本例而言,是的,这基本上是正确的。依赖于将尾部递归优化为循环是一个坏主意。标准明确规定,不保证这样做,事实上,除非启用优化,否则SBCL甚至不会这样做。循环解决方案要好得多。