从哈希表中移除值
Lisp - 从哈希表中移除值
Section titled “Lisp - 从哈希表中移除值”哈希表(hash table)是 Lisp 中用于存储键值对的基本数据结构,能提供高效的数据检索。在本章中,你将学习在 Common Lisp 中从哈希表移除条目的现代、惯用方法。
The REMHASH 函数
Section titled “The REMHASH 函数”从哈希表中移除键值对的主要函数是 REMHASH。它接受一个键和一个哈希表作为参数,如果对应的条目存在则将其移除,并就地修改该哈希表。
(remhash key hash-table) -> generalized-boolean- key:你想要移除的条目的键。
- hash-table:要修改的哈希表。
- 返回值:如果找到并移除了条目,
REMHASH返回T,否则返回NIL。
逐步示例:移除条目
Section titled “逐步示例:移除条目”让我们通过一个完整的示例来演示如何创建哈希表、填充数据、移除项并验证结果。我们将使用 let 来创建一个词法作用域(lexically scoped)的哈希表,这在示例中是一个最佳实践,可以避免污染全局命名空间。
main.lisp
Section titled “main.lisp”(let ((product-prices (make-hash-table :test #'equal))) ;; 1. 使用一些产品数据填充哈希表 (setf (gethash "Laptop" product-prices) 1200) (setf (gethash "Mouse" product-prices) 25) (setf (gethash "Keyboard" product-prices) 75)
(format t "Original table: ~a~%" product-prices) (format t "Price of a Mouse before removal: $~a~%~%" (gethash "Mouse" product-prices))
;; 2. 从哈希表中移除 'Mouse' 条目 (let ((removed-p (remhash "Mouse" product-prices))) (if removed-p (format t "Successfully removed the 'Mouse' entry.~%") (format t "'Mouse' entry was not found.~%")))
;; 3. 验证条目已被移除 (multiple-value-bind (price found-p) (gethash "Mouse" product-prices) (format t "~%Checking for 'Mouse' after removal:~%") (if found-p (format t "Entry still exists with price: $~a~%" price) (format t "Entry for 'Mouse' no longer exists.~%")))
(format t "Final table: ~a~%" product-prices))原始表: #<HASH-TABLE :TEST EQUAL :COUNT 3 {1005A...}>移除前鼠标的价格:$25
成功移除了 'Mouse' 条目。
移除后检查 'Mouse':'Mouse' 的条目不再存在。最终表: #<HASH-TABLE :TEST EQUAL :COUNT 2 {1005A...}>最佳实践与常见陷阱
Section titled “最佳实践与常见陷阱”选择正确的 :test 函数
Section titled “选择正确的 :test 函数”创建哈希表时,:test 函数至关重要。它决定了键是如何比较的。
#'eql(默认值):比较相同类型和值的数字,或内存中的相同对象。适用于符号和数字。#'equal:按字符比较字符串,或按内容比较列表和向量。对于字符串键请使用此项。#'equalp:一个更宽松的equal版本,忽略字符串的大小写和数字类型差异。
正确检查键是否存在
Section titled “正确检查键是否存在”gethash 返回两个值:与键关联的值(如果未找到则为 NIL),以及一个布尔值(T 或 NIL)指示是否找到了键。键可能存在但其值为 NIL,因此你必须检查第二个返回值以进行准确的存在性检查。
;; 错误的方式(如果值为 NIL 则失败)(if (gethash key table))
;; 正确的方式(multiple-value-bind (value found-p) (gethash key table) (if found-p ;; 找到了键,对 'value' 进行操作 ...))现在你已经知道如何使用 remhash 有效地从 Common Lisp 哈希表中移除条目了。通过遵循现代最佳实践,例如使用 let 进行局部作用域、选择正确的 :test 函数以及正确检查返回值,你可以编写出健壮且可预测的代码。