[[help:regexp|Назад: Регулярные выражения]] ====== Кортежи ====== **QSP** позволяет упаковывать несколько значений в одну переменную, а затем извлекать их оттуда. Упакованные данные называются “**кортеж**”. Чтобы создать кортеж, нужно присвоить переменной, имя которой начинается с символа ''%%%%%'', группу значений, перечисленных в квадратных скобках через запятую. Пример: ! создаём кортеж %personage = ["Петя", 27, 182, 92, "боксёр"] Когда мы создаём кортеж, это называется **упаковкой** данных. Обратный процесс называется **распаковкой**: ! распаковываем данные из кортежа $name, age, height, weight, $sports = %personage Кортежи можно помещать и в отдельные ячейки массивов: %personage[0] = ["Петя", 27, 182, 92, "боксёр"] %personage[1] = ["Вася", 32, 162, 57, "жокей"] %personage[2] = ["Маша", 19, 158, 42, "фигуристка"] %personage[3] = ["Даша", 24, 202, 81, "баскетболистка"] В кортежи можно помещать значения любых типов, в том числе и другие кортежи: %unit = [187, 94, 'steel', [0, 2]] Допустимо использовать круглые скобки ''%%()%%'' для перечисления значений кортежа, однако рекомендуется использовать именно квадратные скобки ''%%[]%%'' для улучшения читаемости кода. %q = (65,'ddd') %q = () & ! пустой кортеж %q = (56, (32,'sdsd'), 3) Так же допустимо совсем опускать скобки при присваивании значений кортежу, однако такая запись тоже не рекомендуется, потому что плохо читаема: %q = 65,'ddd' local %q = 65,'ddd',33 ===== Операции с кортежами ===== ==== Объединение кортежей (конкатенация) & ==== Для объединения кортежей в один кортеж нужно использовать операцию конкатенации. Общая запись: [%новый_кортеж] = ([%кортеж_1] & [%кортеж_2] & ...) В данном случае ставить скобки обязательно. Только так плеер поймёт, что это операция конкатенации, а не перечисление команд через амперсанд ''%%&%%''. Пример: %tpl = ([1, 2] & [3, 4]) ! в переменную %tpl будет записан кортеж [1, 2, 3, 4] ==== Увеличение значений кортежа + ==== Общая запись: [%новый_кортеж] = [%кортеж_1] + [значение] При выполнении данной операции к каждому элементу кортежа ''%%[%кортеж_1]%%'' будет прибавлен элемент ''%%[значение]%%''. ''%%[значение]%%'' может быть кортежем, тогда каждый элемент ''%%[%кортеж_1]%%'' будет сложен с кортежем ''%%[%значение]%%''. Примеры: %tuple = [4, 10, 16] %a = %tuple + 2 ! %a будет равно [6, 12, 18] [4, 10] + ['b', 'x'] & ! [4 + ['b', 'x'], 10 + ['b', 'x']] ! [['4b','4x'], ['10b','10x']] ==== Уменьшение значений кортежа - ==== Общая запись: [%новый_кортеж] = [%кортеж_1] - [#значение] При выполнении данной операции из каждого элемента кортежа ''%%[%кортеж_1]%%'' будет вычтен элемент ''%%[#значение]%%''. ''%%[#значение]%%'' может быть только числом. Все остальные варианты приведут к ошибке о несоответствии типов данных. Примеры: %tuple = [4, 10, 16] %a = %tuple - 2 ! %a будет равно [2, 8, 14] [4, 10] - ['b', 'x'] & ! ошибка о несоответствии типов данных ==== Увеличение значений кортежа * ==== Общая запись: [%новый_кортеж] = [%кортеж_1] * [#значение] При выполнении данной операции каждый элемент кортежа ''%%[%кортеж_1]%%'' будет умножен на значение элемента ''%%[#значение]%%''. ''%%[#значение]%%'' может быть только числом. Все остальные варианты приведут к ошибке о несоответствии типов данных. Примеры: %tuple = [4, 10, 16] %a = %tuple * 2 ! %a будет равно [8, 20, 32] [4, 10] * 'b' & ! ошибка о несоответствии типов данных ==== Сокращение значений кортежа / ==== Общая запись: [%новый_кортеж] = [%кортеж_1] / [#значение] При выполнении данной операции каждый элемент кортежа ''%%[%кортеж_1]%%'' будет поделён на значение элемента ''%%[#значение]%%''. ''%%[#значение]%%'' может быть только числом. Все остальные варианты приведут к ошибке о несоответствии типов данных. Примеры: %tuple = [4, 10, 16] %a = %tuple / 2 ! %a будет равно [2, 5, 8] [4, 10] / 'b' & ! ошибка о несоответствии типов данных ==== Операции с присваиванием ==== Операции с присваиванием ''%%+=%%'', ''%%-=%%'', ''%%*=%%'' и ''%%/=%%'' применимы для кортежей. Только в операции ''%%+=%%'' можно добавлять к элементам кортежей значения любых типов. В операциях ''%%-=%%'', ''%%*=%%'' и ''%%/=%%'' можно использовать только целые значения. Примеры: %tuple = [5, 10, 15] %tuple /= 5 ! %tuple будет равно [1, 2, 3] %tuple *= 10 ! %tuple будет равно [10, 20, 30] %tuple -= 10 ! %tuple будет равно [0, 10, 20] %tuple += 13 ! %tuple будет равно [13, 23, 33] ===== Функции и операторы, работающие с кортежами ===== * ''%%LEN([%кор])%%'' - возвращает число элементов кортежа ''%%[%кор]%%''. *pl LEN([5,7,'a']) &! на экране будет число 3 * ''%%ISNUM([%кор])%%'' - проверяет, можно ли преобразовать ''%%[%кор]%%'' в число. Функция возвращает ''%%0%%'' (ложь) или ''%%1%%'' (истина). ISNUM([' 9999 ']) &! 1 ISNUM([' -888']) &! 1 ISNUM(['777a6']) &! 0 ISNUM(['']) &! 0, т.к пустая строка не содержит числа ISNUM(['1', '1']) &! 0, т.к. кортеж из двух значений ISNUM([1, 1]) &! 0, т.к. кортеж из двух значений * ''%%VAL([%кор])%%'' - переводит кортеж ''%%[%кор]%%'' в соответствующее число. Если преобразование невозможно, возвращает ''%%0%%''. val(['123']) & ! увидим 123 val(['']) & ! увидим 0 val(['1', 1]) & ! увидим 0 * ''%%$STR([%кор])%%'' - переводит кортеж в строку. *pl $STR([5,7,'a']) &! на экране увидим [5,7,'a'] * ''%%ARRPACK([$имя_массива], [#начальный_индекс], [#количество])%%'' - упаковывает массив ''[$имя_массива]'' в кортеж. * Можно указать, сколько элементов ''[#количество]'' упаковать в кортеж, и с какого элемента ''[#начальный_индекс]'' начинать упаковку. Параметры опциональны, по умолчанию ''[#начальный_индекс]'' равен нулю, а ''[#количество]'' соответствует размеру массива. * Функция возвращает кортеж с упакованными значениями. * Примеры: LOCAL type, name = ARRPACK('args') ! Из массива char берём пять элементов, начиная со второго, и упаковываем в кортеж: %unit[123] = ARRPACK('char', 2, 5) * ''%%UNPACKARR [$имя_массива], [%кортеж], [#начальный_индекс], [#количество]%%'' - распаковывает значения из кортежа ''[%кортеж]'' в массив ''[$имя_массива]''. * Можно указать, сколько элементов ''[#количество]'' распаковать, и с какого элемента ''[#начальный_индекс]'' начинать распаковку. Параметры опциональны, по умолчанию ''[#начальный_индекс]'' равен нулю, а ''[#количество]'' соответствует длине кортежа. * Пример: UNPACKARR 'A', ['тест','нескольких','значений',67, ['вложенный кортеж']] ! $A[0] будет содержать 'тест' ! $A[1] будет содержать 'нескольких' ! $A[2] будет содержать 'значений' ! A[3] будет содержать 67 ! %A[4] будет содержать ['вложенный кортеж'] * оператор позволяет извлечь из кортежа одно значение по указанному индексу: %tpl = ['тест','нескольких','значений',67, ['вложенный кортеж']] UNPACKARR 'A', %tpl, 3, 1 ! в A будет 67 ===== Индексация ячеек массивов через кортежи ===== Мы можем индексировать ячейки массивов с помощью кортежей, точно так же, как и с помощью строк. При этом повторяющиеся квадратные скобки можно и нужно опускать для лучшей читаемости кода. Таким образом можно создавать многомерные массивы: ! многомерный массив: $map[1,2] = 'space' $map[1,3] = 'space' $map[5,7] = 'tree' $map[0,-1] = 'hero' *pl $map[x,y] ! можно, но не рекомендуется, ! писать так: $map[[1,2]] = 'space' $map[[1,3]] = 'space' $map[[5,7]] = 'tree' $map[[0,-1]] = 'hero' *pl $map[[x,y]] Почитать про многомерные массивы можно в соответствующем подразделе раздела [[help:arrays|“Массивы”]]. Опускать повторяющиеся скобки нельзя, если для индексации используются кортежи, состоящие из одного значения. ===== Кортеж из одного значения ===== В **QSP** 5.9.0 появилась возможность создавать кортежи из одного значения. Например: %tuple = [-1] *pl %tuple & ! [-1] С помощью таких кортежей можно индексировать массивы, обходя ограничение на отрицательные индексы ячеек. Но в этом случае необходимо сохранять повторяющиеся квадратные скобки: $line_map[[-1]] = 'personage' *pl $line_map[[-1]] ===== Возвращение нескольких значений из функции ===== Поскольку кортежи позволяют упаковывать в переменную несколько значений, появилась возможность возвращать из пользовательской функции сразу несколько значений, используя распаковку: !foo %result = [12, 45] !start x, y = @foo() ===== Ограничения кортежей ===== * Используя лишь одну пару квадратных скобок нельзя создать кортеж из более чем двадцати элементов. Пример попытки создать кортеж из 21 элемента: %tpl = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21] ! это приведёт к ошибке: Неверное число аргументов операции/функции Однако вы можете создать кортеж, сколько угодно большой длины, используя конкатенацию: %tpl = ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] & [21]) **Настоятельно не рекомендуется** создавать кортежи большой длины. * Кортежи нельзя изменять. То есть, например, в кортеже из трёх элементов нельзя заменить второй элемент. Нужно распаковать кортеж в переменные, изменить одну из переменных и снова упаковать в кортеж: %pos_in_space = [12, -3, 9] x, y, z = %pos_in_space y = -13 %pos_in_space = [x, y, z] * Нельзя извлечь из кортежа одно конкретное значение, например, второе. Зато можно извлекать одно или несколько первых значений. В этом случае из набора переменных, в которые распаковывается кортеж, имя последней должно начинаться с символа ''%%%%%'', так как в эту переменную будет упаковываться оставшаяся часть кортежа: %personage = ["Петя", 27, 182, 92, "боксёр"] $name, %tale = %personage *pl $name &! 'Петя' $name, age, height, %tale = %personage *pl "Имя: <<$name>>, возраст: <>, рост: <>." weight, $sports = %tale *pl $sports * Как и в строках, предел объёмов данных для кортежа 2 Гигабайта или **2147483648** элементов. Величина кортежа не может превысить объём оперативной памяти. [[help:conditional|Вперёд: Условия]]