Saya benar-benar bingung dengan .
notasi. Apakah '(a . b)
daftar?
(listp '(a . b))
kembali t
tetapi ketika saya ingin tahu panjangnya (length '(a . b))
memberikan kesalahan Wrong type argument: listp, b
. Hal yang sama untuk fungsi lain seperti nth,mapcar
dll. Mereka semua memberikan kesalahan yang sama
Apakah ada fungsi yang bisa saya bedakan antara '(a b)
dan '(a . b)
?
Konteks: Saya mengalami masalah ini ketika saya ingin mengimplementasikan versi rekursif dari mapcar
. Ini implementasi saya
(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))
Saya menggunakan ini untuk mengekstrak semua tag tertentu dari html parsed. Contoh html
untuk menguraikan
;; 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>
Lalu saya mengekstrak semua <td>
sebagai
(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
dan saya ingin mengekstrak semua <td>
tag.
consp
malah.
cddr
daftar (untuk melewati nama elemen dan atribut). Setelah Anda melakukannya, Anda harus menemukan bahwa semua daftar sudah benar dan masalah Anda akan hilang. Ini juga akan memperbaiki bug dalam kode Anda di mana Anda dapat mengacaukan td
atribut untuk td
elemen.
true-list-p
di Elisp hanya karena belum ditemukan cukup berguna untuk menyediakannya. Memang, saya tidak ingat kapan terakhir kali saya ingin menguji apakah daftar itu benar, jadi mungkin jika Anda memberi kami sedikit lebih banyak informasi tentang kasus penggunaan Anda, kami dapat membantu Anda memecahkan masalah Anda dengan cara lain.