Для петлі на Луа


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 говорить про те, що внутрішня частина циклу буде викликатися за допомогою names = 1then names = 2, і нарешті 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
Фрейзер

19

Читаючи в Інтернеті ( підручник з таблиць ), здається, таблиці поводяться як масиви, тому ви шукаєте:

Шлях1

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

Шлях2

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не потрібно повертати значення ключа в певному порядку?
Nicol Bolas,

ipairsСпочатку я фактично використовував, але коли додав myKey="myValue"приклад, що потребує pairsнечислового ключа, я вирішив змінити і решту pairs. Вибачте, якщо я пропустив, що замовлення не гарантується з парами, але я залишив посилання там, щоб він прочитав.
дерп

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
Downvoter: прохання надати дійсний привід для downvoting. Незважаючи на те, що я думаю, що відповідь вводить в оману, оскільки names(цілочисельний лічильник), як оголошено в forобласті, вводить локальну змінну, яка затінює names(масив таблиці), як оголошено в глобальній області.
Dejavu
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.