Common Lisp:将给定哈希表的所有键作为列表

时间:2012-03-15 12:37:41

标签: lisp hashmap hashtable common-lisp key

我想知道是否有比使用循环更简洁的方法。无论如何,这在CLISP中对我有用:

(loop for key being the hash-keys of *my-hash* collect key)

我见过其他人使用maphash,但这涉及将每个密钥累积到一个列表中。除了比使用循环更多参与之外,它还引入了副作用,我尽可能避免这种副作用 - 我更喜欢函数式编程:)

是否有针对此常见任务预定义的内容,即使是特定于实现的?

(defun hash-keys (hash-table)
  (loop for key being the hash-keys of hash-table collect key))

2 个答案:

答案 0 :(得分:21)

Common Lisp来自于“包含电池”的理念变得普遍,并且大多数功能预计将由第三方库提供而非实现。虽然Common Lisp有时被称为大型语言,但它只与C语言相似,与Python和其他具有大量标准库的语言相比,语言本身相当小。

出于此特定目的,Alexandria是Common Lisp实用程序的常用集合。在其他许多内容中,它包含hash-table-keys

答案 1 :(得分:10)

定义

没有缺点
(defun hash-keys (hash-table)
  (loop for key being the hash-keys of hash-table collect key))

因为在Common Lisp中编译了该函数。如果你的供应商提供了这个功能,那么它几乎可以做同样的事情而不是比你的更有效率。如果有的话。

在解释型语言中,与“内在”例程相比,您自己编写的几乎任何内容都具有性能劣势。

消耗哈希的内容是浪费的;循环允许您处理哈希而不占用内存。所以也许你想要一个宏(有些Lisps提供dohash或类似的扩展名)。

(defmacro do-hash ((key-var val-var hash-expr &optional result-form) &body body)
  (let ((hash-var (gensym "HASH-")))
     `(loop with ,hash-var = ,hash-expr
            for ,key-var being the hash-keys of ,hash-var
            for ,val-var being the hash-values of ,hash-var
            do (progn ,@body)
            finally (return ,result-form))))

或者哈希映射函数:

 (defun mapc-hash (hash-table fun) 
   (loop for key being the hash-keys of hash-table
         for value being the hash-values of hash-table
         do (funcall fun key value)))

语言是否应该有这样的小工具,任何人都可以在一分钟内写出来?

在Common Lisp中,包括电池,但它们是其他类型的电池:实际上很难做到的事情。例如,compile函数用于在运行时动态编译代码。与以六种不同方式从哈希表中提取密钥或值相比,大多数用户从头开始开发这样的东西是非常困难的。