Estou realmente confuso com a .
notação. É '(a . b)
uma lista?
(listp '(a . b))
retorna, t
mas quando eu quero saber o seu comprimento (length '(a . b))
dá um erro Wrong type argument: listp, b
. O mesmo se aplica a outras funções, nth,mapcar
etc. todos eles dão o mesmo erro
Existe alguma função que eu possa distinguir entre '(a b)
e '(a . b)
?
Contexto: eu encontrei esse problema quando queria implementar a versão recursiva do mapcar
. Aqui está a minha implementação
(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))
Eu uso isso para extrair todas as tags específicas do html analisado. Exemplo de html
para analisar
;; 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>
Então eu extraio tudo <td>
como
(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
e quero extrair todas as <td>
tags.
consp
vez disso.
cddr
a lista (para ignorar o nome do elemento e os atributos). Depois de fazer isso, você deve descobrir que todas as listas estão corretas e seu problema desaparecerá. Ele também corrigirá um erro no seu código, onde você pode confundir um td
atributo para um td
elemento.
true-list-p
no Elisp simplesmente porque não foi considerado útil o suficiente para fornecê-lo. Na verdade, não me lembro da última vez em que desejei testar se uma lista era adequada; talvez, se você nos der um pouco mais de informações sobre seu caso de uso, possamos ajudá-lo a resolver seu problema de outra maneira.