İki listeyi nasıl birleştirebilirim?


15

Üzgünüm, ama elisp benim en iyim değil. Dizelerin iki listesini bu şekilde birleştirmem gerekiyor:

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

Peki, sipariş önemli değil, bu yüzden bu kodu yazdım:

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

Çalışıyor, ama bunu zaten yapan bir işlev olup olmadığını merak ediyorum.

Bir ipucu? Şimdiden teşekkürler.


4
Elisp kılavuzunun düğüm Oluşturma Listelerine bakın .
Drew

2
appendburada doğru cevap, ama bunu yapmanın başka (yıkıcı) bir yolu olurdu (setcdr (last a) b).
Sean Allred

1
Listeler üzerinde mi çalışıyorsunuz? dash.el ! (-concat '(1) '(2 3) '(4)) ;; => '(1 2 3 4)
Ehvince

Asla add-to-listLisp kodunda kullanmayın (bunu docstring'de söylüyor). Bunun yerine kullanın push.
Radon Rosborough

Yanıtlar:


25

Sadece append komutunu da kullanabilirsiniz.

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

2
Ve,(nconc '("a" "b" "c") '("d" "e" "f"))
hukukçu

1
Oh, evet, gerçekten appendburada daha iyi görünüyor.
JeanPierre

nconc çalışır, ancak listeleri değişkenlerde saklarsanız, bunlar nconc tarafından değiştirilir. Örneğin (let ((a '(1 2 3)) (b' (3 4 5))) (nconc ab) a) bir değişkeni değiştirecektir.
John Kitchin

1
FYI cl-concatenate, appendTYPE olduğunda kullanılır list, bu nedenle her iki cevap da aynı sonucu üretir.
phils

Yess, kesinlikle işi yapıyor. Yardımınız için herkese çok teşekkürler.
Daniele

3

concatenate, 'cl.el' içindeki 'cl-concatenate' için bir takma addır.

(TİP SIRASI'nı bitiştir ...)

TYPE türünde bir sıraya SEQUENCE argümanı ekleyin.

Yani örneğin

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

İçinde tanımlandığından, önce clyapmanız gerekebilir (require 'cl), aksi takdirde cl-concatenatevarsayılan olarak yüklenmiş gibi kullanabilirsiniz .

Ayrıca, @phils'in işaret ettiği gibi , TYPE olduğu zaman cl-concatenateçağrı appendyapar 'list, kaynak 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))))

Bu nedenle, yalnızca listeleri kullanıyorsanız append, @John Kitchin tarafından işaret edildiği gibi doğrudan kullanmak daha kolaydır .

Son olarak, @lawlist şunları söyledi nconc:

nconc, 'C kaynak kodu'nda yerleşik bir fonksiyondur.

(dinlen ve dinlen LİSTELERİ)

İstediğiniz sayıda listeyi değiştirerek birleştirin. Yalnızca son argüman değiştirilmez ve bir liste olması gerekmez.

Bunun anlamı:

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

Teşekkürler, ancak 2. ve 3. bağımsız değişkenler değişken listeleri ve açık listeler değilse bir hata döndürüyor gibi görünüyor.
Daniele

1
(setq l1 '("a" "b" "c") l2 '("d" "e" "f")) (concatenate 'list l1 l2)Tamam çalışıyor.
JeanPierre

@Daniele Değişkenleri alıntılamaya çalıştığınızdan şüpheleniyorum , yani liste değerlerine göre değerlendirilmiyorlar. (örneğin, istediğiniz varnameyerine 'varname).
phils

Tamlık için, Emacs> = 25: seq-concatenate(after (require 'seq)) içindeki herhangi bir diziyi birleştirmenin CL olmayan yolundan da bahsetebilirim , ancak bu sadece sarar cl-concatenate.
Fesleğen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.