Bagaimana cara menggabungkan dua daftar?


15

Maaf, tapi elisp bukan yang terbaik. Saya perlu menggabungkan dua daftar string dengan cara ini:

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

Nah, urutannya tidak penting, jadi saya menulis kode ini:

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

Berhasil, tapi saya bertanya-tanya apakah ada fungsi yang sudah melakukan ini.

Ada petunjuk? Terima kasih sebelumnya.


4
Lihat simpul Daftar Bangunan manual Elisp.
Drew

2
appendadalah jawaban yang benar di sini, tetapi cara lain (destruktif) untuk melakukannya adalah (setcdr (last a) b).
Sean Allred

1
Sedang mengerjakan daftar? dash.el ! (-concat '(1) '(2 3) '(4)) ;; => '(1 2 3 4)
Ehvince

Jangan pernah gunakan add-to-listdalam kode Lisp (ia mengatakan ini di docstring). Sebaliknya, gunakan push.
Radon Rosborough

Jawaban:


25

Anda juga bisa menggunakan append.

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

2
Dan,(nconc '("a" "b" "c") '("d" "e" "f"))
hukum

1
Oh, ya, memang appendsepertinya lebih baik di sini.
JeanPierre

nconc berfungsi tetapi, jika Anda menyimpan daftar dalam variabel, mereka akan dimodifikasi oleh nconc. Misalnya (let ((a '(1 2 3)) (b' (3 4 5))) (nconc ab) a) akan memodifikasi variabel a.
John Kitchin

1
FYI cl-concatenatemenggunakan appendketika TYPE adalah list, jadi kedua jawaban menghasilkan hasil yang sama.
phils

Ya, itu pasti berhasil. Banyak terima kasih kepada semua orang atas bantuan Anda.
Daniele

3

concatenate adalah alias untuk 'cl-concatenate' di 'cl.el'.

(SEQUENCE TYPE gabungan ...)

Concatenate, menjadi urutan tipe TYPE, argumen SEQUENCEs.

Jadi untuk contoh Anda

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

Karena itu didefinisikan di clAnda mungkin harus (require 'cl)terlebih dahulu, jika tidak Anda dapat menggunakan cl-concatenateyang tampaknya dimuat secara default.

Juga, seperti yang ditunjukkan oleh @phils cl-concatenatehanya menelepon appendsaat TYPE sedang'list , inilah sumber dari 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))))

Jadi jika Anda hanya menggunakan daftar, lebih mudah digunakan secara langsung append, seperti yang ditunjukkan oleh @John Kitchin.

Akhirnya, @lawlist menyebutkan nconc:

nconc adalah fungsi bawaan di 'kode sumber C'.

(nconc & sisanya LISTS)

Gabungkan sejumlah daftar dengan mengubahnya. Hanya argumen terakhir yang tidak diubah, dan tidak perlu daftar.

Apa artinya ini:

(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")

Terima kasih, tetapi sepertinya ia mengembalikan kesalahan jika argumen 2 dan 3 adalah variabel dan bukan daftar eksplisit.
Daniele

1
(setq l1 '("a" "b" "c") l2 '("d" "e" "f")) (concatenate 'list l1 l2)berfungsi ok.
JeanPierre

@Aniele Saya curiga Anda mencoba untuk mengutip variabel, yang berarti mereka tidak dievaluasi dengan nilai daftar mereka. (Yaitu Anda inginkan varnamedaripada 'varname).
phils

Untuk kelengkapan, saya mungkin juga menyebutkan cara non-CL untuk menggabungkan semua jenis urutan dalam Emacs> = 25: seq-concatenate(setelah (require 'seq)), meskipun ini pada gilirannya hanya membungkus cl-concatenate.
Basil
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.