Поскольку вы на самом деле не дали спецификации того, для чего предназначена ваша программа, вот что-то, что превращает вашу структуру в ту, которую вы хотите, в предположении, что что-то еще дает вам эту структуру.
Ваша структура - это минусы, автомобиль которых либо нулевой, если структуры больше нет, либо структура.CDR структурного списка одноэлементных списков, и нам нужны эти элементы.
Я назвал структуру BLOB-TREE, и каждый CDR является BLOB.
(defun blob-to-list (blob)
;; a blob is a list of single-element lists, and we want the elements
(mapcar (lambda (e)
(assert (and (listp e) (null (rest e))))
(first e))
blob))
(defun blob-tree-to-list (blobs)
;; BLOB-TREE is some horrible tree: what we need to do is split it into
;; its car & cdr, and then convert the cdr to a list with
;; blob-to-list, then recurse on the car, until we get a null car.
(labels ((extract-blobs (remains accum)
(etypecase remains
(null accum)
(cons
(extract-blobs (car remains) (cons (blob-to-list (cdr remains))
accum))))))
(extract-blobs blobs '())))
Исейчас
> (blob-tree-to-list '(((NIL (B) (C) (B)) (A)) (E) (G)))
((b c b) (a) (e g))
Я скорее сомневаюсь, что это именно то, что вы хотите сделать.
В качестве проверки я написал функцию, которая принимает список в нужной вам форме ипревращает его в блоб-дерево.Вы можете использовать это, чтобы проверить, что все происходит в правильном направлении.
(defun list-to-blob-tree (l)
(labels ((list-to-blob (es)
(mapcar #'list es))
(build-blob-tree (tail accum)
(if (null tail)
accum
(build-blob-tree (rest tail)
(cons accum (list-to-blob (first tail)))))))
(build-blob-tree l '())))
Если вы действительно хотите иметь дело с такими вещами (что в реальной жизни вам иногда приходится), хорошийПодход состоит в том, чтобы написать набор функций доступа, которые позволят вам абстрагироваться от непонятных структур данных, которые вам были предоставлены.
В этом случае мы можем написать функции для работы с BLOB-объектами:
;;; Blobs are lists are lists where each element is wrapped in a
;;; single-element list
(defun blob->element-list (blob)
;; a blob is a list of single-element lists, and we want the elements
(mapcar (lambda (e)
(assert (and (listp e) (null (rest e))))
(first e))
blob))
(defun element-list->blob (list)
;; turn a list into a blob
(mapcar #'list list))
И еще один набор функций для работы с деревьями BLOB-объектов, которые (оказывается) - это просто списки, построенные с заменой их машин и CDR:
;;; Blob trees are lists, built backwards
;;;
(deftype blob-tree ()
'(or cons null))
(defconstant null-blob-tree nil)
(defun blob-tree-car (blob-tree)
(cdr blob-tree))
(defun blob-tree-cdr (blob-tree)
(car blob-tree))
(defun blob-tree-cons (car cdr)
(cons cdr car))
(defun blob-tree-null-p (blob-tree)
(null blob-tree))
В обоих случаях я написал только те функции, которые мне нужны: есть читатели, но нет писателей, например.
И теперь мы можем написать функции, которые нам нужны в терминах этих абстракций:
(defun blob-tree->element-list (blob-tree)
(labels ((extract-blobs (tree accum)
(assert (typep tree 'blob-tree))
(if (blob-tree-null-p tree)
accum
(extract-blobs (blob-tree-cdr tree)
(cons (blob->element-list (blob-tree-car tree))
accum)))))
(extract-blobs blob-tree '())))
(defun element-list->blob-tree (el)
(labels ((build-blob-tree (elt accum)
(if (null elt)
accum
(build-blob-tree (rest elt)
(blob-tree-cons
(element-list->blob (first elt))
accum)))))
(build-blob-tree el null-blob-tree)))
Это означает, что если представление изменяет эти два мягковолосатые функции не делают.