Для цикла на Lua


86

Мое задание - как сделать цикл for. Я понял это в терминах чисел, но не могу понять это в терминах имен. Я хотел бы создать цикл for, который запускает список имен. Вот что у меня есть до сих пор:

names = {'John', 'Joe', 'Steve'}
for names = 1, 3 do
  print (names)
end

Я пробовал еще кое-что, но это просто не работает, терминал всегда отображает только 1, 2, 3 ... Что я делаю не так?

Ответы:


203

Ваша проблема проста:

names = {'John', 'Joe', 'Steve'}
for names = 1, 3 do
  print (names)
end

Этот код сначала объявляет глобальную переменную с именем names. Затем вы запускаете цикл for. Цикл for объявляет локальную переменную, которая тоже случайно namesвызывается; тот факт, что переменная ранее была определена, namesсовершенно не имеет значения. Любое использование namesвнутри цикла for будет относиться к локальному , а не к глобальному.

Цикл for говорит, что внутренняя часть цикла будет вызываться with names = 1, then names = 2и finally names = 3. Цикл for объявляет счетчик, который считает от первого числа до последнего, и вызывает внутренний код один раз для каждого подсчитываемого значения.

На самом деле вам нужно было что-то вроде этого:

names = {'John', 'Joe', 'Steve'}
for nameCount = 1, 3 do
  print (names[nameCount])
end

Синтаксис [] - это способ доступа к элементам таблицы Lua. Таблицы Lua отображают «ключи» в «значения». Ваш массив автоматически создает ключи целочисленного типа, которые увеличиваются. Таким образом, ключ, связанный с «Джо» в таблице, равен 2 (индексы Lua всегда начинаются с 1).

Следовательно, вам нужен цикл for, который считает от 1 до 3, что вы и получите. Вы используете переменную count для доступа к элементу из таблицы.

Однако в этом есть недостаток. Что произойдет, если вы удалите один из элементов из списка?

names = {'John', 'Joe'}
for nameCount = 1, 3 do
  print (names[nameCount])
end

Теперь мы получаем John Joe nil, потому что попытка доступа к значениям из таблицы, которая не существует, приводит к nil. Чтобы этого не произошло, нам нужно считать от 1 до длины таблицы:

names = {'John', 'Joe'}
for nameCount = 1, #names do
  print (names[nameCount])
end

Оператор #длины. Он работает с таблицами и строками, возвращая длину любого из них. Теперь, независимо от того, насколько велик он или маленький names, это всегда будет работать.

Однако есть более удобный способ перебирать массив элементов:

names = {'John', 'Joe', 'Steve'}
for i, name in ipairs(names) do
  print (name)
end

ipairsэто стандартная функция Lua, которая выполняет итерацию по списку. Этот стиль forцикла, итератор для цикла, использует такую ​​функцию итератора. iЗначение является индексом элемента массива. nameЗначение является значением по этому индексу. Так что в основном он делает за вас много ворчливой работы.


1
Итак, for with ipairs () работает как foreach () на других языках
boctulus

15
Отличный ответ, я бы просто добавил, что в последнем примере довольно часто используется, _когда var не используется. напримерnames = {'John', 'Joe', 'Steve'} for _, name in ipairs(names) do print (name) end
Fraser

19

Читая онлайн ( учебник по таблицам ), кажется, что таблицы ведут себя как массивы, поэтому вы ищете:

Путь1

names = {'John', 'Joe', 'Steve'}
for i = 1,3 do print( names[i] ) end

Way2

names = {'John', 'Joe', 'Steve'}
for k,v in pairs(names) do print(v) end

Way1 использует таблицу index/key, в вашей таблице namesкаждый элемент имеет ключ, начинающийся с 1, например:

names = {'John', 'Joe', 'Steve'}
print( names[1] ) -- prints John

Так что вы просто iпереходите от 1 к 3.

На Way2 вместо этого указать , какой стол вы хотите запустить и назначить переменную для своего ключа и значения, например:

names = {'John', 'Joe', myKey="myValue" }
for k,v in pairs(names) do print(k,v) end

печатает следующее:

1   John
2   Joe
myKey   myValue

6
Вы читали учебник по таблицам, но не видели ipairs? Или та часть, где pairsне нужно возвращать значения ключей в каком-либо определенном порядке?
Никол Болас

Я действительно ipairsсначала использовал, но когда я добавил myKey="myValue"пример, который нужен pairsдля нечисловой клавиши, я решил изменить и остальные pairs. Прошу прощения, если я пропустил, что порядок не гарантируется с парами, но я оставил ссылку прямо здесь, чтобы он мог прочитать.
derp 01

1
names = {'John', 'Joe', 'Steve'}
for names = 1, 3 do
  print (names)
end
  1. Вы удаляете свою таблицу и заменяете ее на int
  2. Вы не берете значение из таблицы

Пытаться:

names = {'John','Joe','Steve'}
for i = 1,3 do
    print(names[i])
end

1
Голосующий против : укажите уважительную причину голосования против. Хотя я думаю, что ответ вводит в заблуждение в том, что names(счетчик целых чисел), объявленный в области forвидимости, вводит локальную переменную, которая затеняет names(массив таблиц), объявленный в глобальной области.
Dejavu
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.