将值添加到Lisp中的HashMap表中的列表中的相同键

时间:2016-02-14 00:24:17

标签: hashmap lisp

我想编写一个将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)

1 个答案:

答案 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)))

PUSH在某个地方运作,GETHASH可用于修改条目。

如果您需要对列表进行排序,可以使用MERGE并执行此操作:

(defun push-sorted-table (key table value &key (predicate #'<))
  (setf (gethash key table)
        (merge 'list
               (list value)
               (gethash key table)
               predicate)))

这将破坏性地修改现有列表,但您可能不介意只要您只通过表访问列表,并且不保留指向代码其他部分的内部缺陷单元的指针。 对于大型数据集,您可以存储平衡树而不是列表,以便渐进地更好地插入新元素。