8

如何迭代 Elisp 哈希表中的项目(键、值)?

我使用不同的项目创建了一个哈希表(地图、字典)(make-hash-table)并填充了它。在 Python 中,我可以通过以下方式遍历 dicts:

for k in d # iterate over keys
for k in d.keys() # same
for k in d.values() # iterate over values
for k in d.items() # iterate over tuples (key, value)

我怎样才能以最简洁和优雅的方式做同样的事情,最好没有循环宏?

4

5 回答 5

15

(maphash (lambda (key value) ....your code here...) hash-table)

于 2013-01-07T11:16:40.840 回答
9

我要给自己做一些广告,所以要小心翼翼,但基本上,这里有你的选择:

  • maphash- 这是内置的迭代原语,从根本上说,没有更多的方法可以做到这一点。

  • (loop for KEY being the hash-key of TABLE for VALUE being the hash-value of TABLE ...)可在cl包装中使用。无论如何它都会在内部使用maphash,但它在不同的迭代原语之上为您提供了一些统一。您可以使用loop宏来迭代多个不同的事物,并通过从视线中删除技术信息来减少混乱。

  • http://code.google.com/p/i-iterate/这是我正在开发的一个库,旨在提供更多通用的方法来在 Emacs Lisp 中以不同的方式迭代不同的事物。它受到 Common Lisp Iterate 库的启发,但与它相去甚远(然而,一些基本原则仍然成立)。如果您要尝试这个库,哈希表上的迭代将如下所示:(++ (for (KEY VALUE) pairs TABLE) ...)or(++ (for KEY keys TABLE) ...)(++ (for VALUE values TABLE) ...).

cl loop我将尝试描述使用or的优缺点i-iterate

  • 与 不同loop的是, iterate 允许一次迭代多个哈希表(但您必须注意它产生的额外成本:第二个、第三个等哈希表的键必须在迭代之前收集到一个列表中,这是在后面完成的场景)。
  • Iterate 提供了可以说更多的 Lisp-y 语法,更容易在编辑器中格式化。
  • 使用迭代,您有更多(将来可能甚至更多)选项来将迭代与其他操作结合起来。
  • 到目前为止,除了我自己之外,没有其他人在使用它 :) 它可能仍然存在错误,并且可能会重新设计一些东西,但它已接近功能冻结并准备好正确使用。
  • 明显更多的人熟悉内置的迭代原语或cl库。

顺便说一句,哈希表迭代的完整版本如下所示:(for VAR pairs|keys|values TABLE &optional limit LIMIT),其中LIMIT代表您要查看的元素数量(它将生成更高效的代码,然后如果您要使用更通用的工具)。

于 2013-01-07T12:23:10.347 回答
3

maphash是你想要的功能。另外我建议你看一下手册(info "(elisp) Hash Tables")

于 2013-01-07T16:18:57.633 回答
2

从 2013 年开始有一个第三方库ht,它提供了许多方便的函数来操作 Elisp 哈希表。

假设您有一个哈希表,其中键是字符串,值是整数。要遍历哈希表并返回列表,请使用ht-map

(ht-map (lambda (k v) (+ (length k) v)) table)
;; return list of all values added to length of their keys

ht-each只是maphash. 上述 2 个函数也有照应ht-amap版本,称为和ht-aeach。它们不接受匿名函数,而是公开变量keyvalue. 这是与上述表达式等效的表达式:

(ht-amap (+ (length key) value) table)
于 2016-01-12T00:28:46.847 回答
0

我更愿意将其放入评论中,但具有讽刺意味的是,我的声誉评级使我无法以适当的格式编写此内容......

loop被认为已弃用,cl库也是如此,因为它不遵守用公共库前缀为所有符号添加前缀的约定,因此用没有明确库关联的符号污染了 obarray。

而是使用cl-libwhich 定义相同的函数和宏,但将它们命名为例如cl-loopandcl-defun而不是loopand defun*。如果您只需要宏,则可以导入cl-macs

于 2013-05-30T15:22:44.950 回答