【问题标题】:Common Lisp: getting all keys of a given hash table as a listCommon Lisp:将给定哈希表的所有键作为列表获取
【发布时间】:2012-03-31 23:14:13
【问题描述】:

我想知道是否有比使用循环更简洁的方法。无论如何,这在 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))

【问题讨论】:

    标签: lisp hashmap hashtable common-lisp key


    【解决方案1】:

    Common Lisp 出现在“包含电池”的理念流行之前,大多数功能预计将由第三方库而不是实现提供。虽然 Common Lisp 有时被称为大型语言,但它仅与 C 和类似语言相比,与 Python 和其他具有大量标准库的语言相比,该语言本身非常小。

    为此,Alexandria 是常用的 Common Lisp 实用程序集合。除了许多其他内容,它还包含hash-table-keys

    【讨论】:

    • Common Lisp 在当时非常“包含电池”。人们现在只是期待更多(和不同种类的)电池。
    • 与 C 相比,Common Lisp 现在只是稍微大了一点,C 正在推动接近 700 页的 ISO 标准。 (与 1989 年 200 多页时相比,它只是一种“包含电池”的语言。)
    • 当今流行的大多数“包含电池”的语言必须采用这种方式,因为您自己编写的函数具有性能劣势。
    • 多么不幸; lisp 可以通过从其他总是 lisp 克隆的运行时中提取它需要的功能来统治世界。没有理由 lisp 不能与 nodejs、perl 或 bash 对话并使用它们的库,或者直接访问它们的运行时。
    【解决方案2】:

    定义没有缺点

    (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 函数。与以六种不同的方式从哈希表中提取键或值相比,大多数用户从头开始开发这样的东西是非常困难的。

    【讨论】:

    • (更不用说你在这里展示的宏定义工具...... :))。
    • 这应该是公认的答案,因为它不依赖于外部库
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多