遍历列表并附加到新列表
Looping through a list and appending to a new one
我是 Lisp 新手。我正在尝试编写一个函数,该函数将采用虚线列表的列表(代表特定价值的硬币数量),例如
((1 . 50) (2 . 20) (3 . 10)) ;; one 50 cent coin, two 20 cent coins, three 10 cent coins
然后将其转换为按价值列出每个硬币,例如
(50 20 20 10 10 10)
应该不会太难吧?这是我到目前为止所拥有的。不过目前 returns NIL。有解决这个问题的想法吗?
(defun fold-out (coins)
(let ((coins-list (list)))
(dolist (x coins)
(let ((quantity (car x)) (amount (cdr x)))
(loop for y from 0 to quantity
do (cons amount coins-list))))
coins-list))
既然你可以使用loop
,那就简单地做
(defun fold-out (coins)
(loop
for (quantity . amount) in coins
nconc (make-list quantity :initial-element amount)))
或者,使用 dolist
:
(defun fold-out (coins)
(let ((rcoins (reverse coins)) (res nil))
(dolist (c rcoins)
(let ((quantity (car c)) (amount (cdr c)))
(dotimes (j quantity) (push amount res))))
res))
表达式 (cons amount coins-list)
return 是一个新列表,但它不会修改 coins-list
;这就是为什么最终结果是 NIL。
因此您可以将其更改为 (setf coins-list (cons amount coins-list))
,这将显式修改 coins-list
,这将起作用。
然而,在 Lisp 的做事方式(函数式编程)中,我们尽量不修改那样的东西。相反,我们使每个表达式 return 成为一个基于输入值的值(一个新对象),然后将该新对象传递给另一个函数。通常,对象被传递给的函数与执行传递的函数是同一个函数;这就是递归。
如果我要这样做,我可能会使用嵌套循环:
(defun fold-out (coins)
(loop for (count . value) in coins
append (loop repeat count
collect value)))
节省了相当多的打字、手动积累到事物中,并且总体上相对可读。可以做更多的文档字符串,也许还有一些单元测试。
我是 Lisp 新手。我正在尝试编写一个函数,该函数将采用虚线列表的列表(代表特定价值的硬币数量),例如
((1 . 50) (2 . 20) (3 . 10)) ;; one 50 cent coin, two 20 cent coins, three 10 cent coins
然后将其转换为按价值列出每个硬币,例如
(50 20 20 10 10 10)
应该不会太难吧?这是我到目前为止所拥有的。不过目前 returns NIL。有解决这个问题的想法吗?
(defun fold-out (coins)
(let ((coins-list (list)))
(dolist (x coins)
(let ((quantity (car x)) (amount (cdr x)))
(loop for y from 0 to quantity
do (cons amount coins-list))))
coins-list))
既然你可以使用loop
,那就简单地做
(defun fold-out (coins)
(loop
for (quantity . amount) in coins
nconc (make-list quantity :initial-element amount)))
或者,使用 dolist
:
(defun fold-out (coins)
(let ((rcoins (reverse coins)) (res nil))
(dolist (c rcoins)
(let ((quantity (car c)) (amount (cdr c)))
(dotimes (j quantity) (push amount res))))
res))
表达式 (cons amount coins-list)
return 是一个新列表,但它不会修改 coins-list
;这就是为什么最终结果是 NIL。
因此您可以将其更改为 (setf coins-list (cons amount coins-list))
,这将显式修改 coins-list
,这将起作用。
然而,在 Lisp 的做事方式(函数式编程)中,我们尽量不修改那样的东西。相反,我们使每个表达式 return 成为一个基于输入值的值(一个新对象),然后将该新对象传递给另一个函数。通常,对象被传递给的函数与执行传递的函数是同一个函数;这就是递归。
如果我要这样做,我可能会使用嵌套循环:
(defun fold-out (coins)
(loop for (count . value) in coins
append (loop repeat count
collect value)))
节省了相当多的打字、手动积累到事物中,并且总体上相对可读。可以做更多的文档字符串,也许还有一些单元测试。