Làm thế nào để nối hai danh sách?


13

Xin lỗi, nhưng elisp không phải là tốt nhất của tôi. Tôi cần kết hợp hai danh sách các chuỗi theo cách này:

("a" "b" "c") + ("d" "e" "f") -> ("a" "b" "c" "d" "e" "f")

Chà, thứ tự không quan trọng, vì vậy tôi đã viết mã này:

(while lista
  (add-to-list 'listb (car lista)) 
  (setq lista (cdr lista)))

Nó hoạt động, nhưng tôi tự hỏi nếu có một chức năng đã làm điều này.

Có manh mối nào không? Cảm ơn trước.


4
Xem danh sách nút xây dựng của hướng dẫn Elisp.
vẽ

2
appendlà câu trả lời đúng ở đây, nhưng một cách khác (phá hoại) để làm điều đó sẽ là (setcdr (last a) b).
Sean Allred

1
Làm việc trên danh sách? dash.el ! (-concat '(1) '(2 3) '(4)) ;; => '(1 2 3 4)
Ehvince

Không bao giờ sử dụng add-to-listtrong mã Lisp (nó nói điều này trong chuỗi doc). Thay vào đó, sử dụng push.
Radon Rosborough

Câu trả lời:


23

Bạn cũng có thể chỉ cần sử dụng thêm.

(append '("a" "b" "c") '("d" "e" "f"))

2
Và,(nconc '("a" "b" "c") '("d" "e" "f"))
luật

1
Ồ, vâng, thực sự appendcó vẻ tốt hơn ở đây.
JeanPierre

nconc hoạt động nhưng, nếu bạn lưu trữ danh sách trong các biến, chúng sẽ được sửa đổi bởi nconc. Ví dụ (let ((a '(1 2 3)) (b' (3 4 5))) (nconc ab) a) sẽ sửa đổi một biến.
John Kitchin

1
FYI cl-concatenatesử dụng appendkhi TYPE list, vì vậy cả hai câu trả lời đều cho kết quả như nhau.
phils

Yess, nó chắc chắn làm công việc. Rất cám ơn mọi người đã giúp đỡ.
Daniele

3

concatenate là một bí danh cho 'cl-concatenate' trong 'cl.el'.

(nối với LOẠI TÌM KIẾM ...)

Ghép nối, thành một chuỗi kiểu TYPE, đối số SEQUENCE.

Vì vậy, ví dụ của bạn

(concatenate 'list '("a" "b" "c") '("d" "e" "f"))

Vì nó được định nghĩa trong clbạn có thể phải (require 'cl)đầu tiên, nếu không bạn có thể sử dụng cl-concatenatemà dường như được nạp theo mặc định.

Ngoài ra, như được chỉ ra bởi @phils cl-concatenatechỉ gọi appendkhi TYPE 'list, đây là nguồn từ cl-extra.el:

(defun cl-concatenate (type &rest sequences)
  "Concatenate, into a sequence of type TYPE, the argument SEQUENCEs.
\n(fn TYPE SEQUENCE...)"
  (pcase type
    (`vector (apply #'vconcat sequences))
    (`string (apply #'concat sequences))
    (`list (apply #'append (append sequences '(nil))))
    (_ (error "Not a sequence type name: %S" type))))

Vì vậy, nếu bạn chỉ sử dụng danh sách, việc sử dụng trực tiếp sẽ đơn giản hơn append, như được chỉ ra bởi @John Kitchin.

Cuối cùng, @lawlist đã đề cập nconc:

nconc là một hàm tích hợp trong 'mã nguồn C'.

(DANH SÁCH & DANH SÁCH nghỉ ngơi)

Ghép nối bất kỳ số lượng danh sách bằng cách thay đổi chúng. Chỉ đối số cuối cùng không bị thay đổi và không cần phải là một danh sách.

Điều này có nghĩa là gì:

(nconc '("a" "b" "c") '("d" "e" "f"))
=> ("a" "b" "c" "d" "e" "f")

(setq l1 '("a" "b" "c")
      l2 '("d" "e" "f"))
(nconc l1 l2)
=> ("a" "b" "c" "d" "e" "f")
l1
=> ("a" "b" "c" "d" "e" "f")
l2
=> ("d" "e" "f")

Cảm ơn, nhưng có vẻ như nó trả về lỗi nếu đối số thứ 2 và thứ 3 là các biến và không phải là danh sách rõ ràng.
Daniele

1
(setq l1 '("a" "b" "c") l2 '("d" "e" "f")) (concatenate 'list l1 l2)hoạt động tốt
JeanPierre

@Daniele Tôi nghi ngờ bạn đang cố gắng trích dẫn các biến, có nghĩa là chúng không được đánh giá theo giá trị danh sách của chúng. (tức là bạn muốn varnamechứ không phải 'varname).
phils

Để đầy đủ, tôi cũng có thể đề cập đến cách không CL kết hợp bất kỳ loại trình tự nào trong Emacs> = 25: seq-concatenate(sau (require 'seq)), mặc dù điều này đến lượt nó chỉ là kết thúc tốt đẹp cl-concatenate.
Basil
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.