我有这样的结构
(loop :for c :in list-of-char-codes
:if (gethash c hash-of-frequencies)
:do (incf (gethash c hash-of-frequencies) 0))
是否有合理的方法可以避免冗余(gethash c hash-of-frequencies)
,例如,使用照应宏?
答案 0 :(得分:4)
您是否只想尝试那些已经在hash-of-frequencies
中的字符?
(loop :for c :in list-of-char-codes
:for freq = (gethash c hash-of-frequencies)
:when freq
:do (setf (gethash c hash-of-frequencies) (1+ freq)))
或许您想要计算所有字符?
(loop :for c :in list-of-char-codes
:do (incf (gethash c hash-of-frequencies 0)))
答案 1 :(得分:2)
您通常也可以使用#=
和##
来避免重复:
(loop :for c :in list-of-char-codes
:for freq = #1=(gethash c hash-of-frequencies)
:when freq
:do (setf #1# (1+ freq)))
这是在读取时插入代码。
答案 2 :(得分:1)
为了完整性,w.r.t。其他很好的答案,你也可以这样做:
(defun foo (list-of-char-codes hash-of-frequencies)
(macrolet ((hash (c) `(gethash ,c hash-of-frequencies)))
(loop :for c :in list-of-char-codes
:for freq = (hash c)
:when freq
:do (setf (hash c) (1+ freq)))))
请注意,如果您经常访问/修改相同的哈希表,那么定义一个全局宏来隐藏实现细节可能是个好主意。
另外,你甚至可以使用symbol-macrolet
,但我认为这种不好的风格,因为以下注入c
,使绑定隐式,并在重命名变量c
时会中断(你但是关于照应宏的问题:
;; AVOID DOING THAT, PLEASE
(defun foo (list-of-char-codes hash-of-frequencies)
(symbol-macrolet ((hash (gethash c hash-of-frequencies)))
(loop :for c :in list-of-char-codes
:for freq = hash
:when freq
:do (setf hash (1+ freq)))))