[Scheme ]

Списки в Scheme являются главной "рабочей лошадкой" языка.

(list obj1 ... objn)

Списки создаются с помощью функции "list", эта функция может принимать любое количество аргументов, если аргументов нет то функция возвратит пуской список:

(list 1 2 "три" "четыре" "пять")

->(1 2 три четыре пять)

(list)

->()


(length list)

Для определения длинны списка используется функция "length", что означает "длинна":

(length (list 1 2 3 4))

->4

(length (list))

->0


(list-ref list n)

А эта функция используется для доступа к определённому аргументом "n" элементу списка.

(list-ref (list "zero" "one" "two" "three") 1)

->one

->(list-ref (list "zero" "one" "two" "three") 0)
->zero


(append list ... obj)

А эта функция возвращает новый список с добавленым в его конец элеменом, этот элемент должен быть списком, иначе вы в качестве результата мы получим так называемую "пару", этот тип данных мы обсудим в другой главе.

(define lst (list 1 2 3 4))
(append lst (list 55 666))

->(1 2 3 4 55 666)

lst
->1 2 3 4

Списочный предикат:

(list? lst)

->#t

Как мы увидели из предыдущего примера, изначальный список "lst" не изменился.

(car lst)

Эта функция возвращает первый элемент списка, не внося никаких изменение в изначальный список:

(define lst (list 1 2 3 4))

(car lst)

->1

(number? (car lst))

->#t

(list? (car lst))

->#f


(cdr lst)

А эта функция возвращает список начинающийся со второго элемента списка-аргумента.

(сdr lst)

->(2 3 4)

(cdr (cdr lst))

->(3 4)

(cdr (cdr (cdr lst)))

->(4)

(cdr (cdr (cdr (cdr lst))))

->()

(list-tail list n)

Вызов этой функции выдаёт такой же результак как и вызов n-го количества взаимовложенных функций "cdr".

(cdr lst)

(list-tail lst 1)

->(2 3 4)

(cdr (cdr lst))

(list-tail lst 2)

->(3 4)

(cdr (cdr (cdr lst)))

(list-tail lst 3)

->(3 4)

(cdr (cdr (cdr lst)))

(caar lst) -- тоже самое что и (car (car lst)) или (list-tail lst 2)
(caaar lst) -- тоже самое что и (car (car (car lst))) или (list-tail lst 3)
(caaaar lst) -- тоже самое что и (car (car (car (car lst)))) или (list-tail lst 4)

(cddr lst) -- тоже самое что и (cdr (cdr lst))
(cdddr lst) -- тоже самое что и (cdr (cdr (cdr lst)))
(cddddr lst) -- тоже самое что и (cdr (cdr (cdr (cdr lst))))


(append list ... obj) append returns a new list consisting of the elements of the first list
car (Contents of the Address part of Register number) and cdr (Contents of the Decrement part of Register number)

set-car!

(set-car! pair obj)

Эта процедура заменяет первый элемент списка на "obj".

(define lst (list 1 2 3 4 5))

(set-car! lst 111)

lst

->111 2 3 4 5


(set-cdr! pair new-cdr

А эта функция меняет весь "cdr" на "new-cdr"

(set-cdr! lst (list 222 333 444))

->(111 222 333 444)

Обратите внимание на то, что в качестве аргумента "new-cdr" мы используем список, иначе в результате мы получим пару.

(reverse lst)

Возвращает новый список, в котором все элементы находятся в обратном порядке

(reverse (list 1 2 3 4 5))

->(5 4 3 2 1)


(memq obj list)
(memv obj list)
(member obj list)

Эти функции работают следующим образом -- список просматривается с начала до конца и если аргумент "obj" совпадает с элементом списка, то возвращается хвост начинающийся с этого элемента, если совпадений не найдено, то возвращается #f. Функция "memq" использует для сравнения функцию "eq?", "memv" -- "eqv?", "member" -- "equal?"

(define lst (list 1 2 3 4 5))

(memq 3 lst)

(3 4 5)


Следующии процедуры определены в модуле "lists", который можно подключить выражением:

(import (rnrs lists))

(memp procedure list)

Функция "memp" работает анологично предыдущим трём функциям, только в качестве функции для сравнения используется аргумент "procedure"

(define lst (list 1 2 3 4 5))

(define (my-comparator obj) (eq? obj 4))

(memp my-comparator lst)

->(4 5)

(remv obj list)

(remq obj list)

(remove obj list)

(remp proc list)

Каждая из этих процедур возвращает новый список элементов списка-аргумента, которые не соответствуют заданному условию.

(remq 3 (list 1 2 3 4 5))

->(1 2 4 5)


Сортировка списков производится с помощью функции "(list-sort proc list)", которая определенна в модуле "(rnrs sorting)", эта функция возвращает новый список, в котором элементы выстроенны в соответствии с функцией "proc".

(import (rnrs sorting))
(list-sort  > lst)

->(5 4 3 2 1)

lst

->(1 2 3 4 5)