2014-06-22 16 views
8

Trong Emacs lisp có add-to-list để thêm một phần tử vào danh sách (nếu nó chưa tồn tại).Cách thêm nhiều phần tử vào danh sách trong Emacs lisp

Thay vì một, tôi muốn thêm nhiều phần tử. Ngoài ra, tôi không muốn lọc các phần tử trùng lặp nhưng vẫn thêm chúng vào danh sách.

Hiện nay, tôi đã thực hiện các chức năng sau:

(defun append-to-list (list-var elements) 
    "Append ELEMENTS to the end of LIST-VAR. 

The return value is the new value of LIST-VAR." 
    (set list-var (append (symbol-value list-var) elements))) 

Chức năng làm những gì tôi muốn, nhưng tôi đã tự hỏi nếu một cái gì đó như thế này (hoặc tốt hơn) đã tồn tại trong Emacs lisp. Tôi không muốn phát minh lại bánh xe.

Cập nhật 1: Stefan chỉ ra bên dưới rằng mã này không hoạt động với phạm vi từ vựng. Có cách nào để làm cho nó hoạt động không?

Cập nhật 2: Trước đây tôi nghĩ rằng tính năng lọc trùng lặp sẽ ổn nhưng không. Tôi cần bản sao.

+1

Mã của bạn vẫn ổn. Không có chức năng hệ thống tương tự. – sds

+1

Tôi sẽ không mô tả nó là "tốt", nhưng có, nó sẽ làm việc. Sử dụng 'symbol-value' và' set' có nghĩa là nó không thể được sử dụng với một biến có phạm vi từ vựng. Trừ khi bạn ** thực sự ** cần nó, tốt hơn nên thêm 'elements' ngay từ đầu, vì' elements' sẽ hầu như luôn ngắn hơn (và đôi khi * nhiều * ngắn hơn) so với 'list-var'. – Stefan

+0

Có cách nào để làm cho mã hoạt động với phạm vi từ vựng không? –

Trả lời

4

Điều này sẽ gần như tương đương nhưng nhanh hơn, vì nó không tạo bản sao của danh sách gốc trước khi thêm các phần tử mới.

(defun append-to-list (list-var elements) 
    "Append ELEMENTS to the end of LIST-VAR. 

The return value is the new value of LIST-VAR." 
    (unless (consp elements) 
    (error "ELEMENTS must be a list")) 
    (let ((list (symbol-value list-var))) 
    (if list 
     (setcdr (last list) elements) 
     (set list-var elements))) 
    (symbol-value list-var)) 

append không sao chép các yếu tố cuối cùng, nhưng sử dụng nó trực tiếp như đuôi của danh sách mới, vì vậy phần đó là giống hệt nhau. Tuy nhiên, nếu có thêm tham chiếu đến đối tượng danh sách gốc (hoặc một số phần của nó), thì sẽ là sự khác biệt chức năng giữa việc sao chép danh sách đó (qua append) và chỉ mở rộng nó (với setcdr). Mà trong hai kết quả mà bạn thực sự muốn là tùy thuộc vào bạn, tất nhiên.

+0

Burps nếu danh sách ban đầu là không! – Stefan

+0

D'oh. Đã sửa. Cảm ơn Stefan. – phils

+0

Ít nhất trong trường hợp sử dụng hiện tại của tôi, tôi không giữ tài liệu tham khảo xung quanh. Vì vậy, điều này có vẻ sạch hơn với tôi vì nó tránh sao chép. Cảm ơn! Nhưng nó có thể được thực hiện để làm việc với phạm vi từ vựng? –

2

Nếu bạn không quan tâm đến đặt hàng:

(setf var (cl-list* elt1 elt2 elt3 var)) 

Đối số cuối cùng để trở thành list* đuôi của danh sách kết quả.

+0

Tôi cần kiểm soát thứ tự, vì vậy điều này sẽ không hoạt động. –

4

Tôi có các thông tin sau trong tệp init cho phép thêm nhiều phần tử. Tôi không biết làm thế nào hiệu quả là để lặp qua các mục để thêm nhưng nó ngăn chặn các yếu tố trùng lặp.

(defun jlp/add-to-list-multiple (list to-add) 
    "Adds multiple items to LIST. 
Allows for adding a sequence of items to the same list, rather 
than having to call `add-to-list' multiple times." 
    (interactive) 
    (dolist (item to-add) 
    (add-to-list list item))) 
+0

Điều này sẽ không hoạt động vì tôi thực sự cần các giá trị trùng lặp trong danh sách. –

Các vấn đề liên quan