Введение в Автолисп

Рыжиков Роман Клавдиевич

5. РАБОТА СО СПИСКАМИ

 

 

Все обрабатываемые данные Автолисп делит на две большие группы: атомы и списки. Под атомом понимается некоторая программная единица, рассматриваемая Автолиспом как единое целое. Список, по определению разработчиков [5], представляет собой группу связанных элементов, разделенных пробелами и заключенных в скобки. Он служит эффективным средством хранения связанных величин и может содержать данные любого типа. При необходимости идентификации элемента с атомом или списком можно воспользоваться одной из двух функций:

(atom элемент ) возвращает nil, если элемент является списком, и T - в противном случае,

(listp элемент ) возвращает Т., если элемент является списком, и nil - в противном случае. Примеры:

(setq а ‘(х у z))

(atom ‘а) возвращает T,

(atom а) возвращает nil,

(atom ‘(a b c)) возвращает nil,

(listp '(abc)) возвращает T,

(listp ‘а) возвращает nil,

(listp 4.38) возвращает Т.

 

5.1. Формирование списков

Основной функцией формирования списков является list. Эта функция принимает любое количество выражений и собирает их в один список. Очень часто она используется для указания координат точки в двух- или трехмерном пространстве. В общем случае формат функции выглядит следующим образом:

(list выражение ... ) .

Примеры списков:

(list a b с) возвращает (А В С),

(list a (b с) d) возвращает (А (В С) D),

(list 2.1 4.8) возвращает (2.1 4.8).

Если ни одно из выражений не содержит переменных или неопределенных элементов, функция list может быть заменена функцией quote. Для Автолиспа эквивалентны выражения

(list 2.1 4.8) и ‘(2.1 4.8).

(append список ... ) . Функция принимает любое количество списков и объединяет их в один.

(append ‘(a b) ‘(с d)) возвращает (А В С D),

(append ‘((a) (b)) ‘((с) (d))) возвращает ((A) (B) (C) (D)).

(cons новый_элемент список ) . Функция принимает новый элемент в качестве первого, добавляя его к уже существующему списку, и возвращает новый список.

(cons ‘a ‘(b с d)) возвращает (А В С D),

(cons ‘(a) ‘(b с d)) возвращает ((A) В С D).

Если место аргумента список занимает атом, функция формирует уже упоминавшуюся ранее точечную пару.

(cons ‘а 2) возвращает (А . 2).

(reverse список ) . Функция обращает список, располагая его элементы в обратном порядке.

(reverse '((a) b c)) возвращает (С В (A)).

(subst новый_элемент старый_элемент список ) . Функция отыскивает в списке старый_элемент и возвращает копию списка, в которой старый_элемент заменен новым. Если старый_элемент в списке отсутствует, список возвращается без изменений.

(setq sample ‘(a b (с d) b))

(subst ‘qq ‘b sample) возвращает (A QQ (С D) QQ),

(subst ‘qq ‘(c d) sample) возвращает (A B QQ В),

(subst ‘qq ‘x sample) возвращает (A B (C D) B).

(length список ) возвращает число элементов в списке.

(length ‘(a b с d)) возвращает 4,

(length ‘(a b (с d))) возвращает 3,

(length ‘()) возвращает 0.

(mapcar функция список1 ... списокN ) . Функция mapсаr просматривает списки, совершает над ними операции, предписанные функцией и возвращает результат.

(setq a 10 b 20 с 30)

(mapcar '1+(list a b c)) возвращает (11 21 31),

т.е., использование функции mapcar эквивалентно использованию последовательно трех выражений:

(1+a),

d+b),

(1+c).

 

5.2. Извлечение данных из списка

Двумя основными функциями, позволяющими извлечь из списка хранящиеся в нем данные, являются car и cdr.

(car список ) . Функция возвращает первый элемент списка . Если список пуст, возвращается nil.

(car ‘(a b c)) возвращает А,

(car ‘((a b) c)) возвращает (А В),

(car ‘()) возвращает nil.

(cdr список). Функция возвращает список, за исключением первого элемента. Если список пуст, возвращается nil.

(cdr ‘(a b c)) возвращает (В С),

(cdr ‘((a b) c)) возвращает (С),

(cdr ‘()) возвращает nil.

Следует иметь в виду, что функция cdr возвращает список, поэтому при попытке извлечь с ее помощью координату “у” двумерной точки может возникнуть конфликтная ситуация. Действительно,

(cdr '(x y)) возвращает (Y),

и из этого списка, состоящего из одного элемента, нужно этот элемент извлечь, т.е., совершить операцию:

(car ‘(у)).

Таким образом, извлечение координаты “у” должно быть осуществлено следующей операцией:

(саг (cdr ‘(х у))).

Для вкладываемых друг в друга функций car и cdr используется сокращенная запись:

(cadr список) эквивалентно (car (cdr список)),

(caar список) эквивалентно (car (car список)),

(cadar список) эквивалентно (car (cdr (car список)))

и так далее. Полная глубина проникновения сцепленных функций car - cdr в обрабатываемый список достигает четырех уровней. Охватывающие крайние возможности метода функции выглядят как (caaaar) и (cddddr). Полный перечень функций можно найти в соответствующей литературе [5, 6].

В качестве примера приводится последовательное извлечение координат точки в трехмерном пространстве:

(setq pt ‘(3.2 5.6 8.4))

(car pt) возвращает 3.0,

(cadr pt) возвращает 5.6,

(caddr pt) возвращает 8.4.

Ранее упоминалось об особом виде списка - точечной паре. Это единственный вид списка, из которого функция cdr извлекает не список, а атом. Например, из точечной пары (62 . 2)

(car (62 . 2)) возвращает 62,

(cdr (62 . 2)) возвращает 2.

(member выражение список ) . Функция просматривает список в поисках выражения и возвращает часть списка , начинающуюся с выражения .

(member ‘с ‘(a b с d e)) возвращает (С D E),

(member ‘q ‘(a b с d e)) возвращает nil.

(nth номер список ) . Функция возвращает элемент списка с указанным порядковым номером.

(nth 2 ‘(a b с d e)) возвращает С,

(nth 5 ‘(a b с d e)) возвращает nil.

Следует иметь в виду, что первому элементу списка соответствует нулевой номер.

(assoc элемент список ) . Функция просматривает список в поисках элемента как ключевого слова и извлекает ассоциированный элемент. Например, при обработке выражения

(setq a ‘((name box) (width 3) (size 4.7) (depth 5)))

(assoc ‘size a) возвращает (SIZE 4.7),

(assoc ‘length a) возвращает nil