Подтвердить что ты не робот

Общий Lisp: получение всех ключей данной хэш-таблицы в виде списка

Интересно, существует ли менее вербальный способ, чем использование цикла. В любом случае это работает для меня в 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))
4b9b3361

Ответ 1

Общий Lisp исходит из того, что философия стала более распространенной, и большинство функций, как ожидается, будут предоставляться сторонними библиотеками, а не реализациями. В то время как Common Lisp иногда называют большим языком, он сравнивается только с C и аналогичным, сам язык довольно крошечный по сравнению с Python и другими языками с массивными стандартными библиотеками.

Для этой конкретной цели Alexandria является обычно используемой коллекцией общих Lisp утилит. Среди многих других вещей он содержит hash-table-keys.

Ответ 2

Нет недостатка в определении

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

потому что в Common Lisp функция скомпилирована. Если ваш поставщик предоставил эту функцию, он в значительной степени сделает то же самое и не будет намного более эффективным, чем ваш, если вообще.

В интерпретируемых языках почти все, что вы пишете, имеет недостаток производительности по сравнению с "внутренней" процедурой.

Консолидация содержимого хэша расточительна; loop позволяет обрабатывать хеш без сохранения памяти. Так что, возможно, вам нужен макрос (некоторые 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)))

Должен ли язык иметь всевозможные гаджеты, подобные тому, что каждый может написать через минуту?

В общем Lisp имеются батарейки, но они - другие типы батарей: вещи, которые на самом деле трудно сделать. Например, функция compile для динамической компиляции кода во время выполнения. Для большинства пользователей было бы трудно создать такую ​​вещь с нуля, по сравнению с извлечением ключей или значений из хеш-таблицы в полдюжины различных способов.