Tôi thực sự bối rối với .
ký hiệu. Là '(a . b)
một danh sách?
(listp '(a . b))
trả về t
nhưng khi tôi muốn biết chiều dài của nó (length '(a . b))
báo lỗi Wrong type argument: listp, b
. Điều tương tự là đối với các chức năng khác, nth,mapcar
v.v ... tất cả đều có cùng một lỗi
Có chức năng nào tôi có thể phân biệt giữa '(a b)
và '(a . b)
?
Bối cảnh: Tôi gặp phải vấn đề này khi tôi muốn triển khai phiên bản đệ quy của mapcar
. Đây là cách thực hiện của tôi
(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))
Tôi sử dụng điều này để trích xuất tất cả các thẻ cụ thể từ html được phân tích cú pháp. Ví dụ về html
phân tích cú pháp
;; 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>
Sau đó tôi trích xuất tất cả <td>
như
(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
và tôi muốn trích xuất tất cả <td>
các thẻ.
consp
thay thế.
cddr
danh sách (để bỏ qua tên thành phần và thuộc tính). Khi bạn làm điều đó, bạn sẽ thấy rằng tất cả các danh sách là phù hợp và vấn đề của bạn sẽ biến mất. Nó cũng sẽ sửa một lỗi trong mã của bạn, nơi bạn có thể nhầm lẫn một td
thuộc tính cho một td
phần tử.
true-list-p
trong Elisp đơn giản vì nó chưa được tìm thấy đủ hữu ích để cung cấp nó. Thật vậy, tôi không thể nhớ lần cuối cùng tôi muốn kiểm tra xem một danh sách có phù hợp hay không, vì vậy có lẽ nếu bạn cung cấp cho chúng tôi thêm một chút thông tin về trường hợp sử dụng của bạn, chúng tôi có thể giúp bạn giải quyết vấn đề của bạn theo cách khác.