Диапазоны чисел и их перебор

Хелпер range пригодится, если в шаблоне для каких-то целей нужно сделать перебор чисел в заданном диапазоне.

Проще всего использовать его так:

{{#range from to}}
{{@value}}
{{/range}}

from — это имя переменной с числом, в которой записана нижняя граница, от которой мы начнем наш диапазон.

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

Т. е. если мы запишем в переменную from — 1, а в переменную to — 10, то мы получим числа от 1 до 9 включительно.

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

{{#range 1 10}}
{{@value}}
{{/range}}

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

Также range позволяет произвольно менять шаг:

{{#range 1 10 step=2}}
{{@value}}
{{/range}}

Параметр step=2 указывает, что двигаться по диапазону нужно с шагом в 2. Такая запись выведет числа 1, 3, 5, 7, 9.

Т. е. сперва в тело хелпера попадет 1, потом к нему добавится 2 — 1 + 2 = 3, и т. д. пока хелпер не дойдет до своей верхней, недостижимой, границы.

Внутри блока range можно использовать две специальные переменные: @value, которую вы могли видеть выше, и @index.

@value — это текущее значение диапазона.

@index — это порядковый номер текущей итерации, начиная от нуля. На него не влияет параметр step. Т.е. в @index в первый раз будет 0, во второй — 1, в третий — 2 и т.д., пока не закончится получение чисел в диапазоне.

Наглядно можно посмотреть на различие @index и @value на примере:

{{#range 1 10 step=2}}
index: {{@index}} | value: {{@value}}
{{/range}}

Результат будет таким:

index: 0 | value: 1
index: 1 | value: 3
index: 2 | value: 5
index: 3 | value: 7
index: 4 | value: 9

Диапазон может идти и в обратном порядке, для этого нижняя граница должна быть больше чем верхняя:

{{#range 10 1 step=2}}
{{@value}}
{{/range}}

Результат:

10
8
6
4
2

Т. е. мы можем получить числа в обратном порядке.

Нестандартный перебор списка

Мы можем сочетать хелпер range с хелпером get, который используется для получения значений из словарей и списков.

Допустим, у нас есть переменная names, в которой хранится список имен людей, приглашенных на вечеринку:

{
"names": ["Alex", "Jane", "Mary", "Ann", "Mortimer", "Maxim"]
}

Например, используя range и get мы можем написать такой шаблон, чтобы показать только четные имена в списке:

{{#range 1 names.length step=2}}
{{get names @value}}
{{/range}}

Результат:

Jane
Ann
Maxim

Давайте разберем этот пример подробнее.

Мы создали блок с диапазоном от 1 до значения переменной names.length. У всех списков есть вложенная переменная length, к которой мы можем обратиться через точку — в ней хранится текущая длинна списка.

Получается, что мы создали диапазон от 1 до длины списка. Обратите внимание, что элементы списков нумеруются не с 1, как мы привыкли в обычной жизни, а с 0, как это принято в компьютерных программах. Поэтому число 1, которое мы получим на первом шаге нашего диапазона — это второй элемент в списке, а не первый.

Внутри блока диапазона мы записали {{get names @value}}.

get — имя хелпера, для получения элементов из списков и словарей.

names — это имя переменной со списком внутри, первый параметр для get.

@value — как мы уже знаем — это внутренняя переменная с текущим значением диапазона на этом шаге.

На каждом шаге диапазона мы получаем из names значение по индексу из @value.

Так как мы задали диапазон с параметром step=2, он будет увеличиваться на 2, т. е. в @value мы получим: 1, 3 и 5 — это как раз индексы четных имен. Помните? Порядок элементов в списках с 0, т. е. индекс 1 — это второй элемент, 3 — четвертый, а 5 — шестой.

Выводим список в обратную стророну

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

{{#range names.length 0}}
{{get names (subtract @value 1)}}
{{/range}}

В этом случае мы добавляем еще хелпер subtract — вычитание.

Мы создаем диапазон в обратную сторону от длины списка до нуля.

Не забываем, что вторая граница диапазона не включается, а длина списка всегда больше индекса последнего элемента, потому что списки индексируются с 0, а не с 1.

По этой причине, диапазон не до конца подходит для получения элементов, и нужно вычитать из значений диапазона 1, для чего мы и используем subtract совместно с get внутри блока range.

Выводим список

Впрочем, если по какой-то причине это необходимо, range можно использовать и для обычного перебора списка, хотя хелпер #each лучше подходит для этих целей:

{{#range 0 names.length}}
{{get names @value}}
{{/range}}

Лучше с #each:

{{#each names}}
{{this}}
{{/each}}

Создание JSON из диапазона

Еще одна возможность, которую дают диапазоны — это быстрое создание JSON-списка при помощи хелпера strinigify:

{{stringify (range 1 10 step=2)}}

Результат JSON:

[1,3,5,7,9]

Такой список можно записать в переменную при помощи компонента Запись переменной или Запись переменных с типом Объект из JSON.

Ограничения

По техническим причинам хелпер range ограничен 1000 итераций. Это значит, что вы можете сгенерировать диапазон от 1 до 1000 включительно с параметром step=1 или от 1 до 2000 включительно с параметром step=2. Т. е. 1000 итераций — это ограничение именно выполнения того, что вы напишете внутри блока range, или ограничение на длину итогового списка, который вы попытаетесь получить через stringify.

В начало ↑