将值添加到与 Lisp 中 HashMap Table 中的列表相同的键
Adding values to same key as list in HashMap Table in Lisp
我想编写一个将键和值作为参数的函数。这样如果 table 中已经存在键,那么它会将值添加到列表中的当前值。
例如,
(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)
LET
具有以下语法:
(let <bindings> <body>)
... 其中绑定是 <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) (list value))))))
但是,您可能会注意到有很多冗余代码。您只需要:
(defun table-push (key table value)
(push value (gethash key table)))
PUSH
operates on a place, and GETHASH
可用于修改条目。
如果你需要对列表进行排序,你可以使用MERGE
并这样做:
(defun push-sorted-table (key table value &key (predicate #'<))
(setf (gethash key table)
(merge 'list
(list value)
(gethash key table)
predicate)))
这将破坏性地修改现有列表,但您可能不介意,只要您仅通过 table 访问列表并且不保留指向代码其他部分的内部 cons 单元格的指针。
对于大型数据集,您可以存储平衡树而不是列表,以便新元素的插入渐进地更好。
我想编写一个将键和值作为参数的函数。这样如果 table 中已经存在键,那么它会将值添加到列表中的当前值。
例如,
(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)
LET
具有以下语法:
(let <bindings> <body>)
... 其中绑定是 <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) (list value))))))
但是,您可能会注意到有很多冗余代码。您只需要:
(defun table-push (key table value)
(push value (gethash key table)))
PUSH
operates on a place, and GETHASH
可用于修改条目。
如果你需要对列表进行排序,你可以使用MERGE
并这样做:
(defun push-sorted-table (key table value &key (predicate #'<))
(setf (gethash key table)
(merge 'list
(list value)
(gethash key table)
predicate)))
这将破坏性地修改现有列表,但您可能不介意,只要您仅通过 table 访问列表并且不保留指向代码其他部分的内部 cons 单元格的指针。 对于大型数据集,您可以存储平衡树而不是列表,以便新元素的插入渐进地更好。