リストを結合する - lisp-cookbook-ja/common-lisp GitHub Wiki

リスト

リストを結合する

リストを結合するには様々な方法があり、それぞれ性質が異なります。

:append:新規のリストが作成されますが、最後の要素はコピーされたものではなく連結されたものになります。

(append '(1 2 3) '(a b c))
;=> (1 2 3 A B C)

(let* ((a (list 1 2 3))
       (b (list 'a 'b 'c))
       (c (list 'i 'ii 'iii))
       (a+b (append a b)))
  (nconc b c) ; bとcを破壊的に連結
  a+b)
;=> (1 2 3 A B C I II III)

:concatenate:すべての要素が連結された新規のリストを返します。

(concatenate 'list '(1 2 3) '(a b c))
;=> (1 2 3 A B C)

(let* ((a (list 1 2 3))
       (b (list 'a 'b 'c))
       (c (list 'i 'ii 'iii))
       (a+b (concatenate 'list a b)))
  (nconc b c) ; bとcを破壊的に連結
  a+b)
;=> (1 2 3 A B C)

:nconc:先頭のリストと後のリストを破壊的に結合します。結果としてリストは破壊的に修正されます。

(nconc (list 1 2 3) (list 4 5 6))
;=> (1 2 3 4 5 6)

(let ((a (list 1 2 3))
      (b (list 'a 'b 'c)))
  (nconc a b)
  (list a b))
;=> ((1 2 3 A B C) (A B C))

少々トリッキーですが、以下のようにしてもリストの連結を実現できます。

`(,@(list 1 2 3) ,@(list 'a 'b 'c))
;=> (1 2 3 A B C)

(バッククオート)の中では,@は評価された上でその場にリストを展開されるので、(,@(list 1 2 3))は(1 2 3)と書いてあるのと同じになります。これを利用すると、

(let ((ls '(a b c)))
  `(1 2 3 ,@ls i ii iii))
; => (1 2 3 A B C I II III)

のように、リストの一部に変数のリストを挿入する場合も簡単に書けます。

FIXME

`(,.(list 1 2 3) ,.(list 4 5 6))
;=> (1 2 3 4 5 6)