Кортежи
Кортеж - это такой тип значения, в котором можно хранить несколько значений другого типа. Например, вы можете упаковать в кортеж два числовых и одно строковое значение:
%pers = [187, 26, 'Петя']
Как видно из примера, для кортежей введён специальный префикс типа "%". Кортежи — это новый полноценный тип данных (например кортеж %A), наравне со строками ($A), и числовым типом (A).
Поскольку кортежи — это отдельный тип данных, вы можете вкладывать одни кортежи в другие:
%unit = ['лучник', [123, 90], [234, 300], 'агрессивен']
Вот ещё несколько примеров создания кортежей:
%q = [4, 6, 7]
%q = ['sdfsd', 6]
%q = [34]
%q = [] & ! пустой кортеж
%q = (65,'ddd')
%q = () & ! пустой кортеж
%q = [56, [32,'sdsd'], 3]
Допустимо использовать круглые скобки `()` для перечисления значений кортежа, однако рекомендуется использовать именно квадратные скобки `[]`.
Так же допустимо совсем опускать скобки при присваивании значений кортежу, однако такая запись тоже не рекомендуется, потому что плохо читаема:
%q = 65,'ddd'
local %q = 65,'ddd',33
Когда вы помещаете несколько значений в кортеж, это называется упаковка.
Чтобы извлечь значения из кортежа, проделываем присвоение «в обратную сторону»:
$name, %coords, %health, $status = %unit
Эта операция называется распаковка кортежа. В этом случае указанным переменным последовательно присваиваются значения элементов кортежа:
! упаковка:
%q = [56, [32,'sdsd'], 3]
! распаковка:
a, %b, c = %q
! используем кортеж для присвоения значений:
a, %b, c = [56, [32,'sdsd'], 3]
! аналогично:
a, %b, c = 56, [32,'sdsd'], 3
! здесь тоже неявно используются кортежи:
local a, b = b, a
local a, n = 123, 56
Каждый кортеж считается одним значением, поэтому их можно использовать для индексации в массивах, а также в значениях элементов массивов.
Примеры индексации в массивах:
$a[56,'sdsd'] = 'test'
$v = $a[56,'sdsd']
$q = $p[%d]
Для кортежей работают операции LEN, &, STR, VAL, ISNUM, а также несколько других:
- LEN возвращает длину кортежа:
LEN([5,7,'a']) = 3 - & объединяет кортежи или значение с кортежем:
(['sss',5,7] & [4,6]) = ['sss',5,7,4,6]
(['sss',5,7] & 66) = ['sss',5,7,66] - STR преобразует кортеж в строку:
$STR([5,7,'a']) = "[5,7,'a']" - VAL пытается преобразовать кортеж в число, возвращает 0 при невозможности:
VAL(['42']) = 42 - ISNUM проверяет можно ли преобразовать кортеж в число:
ISNUM(['42']) = 1
Ещё для кортежей поддерживаются операции «+», «-», «/», «*». Они возвращают новый кортеж, созданный из исходного кортежа, к каждому элементу которого применилась указанная арифметическая операция. Пример:
%tuple = [4, 10, 16]
%a = %tuple + 2
! %a будет равно [6, 12, 18]
%a = %tuple / 2
! %a будет равно [2, 5, 8]
Оператор SCANSTR
Этот оператор находит в строке все вхождения, соответствующие указанному регулярному выражению и помещает их в массив.
Общая запись:
SCANSTR [$имя_массива_с_результатами], [$текст_для_разбора], [$регулярное_выражение_подстроки], [#номер_группы_регулярного_выражения]
Последний параметр опционален. Если не указан или равен 0, то в массив будут добавляться строки, соответствующие всему регулярному выражению.
Примеры:
! вытаскиваем из строки все слова:
$text = 'Шла Саша по шоссе, а Грека через реку.'
scanstr '$words', $text, '\b\w+\b'
!В массиве $words окажутся значения: 'Шла', 'Саша', 'по', 'шоссе', 'а', 'Грека', 'через', 'реку'
! разбиваем строку по разделителю:
$text = 'утро|день|вечер|ночь'
scanstr '$words', $text, '[^|]+'
!В массиве $words окажутся значения: 'утро', 'день', 'вечер', 'ночь'
! вытаскиваем из строки все слова, помещённые в квадратные скобки, но без квадратных скобок:
$text = '[first] ignoredtext [second][third] also ignored'
scanstr '$words', $text, '\[(.*?)\]', 1
!В массиве $words окажутся значения: 'first', 'second', 'third'
Оператор SORTARR
Данный оператор сортирует указанный массив. Общая запись:
SORTARR [$имя_массива], [#порядок]
Параметр [#порядок] опционален. Если не указан или равен 0, то сортирует массив по возрастанию (от меньшего к большему). Если равен 1, то сортирует массив по убыванию (от большего к меньшему).
Может сортировать массивы любых типов (числа, строки, кортежи), но не допускается смешивать значения разных типов в одном массиве.
Для указания типа сортируемых значений нужно указать префикс типа как часть имени массива ($, %).
Пример сортировки текстового массива:
$a[] = 'nn'
$a[] = 'zz'
$a[] = 'aa'
sortarr '$a'
!проверяем результат сортировки:
loop local i=0 while i<arrsize('$a') step i+=1: *pl $a[i]
Функция CUROBJS
Функция получения кода QSP выведенных на экран предметов.
Эта функция аналогична функции CURACTS, которая получает список выведенных на экран действий в виде кода QSP.
Эта функция облегчает уничтожение и восстановление списков предметов. Например:
! сохраняем список предметов как код QSP:
$old_objects = $CUROBJS
! удаляем все предметы из окна предметов:
KILLOBJ
! восстанавливаем все предметы в окне предметов:
DYNAMIC $old_objects
Возможность писать комментарии после многострочных операторов
Примеры (раньше такой код был невозможен и приводил к ошибке):
if 0: ! some comments
'example 1'
else if 123: ! some comments
'example 2'
elseif 33: ! some comments
'example 3'
else: ! some comments
'example 4'
else ! some comments
'example 5'
end
act 'take something': ! some comments
'example 6'
end
loop while 0: ! useless loop
'example 7'
end
Улучшение сообщений об ошибках (показана строка кода с ошибкой, а не только номер строки)
Долгожданное изменение, упрощающее поиск и исправление ошибок!
Исправление ошибок, появившихся в версии 5.8
Оригинал статьи за авторством Byte'а: https://qsp.org/index.php?option=com_content&view=article&id=164&Itemid=76