Доступ к элементам коллекций
Итак, оператором:
BookList: = New(PCollection, Init(50.10));
Мы объявили о создании коллекции, а операторами:
Insert(New(PBook, Init(…)))
Наполнили эту коллекцию нужными элементами. Как осуществить доступ к элементам коллекции? Для этого можно использовать несколько способов.
Во-первых, к любому элементу коллекции можно обратиться по его порядковому номеру (индексу). В отличие от массивов Турбо Паскаля, индексы которых могут иметь произвольные границы, коллекции индексируются целыми числами в диапазоне от 0 до Count-1 (Count – общее количество элементов в коллекции). Любая коллекция имеет поле Count, которое указывает текущую длину коллекции. Чтобы по индексу получить доступ к нужному элементу, используется метод At, который возвращает указатель на элемент.
Например, нам требуется вывести на экран содержимое тех записей нашего каталога, которые соответствуют 1991 году издания. Тогда вместо точек в конце программы, показанной на с.426, следует вставить оператор:
PrintYear(BookList,1991);
Кроме того, в раздел описаний программы добавим две новых процедуры:
Procedure PrintItem(A,T,PB: String; Y,P: Word);
{Выводит на экран элемент коллекции}
begin
WriteLn(A); WriteLn(' ',Т):
WriteLnC ',РВ,', ',Y,', ',Р)
end; {PrintItem}
Procedure PrintYear(BookList: PCollection; Y: Word);
{Выводит на экран издания нужного года выпуска}
var
Book: PBook;
k: Integer;
begin
WriteLn;
for k: = 0 to pred(BookList.Count) do
begin
Book: = BookList.At(k);
with Book do if Year = Y then
PrintItem(Autor,Title,PubHouse,Year,Pages)
end
end; {PrintYear}
В процедуре PrintYear организуется счетный цикл от 0 до pred (TCollection.Count). С помощью оператора:
Book: = BookList.At(k);
В переменную Book помещается указатель на элемент коллекции с индексом k. Именно здесь обеспечивается полиморфизм коллекций: метод At возвращает нетипизированный указатель, который Вы можете интерпретировать нужным Вам образом. Однако здесь же таится источник трудно обнаруживаемых ошибок: в левую часть оператора присваивания можно поместить указатель любого типа и тип этого указателя может не соответствовать типу k-гo элемента коллекции.
Отметим, что обращение к методу At с индексом, выходящим за границы коллекции, активизирует вызов метода TCollection.Error, который по умолчанию аварийно завершает исполнение программы (подробнее см. п. 17.6).
Помимо использования метода At коллекции обеспечивают доступ к трем итерационным методам, которые могут оказаться весьма удобными. Метод ForEach осуществляет некоторую заранее заданную операцию сразу над всеми элементами коллекции, а методы FirstThat и LastThat отыскивают в коллекции первый элемент, удовлетворяющий некоторому опять же заранее заданному критерию поиска: FirstThat ищет от начала коллекции к ее концу, a LastThat – в обратном направлении.
