Я справді плутаю .позначення. Чи '(a . b)є список?
(listp '(a . b))повертається, tале коли я хочу знати, його довжина (length '(a . b))видає помилку Wrong type argument: listp, b. Те саме стосується інших функцій, як nth,mapcarі т. Д. Всі вони дають однакову помилку
Чи є якась функція, яку я можу розрізняти '(a b)і '(a . b)?
Контекст: Я зіткнувся з цією проблемою, коли хотів реалізувати рекурсивну версію mapcar. Ось моя реалізація
(defun true-listp (object)
"Return non-`nil' if OBJECT is a true list."
(and (listp object) (null (cdr (last object)))))
(defun recursive-mapcar (func list)
"Evaluates func on elements of the list, then on elements of elements of the list and so forth."
(let ((output nil))
(flet ((comp (a b) nil)
(call-fun-and-save (x) (add-to-list 'output (funcall func x) t 'comp))
(recursion (l)
(mapcar
(lambda (x)
(call-fun-and-save x)
(if (and (true-listp x)) ;; HERE I use true-listp, testing for list or cons is not sufficient
(recursion x)))
l)))
(recursion list))
output))
Я використовую це для вилучення всіх конкретних тегів з розбору HTML. Приклад htmlрозбору
;; buffer 'html'
<html>
<body>
<table style="width:100%">
<tr> <td>Jill</td> <td>Smith</td> <td>50</td> </tr>
<tr> <td>Eve</td> <td>Jackson</td> <td>94</td> </tr>
</table>
</body>
</html>
Тоді я витягую все <td>як
(with-current-buffer (get-buffer "html")
(let ((data (libxml-parse-html-region (point-max) (point-min))))
;; gat only <td> tags
(-non-nil
(recursive-mapcar
(lambda(x) (and (consp x) (equal 'td (car x)) x))
data))
data
)
)
libxml-parse-html-regionі хочу витягнути всі <td>теги.
conspзамість цього.
cddrсписком (щоб пропустити ім'я елемента та атрибути). Як тільки ви це зробите, ви повинні встановити, що всі списки є правильними і ваша проблема зникне. Він також виправить помилку у вашому коді, де ви можете заплутати tdатрибут для tdелемента.
true-list-pЕліспі немає просто тому, що його не знайшли достатньо корисним для його надання. Дійсно, я не можу пригадати, коли я востаннє хотів перевірити, чи є список належним, тому, можливо, якщо ви дасте нам трохи більше інформації про ваше використання, ми можемо допомогти вам вирішити вашу проблему іншим способом.