だから私はlispでリストをフラット化することを検討してきました。
しかし、私がやりたかったのは、リストをレベルごとにフラット化することです。
だから持っている代わりに
(flatten '(a (b (d (g f))) e)) = (a b d g f e)
が欲しいです
(flatten '(a (b (d (g f))) e)) = (a b (d (g f )) e )
この人をどうやってやるのかについて何か考えはありますか?
感謝します=)
たとえば、次のようなことができます。
(defun fletten-level (tree)
(loop for e in tree
nconc
(if (consp e)
(copy-list e)
(list e))))
(fletten-level '(a (b (d (g f))) e))
;; (A B (D (G F)) E)
これにより、元のツリーの最上位のブランチがループされ、ブランチがリーフであるかどうか、そのリーフ、およびブランチに他の2つのブランチがある場合は、最初のリーフと残りのブランチの両方を含む新しいリストが作成されます。
編集:申し訳ありませんが、実際には初めては良くありませんでしたが、今は修正する必要があります。
EDIT2:私がほとんど混乱したからといって。(cons (car e) (cdr e))
基本的にはただ言うのと同じなので、少し奇妙に見えますe
。ただし、nconc
これによりconsesが破壊的に変更されることに気付いたので、この方法である必要があります(つまり、古いconsセルを再利用するのではなく、連結する新しいconsセルを作成します)。
EDIT3:うわー...実際にはcopy-list
、元のリストをこのように変更するため、そうである必要があります。
これが私の迅速で汚い非破壊的なバージョンです:
(defun flatten-level (tree)
(cond ((null tree) ())
((consp (car tree)) (concatenate 'list (car tree)
(flatten-level (cdr tree))))
(t (cons (car tree) (flatten-level (cdr tree))))))
これは、ツリーをウォークする再帰関数であり、各要素について、それがconsされた要素である場合、それをツリーの残りの部分に連結し、平坦化します。