Je suis vraiment confus avec la .
notation. Est-ce '(a . b)
une liste?
(listp '(a . b))
retourne t
mais quand je veux savoir sa longueur (length '(a . b))
donne une erreur Wrong type argument: listp, b
. La même chose est pour les autres fonctions comme nth,mapcar
etc., elles donnent toutes la même erreur
Y a-t-il une fonction que je peux distinguer entre '(a b)
et '(a . b)
?
Contexte: J'ai rencontré ce problème lorsque j'ai voulu implémenter une version récursive de mapcar
. Voici ma mise en œuvre
(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))
Je l'utilise pour extraire toutes les balises spécifiques du html analysé. Exemple d' html
analyse
;; 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>
Ensuite, j'extrait tout <td>
comme
(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
et que je veux extraire toutes les <td>
balises.
consp
place.
cddr
la liste (pour ignorer le nom de l'élément et les attributs). Une fois que vous avez fait cela, vous devriez constater que toutes les listes sont correctes et votre problème disparaîtra. Il corrigera également un bogue dans votre code où vous pouvez confondre un td
attribut pour un td
élément.
true-list-p
en a pas dans Elisp simplement parce qu'il n'a pas été jugé suffisamment utile pour le fournir. En effet, je ne me souviens pas de la dernière fois que j'ai voulu tester si une liste était correcte, alors peut-être que si vous nous donnez un peu plus d'informations sur votre cas d'utilisation, nous pouvons vous aider à résoudre votre problème d'une autre manière.