Индексаторы объектов. Срезы массивов и строк.
Если данные в программе хранятся в виде нумерованных или именованных списков, например, в массивах, коллекциях, строках или кортежах, то доступ к отдельным элементам таких списков по индексу или по имени будет очень удобен.
«-Индексаторы и инициализаторы – это сладкая парочка, сказал Великий программист,
-Точно, сказал кот Василий, сметана и сливки очень хороши вместе.»
Индексатор - это список значений или выражений в квадратных скобках, позволяющий получить один или несколько элементов из строки, массива, коллекции, кортежа или другого объекта, поддерживающего получение элементов по индексу. В специальных случаях индексатор позволяет получить значение свойства объекта по его идентификатору.
В языке программирования Перфолента.Net индексаторы бывают двух видов:
· Индексаторы, получающие один элемент
· Индексаторы, получающие выборку (срез) элементов
Рассмотрим оба этих варианта подробнее.
Индексаторы, получающие один элемент.
Индексаторы, получающие один элемент, имеют между квадратными скобками либо одно выражение, либо список выражений, разделенных запятыми. Выражения НЕ могут быть пустыми.
Для индексаторов, получающих один элемент, применяются следующие правила:
· Для строк, массивов и кортежей индекс должен быть целым числом, не выходящим за границы имеющихся элементов.
· Числовые индексы могут быть отрицательными и в этом случае отсчет идет от конечного элемента к начальному, причем, индекс -1 соответствует последнему элементу, -2 предпоследнему и т.д..
· Для кортежа индекс должен быть константным выражением, которое может быть вычислено на этапе компиляции.
· Объекты могут поддерживать индексацию, если у них существует свойство Элемент или Item с одним или несколькими параметрами.
· Если индекс в индексаторе задан в виде строки, например, ["Свойство1"], то компилятор попытается найти свойство объекта с таким именем, а если свойство не найдено, то будет сгенерирован вызов свойства Элемент или Item с параметром типа Строка (если оно существует), с фактическим параметром "Свойство1".
· Если индекс в индексаторе задан в виде выражения имеющего тип Строка, например, [ИмяСвойства], то компилятор сгенерирует вызов свойства Элемент или Item с параметром типа Строка (если оно существует) с фактическим параметром ИмяСвойства.
· В индексаторах объектов индексы могут начинаться от единицы, а не от нуля. Это зависит от реализации объекта.
Индексаторы массивов.
//создадим массив
МАС = {100,2,3,4,5,6,7,8}
//получим значение элемента имеющего индекс 0
Зн = МАС[0]
//установим значение элемента имеющего индекс 0
МАС[0] = 1
//примеры для разных допустимых значений индексов
Зн = МАС[3] //четвертое значение с
начала
Зн = МАС[0] //первое значение
Зн = МАС[-1] //первое значение с
конца
Зн = МАС[-2] //второе значение с
конца
//индексы могут быть заданы выражениями
Плюс1 = 1
Минус1 = -1
Зн = МАС[Плюс1 + 1] //третье значение с начала
Зн = МАС[Минус1 - 1] //второе значение с конца
Индексаторы строк.
Строку можно представить, как массив символов, поэтому индексатор для строк применяется так же, как и для массивов, за одним исключением, нельзя устанавливать символы в строке, можно только получать их.
Стр = "АБВГД"
Сим = Стр[3] //четвертый символ с
начала
Сим = Стр[-3] //третий символ с конца
Индексаторы кортежей.
Кортеж можно представить, как массив, у которого каждый элемент может иметь собственный тип. С помощью индексатора можно получить и установить значения элементов кортежа.
//создадим кортеж
Товар = $("Стул",
5)
//получим значения элементов кортежа
Наименование = Товар[0]
Количество = Товар[1]
//установим значения элементов кортежа
Товар[0] = "Стол"
Товар[1] = 10
Индексаторы объектов, имеющих свойство Элемент (Item).
Для того, чтобы пользователь мог создавать свои собственные индексируемые объекты, компилятор языка программирования Перфолента.Net поддерживает специальные свойства с именем Элемент (английский синоним Item). Если у объекта есть такое свойство с одним или несколькими параметрами, то к объекту может быть применен индексатор.
Рассмотрим класс с двумя свойствами Элемент. Свойство Элемент в этом примере перегружено и имеет две реализации, одну с индексом типа Целое и одну с индексом типа Строка, который можно назвать именем или ключом к данным. Свойство с числовым индексом доступно для чтения и записи, а свойство со строковым индексом только для чтения.
&ВидноВсем
Класс КлассСоСвойствомЭлемент
//это свойство вернёт или
установит имя по индексу
&ВидноВсем
Свойство Полное Элемент(Индекс тип Целое) тип Строка
Поле
МасЦел тип Строка[] = {"Вася","Петя","Ира"}
Получить
Возврат МасЦел[Индекс]
КонецПолучить
Установить(Зн тип Строка)
МасЦел[Индекс] = Зн
КонецУстановить
КонецСвойства
//это свойство вернёт номер
месяца по его имени
&ВидноВсем , ТолькоЧтение
Свойство Полное Элемент(Имя тип Строка) тип Целое
Поле
МасМесяцы тип Строка[] = {"","Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"}
Получить
Для Ном = 1 По 12 Цикл
Возврат Ном Если Лев(Имя,3) = МасМесяцы[Ном]
КонецЦикла
Возврат 0
КонецПолучить
КонецСвойства
КонецКласса
Теперь воспользуемся индексаторами, чтобы получать и устанавливать значения индексируемых свойств.
СпецКласс = Новый КлассСоСвойствомЭлемент
//обычные обращения к свойству Элемент без
индексатора
ВыводСтроки СпецКласс.Элемент(2) //вернёт Ира
ВыводСтроки СпецКласс.Элемент("Август")
//вернёт 8
//специальные обращения поддержанные компилятором
ВыводСтроки СпецКласс[1] //вернёт Петя
СпецКласс[1] =
"Пётр" //установим
свойству значение
ВыводСтроки СпецКласс[1] //вернёт Пётр
ВыводСтроки СпецКласс["Январь"] //вернёт
1
Июль = "Июль"
ВыводСтроки СпецКласс[Июль] //вернёт 7
//особый случай, компилятор вызовет свойство Элемент,
//хотя вызов делается без индексатора
ВыводСтроки СпецКласс.Март //вернёт 3
Последний особый случай поддерживается для совместимости с языком 1С. Например, в стандартной библиотеке есть класс Структура, в конструкторе которого создаются именованные свойства. Обращаться к таким свойствам принято без индексатора.
Умнику на заметку: Если класс делается только для Перфоленты, то свойства Элемент достаточно, но если класс будет использоваться в программах написанных на других языках программирования, то желательно добавить свойство Item.
Индексаторы, получающие выборку (срез) элементов.
Индексаторы, получающие выборку (срез) элементов, имеют между квадратными скобками список выражений, разделенных двоеточиями. Выражения могут быть пустыми.
Фактически, такой индексатор реализует цикл выборки значений подобный циклу Для По Шаг.
Формат индексатора такой: [НачальныйИндекс : КонечныйИндекс : ШагВыборки]
Индексаторы, получающие выборку (срез) элементов, поддерживаются только для строк и массивов.
При использовании индексаторов, получающих выборку (срез), применяются такие правила:
· Если пропущен начальный индекс, то он будет равен нулю при положительном шаге или индексу последнего элемента при отрицательном шаге.
· Если пропущен конечный индекс, то он будет равен индексу последнего элемента при положительном шаге или нулю при отрицательном шаге.
· Если пропущен шаг выборки, то он будет равен единице.
· Если начальный или конечный индексы отрицательны, то отсчет позиции такого индекса будет идти от последнего элемента, который имеет индекс -1.
· Если шаг отрицательный, то фактически выборка будет идти в направлении от конца к началу строки, массива или объекта, т.е. для правильной работы среза начальный индекс должен быть больше конечного.
· Начальный и конечный индексы берутся включительно. Внимание, в других языках программирования конечный индекс может браться НЕ включительно. В языке Перфолента обе границы диапазона всегда включаются в диапазон (редкие исключения из этого правила оговорены в документации)!
· Для строки или массива индексатор получающий выборку (срез) всегда создает новый экземпляр строки или массива соответственно.
· Выборку (срез) можно получить только для одномерного массива, многомерные массивы не поддерживаются.
Примеры индексаторов получающих выборку (срез): [:], [::], [0:5], [0:5:1], [5:0:-1], [-1:0:-2], [ИндНач:ИндКон:Шаг], [А:Б]
Рассмотрим практические примеры.
Примеры срезов со строками.
При работе со строками индексаторы выборки (среза) возвращают результат типа Строка.
ТСтр = "АБВГДИЕЁЖЗ" //тестовая
строка
//с шагом 1, аналоги функций Лев(), Сред(), Прав()
ВыводСтроки ТСтр[:]
//копия строки
ВыводСтроки ТСтр[::]
//копия строки
ВыводСтроки ТСтр[::-1] //переворот строки, от
конца к началу
ВыводСтроки ТСтр[:2] //первые три элемента
//ВыводСтроки ТСтр[:20] //ошибка - выход за границу
//ВыводСтроки ТСтр[20:] //ошибка - выход за границу
ВыводСтроки ТСтр[:-3] //без последних двух
символов
ВыводСтроки ТСтр[4:-1:2] //каждый второй символ начиная
с пятой буквы до последней
ВыводСтроки ТСтр[-4:3] //разворот начиная с четвертой от конца до четвёртой
сначала
ВыводСтроки ТСтр[:4]+" : "+ТСтр[5:] //разбили строку на 2
части
//с шагом не равным 1, аналог цикл Для
ВыводСтроки ТСтр[:4:2] // берем от начала до пятого символа каждый второй символ
ВыводСтроки ТСтр[:-1:3] // берем от начала до конца каждый третий символ
ВыводСтроки ТСтр[::2] // берем от начала до
конца каждый второй символ
ВыводСтроки ТСтр[-1:0:-2] // берем от конца до
начала каждый второй символ
ВыводСтроки ТСтр[-1:0:-1] // развернули строку,
от последнего символа до первого с шагом -1
Примеры срезов с массивами и коллекциями.
С массивами индексаторы выборки (среза) работают аналогично работе со строками. Возвращаемый результат является массивом того же типа, что и у исходного массива.
МА = {0,1,2,3,4,5,6,7,8,9}
Результат = МА[:]
//копия массива
Результат = МА[::]
//копия массива
Результат = МА[::-1] //переворот массива, от
конца к началу
Результат = МА[::2] //от начала до конца
каждый второй элемент
Результат = МА[::-2] //от конца до начала
каждый второй элемент
Результат = МА[-1:0:-2] //от конца до начала
каждый второй элемент
Результат = МА[2:5] //с третьего элемента по шестой
Результат = МА[:-3] //без последних двух
элементов
Результат = МА[4:-1:1] //начиная с пятого
элемента до последнего
Результат = МА[-6:7:1] //начиная с шестого
элемента от конца до восьмого от начала
Вывод: Индексаторы позволяют получить данные объекта по индексу, имени или ключу. Для строк и массивов индексаторы так же позволяют делать выборки (срезы) данных.
Сергей Рогаткин
К началу статьи
Предыдущая статья:
Инициализаторы объектов
Вернуться в раздел:
Синтаксис языка Перфолента