我想编写一个将key和value作为参数的函数。如果表中已存在If键,那么它将在列表中为其当前值添加值。
例如,
(setf (gethash "key" table) 1) ==> 1 as Value of Key
(setf (gethash "key" table) 2) ==> (1 2) as Value of key
我有执行该功能的功能检查器
(defun checker(_key values)
(if (gethash _key table)
(let
(setf lists (gethash _key table))
(push values lists)
(setf (gethash _key table) lists))
(setf (gethash _key table) values)))
我收到以下错误:
Bad Binding(gethash _key table)
答案 0 :(得分:1)
LET
具有以下语法:
(let <bindings> <body>)
...其中binding是<var>
或(<var> <value>)
元素的列表。在这里,您定义了一个名为setf
的变量,另一个名为lists
的变量,但第三个变量不是正确的绑定。
您的代码的固定版本将是:
(defun checker (key value)
(let ((list (gethash key table)))
(cond
(list
(push value list)
(setf (gethash key table) list))
(t (setf (gethash key table) value)))))
但是,您可能会注意到有很多冗余代码。您所需要的只是:
(defun table-push (key table value)
(push value (gethash key table)))
如果您需要对列表进行排序,可以使用MERGE
并执行此操作:
(defun push-sorted-table (key table value &key (predicate #'<))
(setf (gethash key table)
(merge 'list
(list value)
(gethash key table)
predicate)))
这将破坏性地修改现有列表,但您可能不介意只要您只通过表访问列表,并且不保留指向代码其他部分的内部缺陷单元的指针。 对于大型数据集,您可以存储平衡树而不是列表,以便渐进地更好地插入新元素。