4.3.5 - Обобщенный for

Обобщенная форма цикла for позволяет отслеживать все значения, возвращенные функцией-итератором. Ранее уже приводился пример обобщенного for:

    -- вывод всех значений массива 'a'
    for i,v in ipairs(a) do print(v) end
На каждом шаге этого кода, i получает индекс, а v - значение, ассоциированное с этим индексом. Подобный же пример показывает прохождение по всем ключам таблицы:
    -- вывод всех ключей таблицы 't'
    for k in pairs(t) do print(k) end
Несмотря на видимую простоту, обобщенный for весьма функционален. With proper iterators, we can traverse almost anything, and do it in a readable fashion. Стандартная библиотека предлагает несколько итераторов, позволяющих проходить по строкам в файле (io.lines), парам в таблице (pairs), словам в строке (string.gfind, рассматриваемая в Главе 20) и другие. Конечно, можно использовать и собственные итераторы. Хотя использовать обобщенный for просто, задача написания функций-итераторов имеет свои особенности. Эта тема будет рассмотрена позже, в Главе 7.

Обобщенная и числовая формы цикла имеют два общих свойства: управляющие переменные являются локальнымидля тела цикла их нельзя изменять.

А теперь несколько более конкретный пример использования обобщенного for. Предположим, у вас есть таблица, собержащая название дней недели:

    days = {"Sunday", "Monday", "Tuesday", "Wednesday",
            "Thursday", "Friday", "Saturday"}
А теперь вы хотите перевести имя в его положение в неделе. Можно искать в таблице, просматривая полученные имена. Чаще, однако, более эффективным подходом в Lua будет построить обратную таблицу сименем revDays, в которой имена являются индексами, а номера - значениями. Такая таблица будет выглядеть так:
    revDays = {["Sunday"] = 1, ["Monday"] = 2,
               ["Tuesday"] = 3, ["Wednesday"] = 4,
               ["Thursday"] = 5, ["Friday"] = 6,
               ["Saturday"] = 7}
Теперь все, что вам нужно сделать - это найти соответствующее имя и индексировать им таблицу:
    x = "Tuesday"
    print(revDays[x])    --> 3
Естественно, обратную таблицу не обязательно объявлять вручную. Можно построить ее автоматически на основе таблицы days:
    revDays = {}
    for i,v in ipairs(days) do
      revDays[v] = i
    end
Цикл будет выполнять присваивание для каждого элемента days, причем переменная i получает индекс (1, 2, ...), а v - значение ("Sunday", "Monday", ...).
Hosted by uCoz