Lisp,嵌套列表中数字的子总数

0 lisp common-lisp

我有一个问题,我只是无法解决,

用户输入列表即

 (total-cost 
   '((anItem 2 0.01) 
     (item 3 0.10) 
     (anotherItem 4 4.10) 
     (item 5 2.51))) 
Run Code Online (Sandbox Code Playgroud)

我需要在最后添加数字,然后返回结果

我的当前代码在每次添加后返回代码.并且还会抛出有关意外类型的错误

(defun total-cost (list)
  (loop with sum = 0
        for x in list
      collect (setf sum (+ sum (last x)))
   )
)
Run Code Online (Sandbox Code Playgroud)

错误:(0.01)' is not of the expected typeNUMBER'

任何帮助表示感谢,感谢Dale

Rai*_*wig 10

使用LOOP:

CL-USER 19 > (loop for (nil nil number) in '((anItem      2 0.01) 
                                             (item        3 0.10) 
                                             (anotherItem 4 4.10) 
                                             (item        5 2.51))
                   sum number)
6.72
Run Code Online (Sandbox Code Playgroud)

REDUCE 是另一种选择:

CL-USER 20 > (reduce '+
                     '((anItem      2 0.01) 
                       (item        3 0.10) 
                       (anotherItem 4 4.10) 
                       (item        5 2.51))
                     :key 'third)
6.72
Run Code Online (Sandbox Code Playgroud)


use*_*lpa 5

Loop有一个sum用于求和的关键字,因此您不必使用显式变量,也不必使用setf:

(defun total-cost (list)
  (loop for x in list sum (third x)))
Run Code Online (Sandbox Code Playgroud)

正如克里斯所说,(car (last x))如果你要找的号码总是最后一个,请使用.或者你可以(third x)在我的例子中使用它,如果它总是第三个.

另请注意,collect如果您的目的是仅返还金额,则使用错误; 你的例子(更正)返回

(0.01 0.11 4.21 6.7200003)
Run Code Online (Sandbox Code Playgroud)

而我的回归

6.7200003
Run Code Online (Sandbox Code Playgroud)

请注意,如果您希望尽可能地避免舍入错误,则需要使用指数标记来使它们成为双浮点,例如:

(total-cost '((anItem 2 0.01D0)
             (item 3 0.10D0) 
             (anotherItem 4 4.10D0) 
             (item 5 2.51D0)))
=> 6.72D0
Run Code Online (Sandbox Code Playgroud)

  • 另见`*READ-DEFAULT-FLOAT-FORMAT* (2认同)