List 公共lisp:如何实现reduce

List 公共lisp:如何实现reduce,list,functional-programming,lisp,common-lisp,reduce,List,Functional Programming,Lisp,Common Lisp,Reduce,我已经找了好几天了,基本上我需要实现一个函数,它做的事情和系统函数reduce做的一样。这是我到目前为止提出的,但是没有初始值,我无法使它工作 这是我的密码 (defun my-reduce (p i lista) (if (null lista) i (funcall p (car lista) (my-reduce p i (cdr lista))))) 顺便说一句,它甚至不能正常工作,因为它是反向的 例如: 应该回来 1234 但我明白了 1234零 有什么想法

我已经找了好几天了,基本上我需要实现一个函数,它做的事情和系统函数reduce做的一样。这是我到目前为止提出的,但是没有初始值,我无法使它工作

这是我的密码

(defun my-reduce (p i lista)
  (if (null lista)
       i
    (funcall p (car lista) (my-reduce p i (cdr lista)))))
顺便说一句,它甚至不能正常工作,因为它是反向的 例如:

应该回来

1234

但我明白了

1234零


有什么想法吗?

我认为您已经实现了正确的右折叠(通常称为右折叠),但需要左折叠。注意特征尾部递归,并使用默认值作为累加器:

(defun my-left-reduce (f i xs)
  (if (null xs)
       i
    (my-left-reduce f (funcall f i (car xs)) (cdr xs))
我从未使用过CommonLisp,但概念应该很清楚


旁白:通常认为左折是向后的。比较我的reduce cons NIL'123和我的left reduce cons NIL'123。后者应该反转列表的原始cons结构。

我认为您已经实现了正确的右折叠(通常称为右折叠),但需要左折叠。注意特征尾部递归,并使用默认值作为累加器:

(defun my-left-reduce (f i xs)
  (if (null xs)
       i
    (my-left-reduce f (funcall f i (car xs)) (cdr xs))
我从未使用过CommonLisp,但概念应该很清楚


旁白:通常认为左折是向后的。比较我的reduce cons NIL'123和我的left reduce cons NIL'123。后者应反转列表的原始cons结构。

左折叠可以通过简单的迭代实现:

(defun my-fold-left (reducer initial list)
  (loop for fold = initial then (funcall reducer fold element)
        for element in list
        finally (return fold)))
例如:

(my-fold-left #'cons 0 '(1 2 3 4))
((((0 . 1) . 2) . 3) . 4)

(my-fold-left #'cons 0 '())
0
如果使用map,也可以概括和折叠向量:


以防您没有阅读,它对左折和右折有一个很好的高级解释。

左折可以通过简单的迭代实现:

(defun my-fold-left (reducer initial list)
  (loop for fold = initial then (funcall reducer fold element)
        for element in list
        finally (return fold)))
例如:

(my-fold-left #'cons 0 '(1 2 3 4))
((((0 . 1) . 2) . 3) . 4)

(my-fold-left #'cons 0 '())
0
如果使用map,也可以概括和折叠向量:


以防你没有读过,它有一个很好的左右折叠的高级解释。

非常感谢!!您知道有什么方法不在输出中显示NIL吗?@user7337963标准函数采用关键字参数:initial value如果不设置,就好像您使用列表的cdr调用它,并使用汽车作为初始值一样。当关键字argument:from end设置为true时,它会将元素向右折叠。@Sylvester谢谢,我将您告诉我的内容与phg的解决方案相结合,生成了一个包含两个参数的函数,该函数调用的是我的reduce@用户7337963,这将起作用。你也可以在里面定义助手,非常感谢!!您知道有什么方法不在输出中显示NIL吗?@user7337963标准函数采用关键字参数:initial value如果不设置,就好像您使用列表的cdr调用它,并使用汽车作为初始值一样。当关键字argument:from end设置为true时,它会将元素向右折叠。@Sylvester谢谢,我将您告诉我的内容与phg的解决方案相结合,生成了一个包含两个参数的函数,该函数调用的是我的reduce@用户7337963,这将起作用。您还可以使用Thank’s在内部定义帮助程序!不幸的是,我不允许使用setfYou,在课堂之外-哦,是的,这是肯定的:但不幸的是,对于我所有的课堂作业,我不被允许使用循环、setf或setq。。。无论如何,我会记住你的回答谢谢!不幸的是,我不允许使用setfYou,在课堂之外-哦,是的,这是肯定的:但不幸的是,对于我所有的课堂作业,我不被允许使用循环、setf或setq。。。无论如何,我会记住你的答案