Menu
Coddy logo textTech

Индексные сигнатуры

Часть раздела Введение в Luau путешествия по Lua на Coddy. Урок 72 из 73.

Ты уже встречал типы map, такие как {[string]: number}, в главе о таблицах: сигнатура индекса: любой строковый ключ any сопоставляется со значением типа number. Они особенно полезны, когда ключи неизвестны во время написания кода: счётчики, настройки, кэши, оценки — всё, что формируется во время выполнения.

type Counts = {[string]: number}

local counts: Counts = {}
counts["potion"] = 3   -- любой строковый ключ разрешён
counts["sword"] = 1
counts["potion"] += 1  -- значения проверяются как числа

При работе с map важны два факта, связанные с выполнением программы. Во-первых, чтение ключа, который никогда не был задан, возвращает nil: классический шаблон подсчёта обрабатывает это с помощью or, превращая «missing» в 0:

counts[item] = (counts[item] or 0) + 1

Во-вторых, pairs() перебирает ключи map в порядке, для которого нет guaranteed order: при двух запусках одной и той же программы ключи могут посещаться по-разному. Когда вывод должен быть предсказуемым, собери ключи в array, выполни для них table.sort, а затем перебирай вместо этого отсортированный array:

local keys: {string} = {}
for key in pairs(counts) do
    table.insert(keys, key)
end
table.sort(keys)
for _, key in ipairs(keys) do
    print(`{key}: {counts[key]}`)
end
challenge icon

Задание

Легко

Подсчитывайте добычу с помощью типизированной map.

  • Объявите type Counts = {[string]: number}.
  • Напишите countItems(items: {string}): Counts, которая создаёт новую map типа Counts и подсчитывает, сколько раз встречается каждая строка (используйте шаблон (counts[item] or 0) + 1).
  • Создайте local loot: {string} = {"potion", "sword", "potion", "shield", "potion", "sword"} и подсчитайте её элементы.
  • Выведите по одной строке [name]: [count] для каждого уникального item в алфавитном порядке: соберите keys, отсортируйте их с помощью table.sort, затем выведите.

Ожидаемый вывод:

potion: 3
shield: 1
sword: 2

Попробуйте сами

-- Напишите код здесь
-- 1) type Counts = {[string]: number}
-- 2) countItems(items: {string}): Counts используя (counts[item] or 0) + 1
-- 3) подсчитайте массив loot из задания
-- 4) соберите ключи, table.sort их, выведите строки `{name}: {count}`
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Введение в Luau

Потренируйтесь самостоятельно: Онлайн-компилятор Lua