Структура 7.0 вносит значительные улучшения в язык Expr, делая его на порядок более мощным. На этой странице перечислены основные дополнения к языку и библиотеке функций, и она предназначена для пользователей Structure 6 и более ранних версий, уже знакомых с Expr.
Новые возможности
Массивы
Expr теперь поддерживает массивы или списки значений. Например, поле Fix Versions может содержать несколько значений — в Structure 7.0 есть функции, которые извлекают определенные значения из этих полей, выполняют операцию над каждым значением и многое другое!
Мы также добавили несколько новых функций для работы с массивами: Функции массива
Характеристики
Формулы теперь могут получать значение определенного свойства элемента, используя следующую нотацию: object.property.
КОД
fixVersion.releaseDate
Это возвращает дату выпуска для fixVersion.
Вы также можете связать несколько вызовов свойств вместе:
КОД
project.lead.email
Это возвращает адрес электронной почты лидера проекта.
Полный список поддерживаемых свойств см. в разделе Справочник по свойствам элемента.
Сцепленные вызовы функций
Этот новый способ вызова функции позволяет удобно применять последовательность функций к значению, перечисляя каждую функцию одну за другой, разделяя их точкой ( . ).
Старый метод: F3(F2(F1(x)))
Новый метод: x.F1().F2().F3()
В этом новом методе значение, стоящее перед точкой, становится первым аргументом функции. Если функция принимает несколько аргументов, остальные аргументы должны быть записаны в круглых скобках.
Например:
КОД
created.FORMAT_DATETIME ("гггг"). CONCAT ("год выпуска")
Если выпуск был создан в 2021 году, результатом будет: «Выпуск 2021 года».
Цепной метод можно применять к любому выражению и любой функции, включая пользовательские функции и массивы: ARRAY(1, 2, 3).MAX().SQR().
Пользовательские функции
Пользовательская функция позволяет определить локально используемую функцию в формуле. Пользовательские функции могут быть определены аналогично локальным переменным:
КОД
С квадратом (х) = х * х:
квадрат(impactField)/квадрат(storyPoints)
В этом примере пользовательской функции дается имя («квадрат»), а затем она используется для выполнения одних и тех же вычислений в нескольких полях. Чтобы узнать больше, см. справочник по языку.
Пользовательские функции для массивов — знакомство с символом «$»
Когда вам нужно выполнить операцию над каждым элементом в массиве, вы можете использовать «$» для обозначения каждого элемента в массиве.
Например, если вы хотите отфильтровать рабочие журналы на основе того, является ли автор текущим пользователем, вы можете написать:
КОД
worklogs.FILTER($.author = ME())
В этой формуле Structure заменяет "$" каждым элементом массива и вычисляет значение выражения "$.author = ME()" - если автор является текущим пользователем, он возвращает true, и этот рабочий журнал будет включен в результаты ФИЛЬТР.
Этот метод становится очень мощным, когда вы объединяете вместе несколько пользовательских функций. Чтобы узнать больше, см. справочник по языку.
Встроенные запросы
Теперь можно включать JQL и S-JQL (наш собственный структурированный JQL) в формулу:
КОД
JQL { assignee = currentUser()}
SJQL { leaf and child of [ assignee = currentUser()] }
Результатом будет логическое значение — true (число 1), если задача (для которой рассчитывается формула) удовлетворяет запросу.
Поскольку JQL — это запрос на основе Jira, он будет работать только с задачами; результат будет ложным (0) для других типов элементов. S-JQL можно использовать для более сложных запросов, применимых ко всей структуре.
Например:
// Соберите общее количество баллов за все подзадачи, назначенные членам группы Team2, если только истории не находятся в папке «Особые».
КОД
SUM {
IF JQL { assignee in membersOf("Team2") } :
IF NOT SJQL { descendant of folder("Special") } :
storyPoints
}
Расширенное выражение IF
Теперь можно создавать сложные операторы IF, а также операторы IF/ELSE в формуле.
КОД
WITH total = x + y :
IF total > 0 :
x / total
ELSE : error
Примечание: «:» после «ELSE» не является обязательным — в приведенном выше примере мы включили его для удобства чтения.
Оператор конкатенации
Оператор CONCAT позволяет соединить две текстовые строки вместе:
КОД
issueLink.source
CONCAT
" depends on "
CONCAT
issueLink.destination
Если link.source имеет значение PR-111, а link.destination — PR-231, приведенный выше код вернет: PR-111 зависит от PR-231.
Фрагменты текста
Текстовые фрагменты позволяют создавать тексты с использованием переменных и выражений. Это особенно полезно в формулах, использующих вики-разметку.
При использовании текстовых фрагментов:
Фрагмент должен быть заключен в """
может быть многострочным
$var заменяется значением переменной var
${выражение} заменяется значением выражения
КОД
"" $var1 + $var2 = ${var1 + var2} """
""" this $glass is half-${
IF optimist:
'full' ELSE: 'empty'} """
Новые функции
Следующие функции были добавлены или обновлены в Structure 7.0. Для получения подробной информации о каждой функции и о том, как их использовать, см. Справочник по функциям Expr.
Функции массива
- ARRAY — создает массив из списка элементов.
- GET — извлекает элемент из массива по его индексу. Индексы массива отсчитываются от 0. Возвращает значение undefined, если индекс выходит за пределы массива.
- UNIQUE — удаляет дубликаты из массива. Порядок неповторяющихся элементов сохраняется.
- COMPACT — удаляет все неопределенные значения из массива.
- FLATTEN — при наличии массива массивов выполняет одноэтапное сглаживание.
- RECURSIVE_FLATTEN — выполняет рекурсивное выравнивание и уплотнение массива, создавая массив, который гарантированно будет плоским и не будет содержать неопределенные значения.
- REVERSE — меняет порядок элементов массива на обратный.
- FILTER — фильтрует массив таким образом, чтобы он сохранял только те элементы, для которых указанная пользовательская функция возвращает истинное значение.
- MAP — применяет пользовательскую функцию к каждому элементу массива.
- SORT - Создает отсортированный массив.
- SORT_BY — сортирует массив, сравнивая значения, полученные при вызове пользовательской функции для каждого элемента массива.
- REDUCE — уменьшает массив до одного значения.
- GROUP — группирует элементы массива в сегменты на основе значения, созданного пользовательской функцией.
- JOIN — создает текст, представляющий массив, путем преобразования каждого элемента в текст и объединения их вместе.
- CONTAINS — возвращает true (1), если массив содержит указанный элемент.
- ANY — проверяет, удовлетворяет ли какой-либо из элементов массива условию.
- ALL — Проверяет, все ли элементы массива удовлетворяют условию.
- NONE — Проверяет, что ни один из элементов массива не удовлетворяет условию.
- /SEQUENCE — создает массив последовательных целых чисел.
- INDEXES — создает массив индексов другого массива.
- SIZE — возвращает количество элементов в массиве.
- MERGE_ARRAYS — создает единый массив с элементами всех массивов параметров.
- СУММА — вычисляет сумму всех числовых элементов массива.
- MUL — производит произведение всех числовых элементов массива.
- SUBARRAY - Создает массив с некоторыми элементами из данного массива.
- CONTAINS_ALL — проверяет, содержит ли один массив все элементы другого массива.
- CONTAINS_ANY — проверяет, содержит ли один массив хотя бы один элемент из другого массива.
- INDEX_OF / LAST_INDEX_OF — возвращает индекс первого/последнего вхождения элемента в массив.
- FIRST/LAST — возвращает первый/последний элемент массива.
- WITHOUT — возвращает входной массив со всеми элементами, кроме тех, которые равны указанному значению.
- IS_EMPTY — проверяет, пуст ли массив.
Статистические функции
- MIN/MAX — при использовании с несколькими аргументами MIN/MAX находит наименьшее/наибольшее значение среди чисел, переданных в качестве параметров. При использовании с массивом находит минимальное/максимальное число в массиве.
- UMIN/UMAX — то же, что и MIN/MAX, но выполняет универсальное сравнение, допуская любые типы значений, включая сущности.
- UMIN_BY/UMAX_BY — возвращает минимум/максимум путем их сравнения с использованием значений, рассчитанных путем вызова пользовательской функции для каждого элемента.
- PERCENTILE — вычисляет N-й процентиль значений в данном массиве.
- MEDIAN — вычисляет медианное значение массива чисел.
- QUARTILE — вычисляет значение квартиля массива чисел.
- AVERAGE — вычисляет среднее значение чисел в массиве.
- STDEV/STDEVP — вычисляет стандартное отклонение (на основе выборки или всей совокупности).
Другие функции
- URL_ENCODE — переводит текст в формат application/x-www-form-urlencoded.
- URL_DECODE — декодирует текст application/x-www-form-urlencoded.
- SPLIT — создает массив из текста, разделяя его с помощью разделителя.
- ACCESS — пытается получить доступ к свойству элемента.
Агрегатные функции
Следующие агрегатные функции были добавлены для работы с новыми возможностями и функциями, представленными в структуре 7.0. Дополнительные сведения см. в разделе Справочник по агрегатным функциям.
- ARRAY { } — вычисляет выражение для каждой подпроблемы (или другого набора строк, как определено модификаторами) и собирает значения в массив.
- VALUES { } — то же, что и ARRAY { }, но удаляет дубликаты, неопределенные значения и расширяет (выравнивает) значения массива, созданные внутренним выражением. Например, VALUES { fixVersion } создаст список всех версий исправлений, установленных для подпроблем.
- /MEDIAN { }, /PERCENTILE { } и другие — вычисляет числовое выражение для каждой подпроблемы (или другого набора проблем), а затем вычисляет соответствующее статистическое значение.
Изменения и примечания для существующих агрегатных функций
Следующие изменения были внесены в существующие агрегатные функции, потому что в Structure 7.0 внутреннее выражение (то, что внутри фигурных скобок) теперь может создавать новые типы — массивы, элементы, карты ключ-значение и пользовательские функции.
Функция агрегирования |
Функция |
Изменение в структуре 7 |
Выражение : Массив |
Выражение : Элемент |
Выражение : Ключевое значение карты |
SUM |
Суммирует результат внутреннего выражения для каждой строки темы. Если используется #distinct, один и тот же элемент не учитывается дважды. |
Если внутреннее выражение создает массив, суммирует элементы этого массива. |
Суммирует элементы массива. |
Ошибка |
Ошибка |
MIN |
Находит минимальное значение expr, рассчитанное для каждой строки. |
Если expr создает массив, находит минимальный элемент в этом массиве. |
Использует минимальное значение из массива. |
Использует порядок элементов. |
Отсортировано, как если бы это было неопределенное значение |
MAX |
Находит максимальное значение expr, рассчитанное для каждой строки. |
Если expr создает массив, находит максимальный элемент в этом массиве. |
Использует максимальное значение из массива. |
Использует порядок элементов. |
Отсортировано, как если бы это было неопределенное значение |
JOIN |
Создает строковое представление значений, созданных выражением, объединенных вместе в виде списка или иерархически. Использует преобразование в Text/Joined. |
Если используется #distinct, не включает одно и то же значение дважды. |
Если expr создает массив, объединяет элементы этого массива. |
Если expr создает массив, объединяет элементы этого массива. |
Ошибка |
Примечание. Если внутреннее выражение создает пользовательскую функцию, это всегда будет приводить к ошибке.
Обратная совместимость
Некоторые улучшения, которые мы сделали, потребовали от нас изменить способ работы формул с определенными элементами или символами. Из-за этого может потребоваться обновление некоторых старых формул, так как они либо больше не будут работать со структурой 7, либо приведут к непредвиденному результату.
Просмотрите следующую диаграмму и при необходимости обновите существующие формулы.
Изменение |
Пример формулы |
Результат перед Structure 7 |
Результат после Structure 7 |
Символ точки ("".") больше не является допустимым символом для переменной. |
WITH my.data = 5 : ... CONCAT("user", user.name) с user.name, привязанным к атрибуту |
действительный расчет |
ошибка синтаксического анализа user.name undefined |
Функция TRIM() для значений массива обрезает каждый элемент. |
Предположим, у нас есть имена версий с пробелами в начале и конце, «v1» и «v2». TRIM(fixVersion) |
"v1, v2" (пробелы внутри) |
"v1, v2" Или ["v1", "v2"] при обработке как массив |
Функции MIN / MAX теперь требуют определенных параметров; в противном случае они теперь могут привести к ошибкам. |
min(1, "aha!") |
1 |
"VALUE?" ошибка |
Сторонние загрузчики атрибутов, которые предоставляют значения в любом формате, кроме TEXT, DURATION, TIME, NUMBER, BOOLEAN, больше не будут загружаться по формуле. Возможность добавить его через переменный селектор стендов. |
х x привязан к загрузчику с неподдерживаемым форматом. |
текстовое представление загруженного значения |
неопределенное значение |
Ошибки формул теперь распространяются через агрегации
|
join { 1/0 } |
"?" |
"DIV/0" ошибка |
Мы ввели ограничения на выполнение. Формулы, требующие слишком большого количества шагов расчета, вернут ошибку, поскольку их обработка займет слишком много времени. |
слишком сложная формула |
действительный расчет |
"LIMIT!" ошибка |
Ограничение размера массива может повлиять на использование переменных и join#distinct
|
fixVersions join#subtree#distinct{ key } |
действительный расчет |
"ARRAY!" ошибка |
Join#distinct работает немного по-другому. Раньше, в примере справа, он интерпретировал бы два набора меток как «a, b» и «b, c» — теперь он может идентифицировать отдельные метки в каждом наборе ( "a" and "b" and "b" and "c").
|
join#distinct{labels}, labels are (a, b) and (b, c) |
a, b, b, c |
a, b, c |
Раньше с помощью эффектора можно было записать одно поле в другое, даже если параметры не совпадали. Например, вы можете написать разрешение на статус. Это уже невозможно, если типы не совпадают. Обходной путь. В некоторых случаях это все еще будет работать, если вы оберните поле, чтобы изменить его тип: вместо «разрешение» используйте «текст (разрешение)». |
разрешение |
пытается записать значение |
ошибка |
По материалам Atlassian JIRA Structure: Changes to Expr in Structure 7