Попробуйте мыслить в терминах списков, а не массивов. Вы используете n-й элемент списка, как если бы он был массивом. Вместо этого с помощью do
вы можете просматривать список, каждый раз беря следующий подсписок, то есть отбрасывая первый элемент и получая другой список без этого первого элемента.
(defun fun(list)
(do ((l list (cdr l))
(result nil) )
((null l) (nreverse result))
(if (listp (car l))
(push (length (car l)) result) )))
Оператор do
принимает три аргумента : список переменных, конечное условие и тело l oop. Первая включает в себя имя переменных, их начальное значение и (необязательно), как они меняются с одной l oop на следующую. Например, (l list (cdr l))
говорит, что вы используете переменную l
, начальным значением которой является список ввода, и от одного l oop к следующему он станет CDR самого себя, то есть потеряет свой первый элемент. Конечное условие включает в себя также возвращаемое значение функции. С ((null l) (nreverse result))
мы говорим, что когда переменная l
равна нулю, функция завершится и вернет значение (nreverse result)
. Почему неверс? Потому что мы используем pu sh в теле, которое накапливает значения в неправильном порядке. Наконец, тело говорит функции добавить к result
длину первого элемента l
всякий раз, когда это список.