更新哈希表中的值
Lisp - 修改哈希表条目
Section titled “Lisp - 修改哈希表条目”哈希表是 Common Lisp 中用于存储键值对的一种基本且高效的数据结构。本教程涵盖了在哈希表中添加、更新和管理条目的标准方法。
创建和修改哈希表
Section titled “创建和修改哈希表”在哈希表中添加或更新值的主要机制是 (setf gethash) 的组合。
(make-hash-table):创建一个新的空哈希表。(gethash key table):从table中检索与key关联的值。如果未找到键,则返回nil。(setf (gethash key table) value):这个强大的构造将与key关联的值设置为value。如果key已存在,其值将被更新。如果key不存在,则会创建一个新条目。
:test 函数的重要性
Section titled “:test 函数的重要性”创建哈希表时,可以使用 :test 参数指定键的比较方式。这对于正确的行为至关重要。
#'eql(默认):比较两个对象是否相同。适用于符号和数字。(eql 'a 'a)为真,但(eql "a" "a")为假,因为它们是内存中两个不同的字符串对象。#'equal:比较两个对象是否具有相同的结构和内容。这对于字符串键是必需的。#'eq:类似于eql,但可能不适用于数字。比较内存位置。#'equalp:equal的一个更宽松版本,它忽略字符串中的大小写和数字类型。
示例 1:使用默认的 eql 测试(针对符号)
Section titled “示例 1:使用默认的 eql 测试(针对符号)”本示例展示了使用符号作为键添加和更新哈希表,这与默认的 eql 测试完美配合。
main.lisp
Section titled “main.lisp”;; 创建一个使用默认测试('eql')的哈希表。(defvar *symbol-ages* (make-hash-table))
;; 添加初始键值对。(setf (gethash 'alice *symbol-ages*) 30)(setf (gethash 'bob *symbol-ages*) 45)
(format t "Initial age of Alice: ~a~%" (gethash 'alice *symbol-ages*))
;; 更新现有值。(format t "Updating Alice's age to 31...~%")(setf (gethash 'alice *symbol-ages*) 31)
(format t "Updated age of Alice: ~a~%" (gethash 'alice *symbol-ages*))
;; 添加新条目。(format t "Adding Charlie, age 25...~%")(setf (gethash 'charlie *symbol-ages*) 25)(format t "Age of Charlie: ~a~%" (gethash 'charlie *symbol-ages*))Initial age of Alice: 30Updating Alice's age to 31...Updated age of Alice: 31Adding Charlie, age 25...Age of Charlie: 25示例 2:使用 equal 测试(针对字符串键)
Section titled “示例 2:使用 equal 测试(针对字符串键)”当使用字符串作为键时,你必须指定 #'equal 作为测试函数。
main.lisp
Section titled “main.lisp”;; 创建一个使用 'equal' 测试(针对字符串)的哈希表。(defvar *fruit-prices* (make-hash-table :test #'equal))
;; 添加键值对。(setf (gethash "apple" *fruit-prices*) 1.50)(setf (gethash "banana" *fruit-prices*) 0.75)
(format t "Initial price of an apple: $~,2f~%" (gethash "apple" *fruit-prices*))
;; 更新苹果的价格。(setf (gethash "apple" *fruit-prices*) 1.75)
(format t "Updated price of an apple: $~,2f~%" (gethash "apple" *fruit-prices*))Initial price of an apple: $1.50Updated price of an apple: $1.75要从哈希表中移除一个条目,请使用 remhash 函数。如果移除了条目,它返回 t,否则返回 nil。
(remhash 'bob *symbol-ages*) ; => T(条目已移除)(gethash 'bob *symbol-ages*) ; => NIL(不再存在)(remhash 'dave *symbol-ages*) ; => NIL(从未存在)