Je me suis donné pour tâche d'écrire une fonction Common Lisp qui concatène deux listes sans utiliser append.

L'entrée Common Lisp (concat-lists '(1 2 3) '(4 5 6)) doit renvoyer (1 2 3 4 5 6)

Même si ma solution semble fonctionner, elle semble ouvertement compliquée

(defun concat-lists(seq1 seq2)
    (cond ((not (null seq1)) (cons (car seq1) (concat-lists (cdr seq1) seq2)))
          (T (cond ((not (null seq2)) (cons (car seq2) (concat-lists seq1 (cdr seq2))))
                   (T nil)))))

Ce que je recherche, c'est une solution plus élégante utilisant reduce où j'utilise seq1 comme valeur initiale, puis j'applique une fonction à chaque élément de seq2, ajoutant ainsi chaque valeur de la liste à seq1. D'une manière ou d'une autre, je reste toujours bloqué en essayant ...

Toute aide ou contribution est très appréciée. Merci!

3
lawrence313 21 nov. 2018 à 01:51

3 réponses

Meilleure réponse
CL-USER 39 > (reduce #'cons
                     '(1 2 3 4 5)
                     :initial-value '(a b c d e)
                     :from-end t) 
(1 2 3 4 5 A B C D E)
5
Rainer Joswig 20 nov. 2018 à 23:46

Je comprends votre exigence de «réduire». et ici d'autres options:

CL a également 'concaténer'

(concatenate 'list '(1 2 3) '(4 5 6))

Il y a aussi l'autre moins compliqué (IMHO), et pas aussi élégant.

(defun concat-lists (list1 list2) (let ((a (copy-list list1)) (b (copy-list list2))) (rplacd (last a) b) a))

Ou

(defun concat-lists (list1 list2) (let ((a (copy-list list1)) (b (copy-list list2))) (nconc a b)))

3
Ala'a Mohammad 24 nov. 2018 à 14:21

La solution de Rainer Joswig est vraiment élégante et simple, et respecte votre demande d'utilisation de reduce.

Si vous voulez voir aussi une solution récursive et simple, alors voici la solution classique:

(defun concat-lists (seq1 seq2)
  (if (null seq1)
      seq2
      (cons (car seq1) (concat-lists (cdr seq1) seq2))))

(concat-lists '(1 2 3) '(4 5 6))
(1 2 3 4 5 6)
4
Renzo 21 nov. 2018 à 15:04