Jestem naprawdę pomylony z .
notacją. Jest '(a . b)
lista?
(listp '(a . b))
zwraca, t
ale gdy chcę wiedzieć, jego długość (length '(a . b))
powoduje błąd Wrong type argument: listp, b
. To samo dotyczy innych funkcji nth,mapcar
itp., Wszystkie dają ten sam błąd
Czy jest jakaś funkcja, która mogę rozróżnić '(a b)
i '(a . b)
?
Kontekst: napotkałem ten problem, gdy chciałem zaimplementować wersję rekurencyjną mapcar
. Oto moja implementacja
(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))
Używam tego do wyodrębnienia wszystkich określonych tagów z przeanalizowanego HTML. Przykład html
analizy
;; 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>
Następnie wyodrębniam wszystko <td>
jako
(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
i chcę wyodrębnić wszystkie <td>
tagi.
consp
zamiast tego.
cddr
listą (aby pominąć nazwę elementu i atrybuty). Gdy to zrobisz, powinieneś stwierdzić, że wszystkie listy są prawidłowe, a Twój problem zniknie. Naprawi to również błąd w kodzie, w którym możesz pomylić td
atrybut td
elementu.
true-list-p
w Elisp po prostu dlatego, że nie został uznany za przydatny wystarczy do jej świadczenia. Rzeczywiście, nie pamiętam, kiedy ostatni raz chciałem sprawdzić, czy lista jest odpowiednia, więc może jeśli podasz nam nieco więcej informacji na temat swojego przypadku użycia, możemy pomóc Ci rozwiązać problem w inny sposób.