Доступ к элементам коллекций
Итак, оператором:
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 – в обратном направлении.