Come concatenare due elenchi?


15

Siamo spiacenti, ma elisp non è il massimo. Ho bisogno di combinare due elenchi di stringhe in questo modo:

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

Bene, l'ordine non è importante, quindi ho scritto questo codice:

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

Funziona, ma mi chiedo se c'è già una funzione che lo fa.

Qualche idea? Grazie in anticipo.


4
Vedi il nodo Elenchi di costruzione del manuale Elisp.
Disegnò

2
appendè la risposta corretta qui, ma un altro modo (distruttivo) per farlo sarebbe (setcdr (last a) b).
Sean Allred,

1
Stai lavorando su liste? dash.el ! (-concat '(1) '(2 3) '(4)) ;; => '(1 2 3 4)
Ehvince,

Non usare mai add-to-listnel codice Lisp (dice questo nel docstring). Invece, usa push.
Radon Rosborough,

Risposte:


25

Puoi anche semplicemente usare append.

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

2
E,(nconc '("a" "b" "c") '("d" "e" "f"))
elenco delle leggi

1
Oh, sì, appendsembra davvero meglio qui.
JeanPierre,

nconc funziona ma, se si memorizzano elenchi in variabili, verranno modificati da nconc. Ad esempio (let ((a '(1 2 3)) (b' (3 4 5))) (nconc ab) a) modificherà la variabile a.
John Kitchin,

1
FYI cl-concatenateutilizza appendquando TYPE è list, quindi entrambe le risposte producono lo stesso risultato.
phils

Sì, sicuramente fa il lavoro. Mille grazie a tutti per il vostro aiuto.
Daniele,

3

concatenate è un alias per "cl-concatenate" in "cl.el".

(concatena SEQUENZA DI TIPO ...)

Concatenare, in una sequenza di tipo TYPE, l'argomento SEQUENCEs.

Quindi per il tuo esempio

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

Poiché è definito in cl, potrebbe essere necessario (require 'cl)innanzitutto, altrimenti è possibile utilizzare cl-concatenatequale sembra essere caricato per impostazione predefinita.

Inoltre, come sottolineato da @phils cl-concatenatechiama solo appendquando TYPE è 'list, ecco la fonte da 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))))

Quindi, se stai usando solo le liste, è più semplice da usare direttamente append, come sottolineato da @ John Kitchin.

Infine, @lawlist ha menzionato nconc:

nconc è una funzione integrata in "codice sorgente C".

(nconc & rest LISTE)

Concatena un numero qualsiasi di elenchi modificandoli. Solo l'ultimo argomento non viene modificato e non è necessario che sia un elenco.

Cosa significa:

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

Grazie, ma sembra che restituisca un errore se il secondo e il terzo argomento sono variabili e non elenchi espliciti.
Daniele,

1
(setq l1 '("a" "b" "c") l2 '("d" "e" "f")) (concatenate 'list l1 l2)funziona bene
JeanPierre,

@Daniele Sospetto che stavi cercando di citare le variabili, il che significa che non vengono valutate in base ai loro valori di elenco. (cioè vuoi varnamepiuttosto che 'varname).
phils

Per completezza, potrei anche menzionare il modo non-CL di concatenare qualsiasi tipo di sequenza in Emacs> = 25: seq-concatenate(dopo (require 'seq)), sebbene questo a sua volta si concluda cl-concatenate.
Basil
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.