Цикл с pairs
ipairs проходит по списку: 1, 2, 3… до первого отсутствующего номера. Ключей вроде carrot он не видит. Чтобы пройти по всем ключам таблицы, используйте pairs. На каждом круге цикла он выдаёт один ключ и его значение:
local barn = {carrot = 12, potato = 30, pumpkin = 4}
for crop, count in pairs(barn) do
print(crop .. ": " .. count)
endВыведется, например:
potato: 30
pumpkin: 4
carrot: 12Почему «например»? Потому что порядок в pairs не определён. Lua хранит ключи так, чтобы быстро находить любой из них, а не в том порядке, в каком вы их записали. Полагаться на какой-то порядок нельзя: ни на тот, что в коде, ни на алфавитный. На этом сайте порядок может даже меняться при каждом нажатии кнопки «Запустить»: попробуйте несколько раз. В большой программе он может измениться и тогда, когда ключи добавляют или удаляют.
Во многих задачах порядок не важен: сложить значения, посчитать ключи, найти наибольшее значение. Помните, что # не считает ключи словаря? Цикл их посчитает:
local barn = {carrot = 12, potato = 30, pumpkin = 4}
local kinds = 0
local total = 0
for crop, count in pairs(barn) do
kinds = kinds + 1
total = total + count
end
print("Видов: " .. kinds)
print("Итого: " .. total)Видов: 3
Итого: 46Когда порядок важен, например когда вы выводите амбар для Эммы, сначала отсортируйте ключи. Соберите их в список, отсортируйте через table.sort и пройдите по отсортированному списку через ipairs; значения читайте из словаря по ключам. Если после for стоит только одна переменная, pairs выдаёт одни ключи:
local barn = {potato = 30, pumpkin = 4, carrot = 12}
local crops = {}
for crop in pairs(barn) do
table.insert(crops, crop)
end
table.sort(crops)
for _, crop in ipairs(crops) do
print(crop .. ": " .. barn[crop])
endЭто выведет одни и те же строки в одном и том же порядке при каждом запуске:
carrot: 12
potato: 30
pumpkin: 4С функцией сравнения из урока про функции можно сортировать и по значениям: table.sort(crops, function(a, b) return barn[a] > barn[b] end) ставит первой культуру с наибольшим количеством штук.
pairs работает и со списками (их ключи — 1, 2, 3…), но порядок не гарантирует. Для списков используйте ipairs.
Типичные ошибки:
ipairs(barn)вместоpairs(barn): в таблице нет ключа1, поэтому цикл не выполнится ни разу. Ничего не выводится и ошибки нет, так что будьте внимательны.- Забыли
pairs:for crop, count in barn doзаканчивается ошибкойattempt to call a table value (for iterator 'for iterator'). - Добавление новых ключей в таблицу, пока по ней идёт
pairs. Менять или удалять ключи, которые выдаёт цикл, можно, а добавлять новые прямо в цикле нельзя.
Задание
- 1
С помощью цикла
forиpairsвыведите каждую культуру из амбара с её количеством. Строки могут идти в любом порядке, например:wheat: 50 carrot: 12 pumpkin: 4 potato: 30 - 2
Ниже посчитайте виды культур в амбаре и сложите все штуки. Выведите:
Видов: 4 Итого: 96 - 3
Наконец, выведите
По порядку:, а под ним ещё раз культуры, теперь отсортированные по алфавиту:По порядку: carrot: 12 potato: 30 pumpkin: 4 wheat: 50