Содержание

Назад: Программный код

Массивы

Зачем нужны массивы

Иногда нам становится неудобно хранить множество однотипных значений в разных переменных. Например, у нас есть двадцать "железных мечей" и для каждого мы прописали урон в двадцати разных переменных:

меч_железный_1 = 23
меч_железный_2 = 34
меч_железный_3 = 27
...
меч_железный_19 = 7
меч_железный_20 = 41

Даже для того, чтобы просто вывести на экран данную характеристику для каждого меча, нам придётся написать двадцать строчек кода, почти ничем не отличающихся:

*pl "Меч железный №1. Урон: "+$str(меч_железный_1)
*pl "Меч железный №2. Урон: "+$str(меч_железный_2)
*pl "Меч железный №3. Урон: "+$str(меч_железный_3)
...
*pl "Меч железный №19. Урон: "+$str(меч_железный_19)
*pl "Меч железный №20. Урон: "+$str(меч_железный_20)

Всё бы ничего, но что если нам нужно найти среди всех этих переменных ту, которая содержит максимальное число (мы ведь хотим пользоваться самым хорошим мечом)? Тут нам придётся городить огромную конструкцию условий, которая сравнивает каждую переменную со всеми остальными, и объём необходимого нам кода возрастает многократно.

Да, есть некоторые варианты решения этих двух задач без использования массивов, но они тоже весьма сложны. Куда как проще работать с однотипными данными, если они представлены в форме массива.

Если переменную мы можем вообразить в виде отдельной маленькой коробки, в которую можно положить лишь одно значение, то массив — это большой шкаф, со множеством пронумерованных ящиков (ячеек), в каждый из которых мы можем положить по одному значению.

Что такое массивы

Массив - в QSP это последовательный набор значений, записанных под одним общим именем.

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

Имена переменных и имена массивов записываются похожим образом. Единственное отличие в том, что когда мы обращаемся к массиву — возле его имени в квадратных скобках ставим номер одной из ячеек.

меч_железный[0] = 23 & ! нумерация ячеек массива начинается с нуля
меч_железный[1] = 34
меч_железный[2] = 27
...
меч_железный[18] = 7
меч_железный[19] = 41 & ! значение для двадцатого меча лежит в ячейке под номером 19

Из этого примера видно, чтобы записать значение в отдельную ячейку массива, мы должны:

В нашем примере массив называется "меч_железный", а в квадратных скобках мы указываем номера ячеек этого массива.

Создание массива

Записывая значения хотя бы в одну ячейку массива, мы тем самым создаём (инициализируем) весь массив.

Типы данных в массивах

Массив можно представить себе как список значений. Если вам нужно хранить только одно значение, достаточно обычной переменной, но если вам нужно сохранить множество значений, как некий список, то обязательно используйте массив. Например, вы можете вести список имён всех встреченных персонажей:

$встреченные_неписи[0] = "Домовёнок Нафаня"
$встреченные_неписи[1] = "Девочка Оля"
$встреченные_неписи[2] = "Лариса Петровна"
$встреченные_неписи[3] = "Баба Яга"

В данном примере мы помещали в массив строковые значения.

Чтобы поместить в ячейку массива строковое значение, нужно поставить перед именем массива символ $.

То же самое и в случае, когда мы хотим получить значение из ячейки массива:

если мы хотим получить строковое значение, нужно поставить символ $ перед именем массива.

И точно так же это работает для числовых значений и кортежей:

Примеры:

$яблоки[0]='антоновка'
$яблоки[1]='белый налив'
$яблоки[2]='астраханское'
$яблоки[3]='ранетка'
$яблоки[4]='симиренко'

сорт_яблока[0] = 1
сорт_яблока[1] = 2
сорт_яблока[2] = 4

%сорта_в_корзине[0] = [1, 4]
%сорта_в_корзине[1] = [2, 4]
%сорта_в_корзине[2] = [1, 2]

*pl $яблоки[сорт_яблока[номер_яблока]]

В одном массиве допускается хранить значения любых типов, однако строго рекомендуем хранить в одном массиве только значения одного типа: либо строковые, либо числовые, либо кортежи, — во избежание возможных багов.

В одной ячейке массива можно хранить значение только одного типа! Если вы запишете в ячейку, которая хранит строку, числовое значение — это числовое значение "затрёт" строковое. И точно так же со значением любого другого типа.

Обработка массивов

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

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

меч_железный[0] = 23 & ! нумерация ячеек массива начинается с нуля
меч_железный[1] = 34
меч_железный[2] = 27
...
меч_железный[18] = 7
меч_железный[19] = 41 & ! значение для двадцатого меча лежит в ячейке под номером 19

! выводим на экран список с помощью цикла
loop i=0 while i<20 step i+=1:
  *pl "Меч железный №<<i+1>>. Урон: "+$str(меч_железный[i])
end

В этом примере для вывода на экран всех значений из всех двадцати ячеек массива нам потребовалось написать всего три строчки кода.

А вот как выглядит поиск железного меча с наибольшим значением урона:

pos = arrpos('меч_железный', max('меч_железный'))
*pl "Наибольший урон имеет Меч железный №<<pos+1>>: "+$str(меч_железный[pos])

В обоих примерах вместо указания конкретного номера ячейки массива, при получении данных из массива, мы подставляли значение переменной. Именно эта возможность позволяет так легко и быстро обрабатывать множество данных в массивах, и делает работу с ними более удобной, чем с обычными переменными.

Индексирование элементов массива

Выше мы писали, что ячейки массивов нумеруются подряд, начиная с нуля, и нумерация эта не прерывается. Номер ячейки массива называется числовым индексом ячейки массива.

! ячейки массивов индексируются через числа
$любимый_сорт[3] = $яблоки[2]
любимое_число[19] = 5
$item_loc[0] = 'лес'

Важно! Настоятельно не рекомендуем использовать большие числовые индексы без необходимости.

QSP позволяет создавать для элементов массивов не только числовые, но и строковые индексы. Иными словами массивы могут индексироваться через строки. Примеры:

! ячейки массивов индексируются через строки
$любимый_сорт['Иван'] = $яблоки[2]
любимое_число['Алексей'] = 5
$item_loc['палка'] = 'лес'

Регистр символов в строковом индексе массива значения не имеет:

$любимый_сорт['иван'] = 'Антоновка'
*pl $любимый_сорт['ИВАН'] & ! выведет строку Антоновка

Есть небольшая хитрость в том, как назначаются строковые индексы ячейкам массивов. Когда вы инициализируете (создаёте, объявляете) новую ячейку массива со строковым индексом, происходит следующее:

Поэтому, если вы создаёте ячейку со строковым индексом, вы можете получать из неё значения в том числе и по числовому индексу:

яблоки['у Паши']=37
яблоки['у Даши']=19
яблоки['у Лёши']=11
*pl яблоки[0] & ! выведет на экран число 37
*pl яблоки[1] & ! выведет на экран число 19
*pl яблоки[2] & ! выведет на экран число 11

Настоятельно рекомендуется использовать для индексирования или только числовые, или только строковые индексы.

Строковые индексы позволяют обойти ограничение массивов на начало нумерации только с нуля:

$item['-2']='Палка'
$item['-1']='Дрель'
$item['0']='Радиоактивный пепел'

Многомерные массивы

Начиная с плееров версии 5.8.0 вы можете создавать в QSP многомерные массивы.

Упрощённый доступ к ячейкам массивов

На самом деле каждая переменная в QSP является массивом, состоящим из одной единственной ячейки:

яблоки = 0
!эквивалентно
яблоки[0] = 0

то есть, если мы создаём переменную с именем "яблоко", мы тем самым создаём массив с именем "яблоко", состоящий из одной ячейки.

Таким образом вы всегда можете получить или присвоить данные нулевой ячейке массива, просто указав его имя:

! присваиваем нулевой ячейке массива '$COUNTER' строковое значение
$usercom = 'строка_ввода'
*pl $usercom[0] & ! проверяем
! присваиваем нулевым ячейкам массивов red, green, blue значения
set red[0], green[0], blue[0] = 234,198,77
*pl "red: <<red>>, green: <<green>>, blue: <<blue>>" & ! проверяем

Существует упрощённый синтаксис чтения последнего и добавления нового элемента в массив. Для этого квадратные скобки пишутся без указания индекса:

Функции и операторы для работы с массивами

Так же см. ARRPACK и UNPACKARR в разделе "Кортежи"

Вперёд: Строки