maphash
当我找到我想要的东西时,我需要尽早退出。
(defun find-in-hash (str hash)
(let ((match nil))
(maphash (lambda (key value)
(if (string-prefix-p str key)
(setq match key))) hash)
match))
我将如何在 Emacs Lisp 中做到这一点?
如如何中断 maphash中所述,您可以将 amaphash
放在块内并通过 退出块return-from
,即使用表单
(block stop-mapping
(maphash
;; Function to call for all entries in ht.
;; A condition for when to stop mapping.
(return-from stop-mapping)
ht))
请注意,这需要cl
可以通过(require 'cl)
. 正如评论中提到的,在纯 elisp 中可以通过以下方式实现相同的结果
(catch 'stop-mapping
(maphash
;; Function to call for all entries in ht.
;; A condition for when to stop mapping.
(throw 'stop-mapping retval)
ht))
这里有点自我推销:)
我一直在研究一组宏(尽管最近没有那么多),以使其更加统一,并且希望更容易对 Emacs Lisp 中可用的各种集合进行各种迭代。它是:https ://code.google.com/p/i-iterate/它不是 100% 完成和测试的,但在大多数情况下它是。
正如已经说过的,唯一的突破方法maphash
是抛出一个错误。但这只是 Emacs Lisp 在设计时获得的东西。许多较旧的语言具有用于迭代特定集合或执行数字迭代的特殊原语,而它们没有语言级别的迭代抽象。loop
Emacs Lisp中包中的宏cl
是解决这种情况的一种(好)方法,但就其本质而言,它必须镜像 Common Lisp 中的相同宏,并且该宏不可扩展(您不能向其中添加自己的驱动程序,甚至如果某些实现允许它)。
我工作的库试图在精神上效仿另一个 Common Lisp 库:iterate
并从那里借鉴了许多想法。
只是为了说明loop
宏可以做什么:
(loop with hash = (make-hash-table)
initially
(setf (gethash 'a hash) 'b
(gethash 'b hash) 'b
(gethash 'c hash) 'c) ; initialize variables
; before any iteration happens
for x being the hash-key in hash
using (hash-value y) ; define variables used in iteration
collect (list x y) into z ; some predefined functionality
until (eq x y) ; termination condition
finally (return (cons 'd z))) ; returning from iteration
;; (d (a b) (b b))
得益于它对哈希表、数组或列表的工作方式类似。
++
使用宏的类似代码:
(++ (with ((hash (let ((h (make-hash-table)))
(setf (gethash 'a h) 'b
(gethash 'b h) 'b
(gethash 'c h) 'c) h))))
(for (x . y) pairs hash)
(collect (list x y) into z)
(when (eq x y) (return (cons 'd z))))
;; (d (b b) (a b))
(我还没有类似的东西initially
)