Common Lisp - 将函数应用于列表中的每个其他元素

lan*_*our 3 lisp loops common-lisp

我想将函数(*x 2)应用于列表中的每个其他元素,并使用循环宏返回整个列表.我到目前为止提出的解决方案是这样的:

(defun double-every-other (xs)
  (loop for x in xs by #'cddr collect (* x 2)))
Run Code Online (Sandbox Code Playgroud)

但是,这会使每个其他元素加倍,只返回加倍的元素,所以如果我执行:

(double-every-other '(1 2 3 4))
Run Code Online (Sandbox Code Playgroud)

结果将是:

'(4 8)
Run Code Online (Sandbox Code Playgroud)

但我希望结果如下:

'(1 4 3 8)
Run Code Online (Sandbox Code Playgroud)

有没有办法可以使用(循环)?

cor*_*ump 7

另一个数学较少的版本:

(defun double-every-other (list)
  (loop
     for (a b) on list by #'cddr
     collect a
     when b collect (* b 2)))

(double-every-other '(1 2 3 4))
=> (1 4 3 8)

(double-every-other '(1 2 3 4 5))
=> (1 4 3 8 5)
Run Code Online (Sandbox Code Playgroud)

显然,你将无法像其他答案那样轻松地抽象N(如果你正在考虑"宏",现在就停止).这里我们使用on关键字进行迭代,这意味着依次访问每个子列表.自从我们使用以来by #'cddr,每个其他子列表都被跳过.解构语法(a b)绑定访问列表的第一个和第二个元素.


Ren*_*nzo 5

例如,您可以在扫描列表时测试整数增加:

(defun double-every-other (xs)
  (loop for x in xs
     for i from 1
     if (oddp i)
     collect x
     else collect (* x 2)))
Run Code Online (Sandbox Code Playgroud)


Rai*_*wig 5

(defun double-every-other (xs)
  (loop for x in xs
        for doublep = nil then (not doublep)
        collect (if doublep (* x 2) x)))
Run Code Online (Sandbox Code Playgroud)