(loop for a in l appending (g a))
私の時代には、私たちが書いた代わりに(mapcan #'g l)
。(apply #'append (mapcar #'g l))
多かれ少なかれ同等です:
(defun flatten (l)
(if l
(if (atom l)
(list l)
(mapcan #'flatten l))))
では、この場合はどういう意味ですか?を呼び出すと想像してください(flatten (list 1 2 3 4 5))
。つまり、引数リストにはアトムしかありません。そのリスト内の各アトムはリストに囲まれます-などのようにシングルトン リスト(1) (2)
になります。その後、それらはすべて一緒に追加され、元のリストが返されます:
( 1 2 3 4 5 )
( (1) (2) (3) (4) (5) )
( 1 2 3 4 5 )
したがって、アトムのリストを平坦化することは同一性操作です (Common LISP では、それは です#'identity
)。ここで、いくつかのアトムとアトムのリストを含むリストをフラット化することを想像してください。繰り返しますが、リストの各要素は によって変換され、すべて一緒に追加されます。先ほど見たように、アトムのリストはそれ自体のままです。アトムはそれぞれリストに含まれます。したがって、追加すると、ネストされたリストの両方のレベルにあったすべてのアトムが返され、フラット化されます。flatten
( 11 12 (1 2 3 4) 13 )
( (11) (12) (1 2 3 4) (13) )
( 11 12 1 2 3 4 13 )
などなど、より多くのネストのレベルについても同様です。
NIL
リスト内の要素としての s は問題を引き起こします。NIL
は空のリストであり、空のリストには何も含まれていないため、何も提供しないでください。しかしNIL
、原子でもあります。そのため、それをシングルトン リストに含めないように、特別なケースを作成します。そのままにしておくと、追加されたときに消えてしまいます。