Цикл с ipairs
Пройти по списку от первого элемента до последнего нужно так часто, что в Lua для этого есть короткий путь. Кроме числового for, который вы уже знаете, есть второй вид цикла for, получающий значения от функции. С функцией ipairs он проходит по элементам списка:
local crops = {"морковь", "картофель", "тыква"}
for i, crop in ipairs(crops) do
print(i, crop)
endВыведется:
1 морковь
2 картофель
3 тыкваЧитайте первую строку так: для каждого индекса i и элемента crop в списке crops сделать следующее. В каждой итерации цикл даёт два значения: индекс и элемент с этим индексом. Писать crops[i] не нужно: элемент уже лежит в crop. Название ipairs происходит от index–value pairs — «пары индекс–значение».
Как и в числовом for, обе переменные существуют только внутри цикла, и называть их можно как угодно. Хорошее имя для элемента — единственное число от имени списка: crop для crops, price для prices.
Часто индекс не нужен. Тогда вместо него пишут _ (подчёркивание):
local crops = {"морковь", "картофель", "тыква"}
for _, crop in ipairs(crops) do
print("Поливаем: " .. crop)
endВыведется:
Поливаем: морковь
Поливаем: картофель
Поливаем: тыква_ — обычное имя переменной, но программисты на Lua пишут его там, где значение не нужно, чтобы любой, кто читает код, видел: индекс не используется. Просто пропустить индекс нельзя. Первая переменная всегда получает индекс, как бы она ни называлась:
local crops = {"морковь", "картофель", "тыква"}
for crop in ipairs(crops) do
print(crop)
endВыведется:
1
2
3Несмотря на название, crop получила индексы. Ещё одна частая ошибка — забыть ipairs. Цикл ждёт после in функцию, а получает таблицу:
local crops = {"морковь", "картофель", "тыква"}
for i, crop in crops do
print(crop)
endmain.lua:2: attempt to call a table value (for iterator 'for iterator')Ещё две вещи об ipairs:
- Он останавливается на первом
nil. В списке с дырой он доходит только до дыры и пропускает элементы после неё. Это ещё одна причина не оставлять дыр. - Присваивание нового значения переменной
cropменяет только эту переменную, а не список. Чтобы изменить элемент, пишитеcrops[i] = …, как в предыдущем упражнении.
Какой же цикл выбрать? ipairs — когда вы идёте по списку от начала до конца, а это бывает чаще всего. Числовой for — когда нужно что-то другое, например идти назад. В уроке о словарях вы познакомитесь с «братом» ipairs — функцией pairs.
Задание
- 1
Напишите цикл с
ipairs, который проходит поeggs, с переменнойdayдля индекса иcountдля элемента. - 2
В цикле выведите яйца за каждый день:
День 1, яиц: 4 День 2, яиц: 6 День 3, яиц: 5 День 4, яиц: 7 День 5, яиц: 3 День 6, яиц: 6 День 7, яиц: 5 - 3
Под ним напишите второй цикл
ipairsпоeggs, с_вместо индекса. В нём посчитайте хорошие дни, когда куры снесли не меньше 6 яиц. (Создайте счётчик до цикла, как в уроке о циклах.) - 4
После цикла выведите результат:
Хороших дней: 3.