For Loop on Lua

86

Moim zadaniem jest wykonanie pętli for. Rozgryzłem to w kategoriach liczb, ale nie mogę tego rozgryźć w kategoriach nazw. Chciałbym utworzyć pętlę for, która prowadzi do listy nazwisk. Oto, co mam do tej pory:

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

Próbowałem innych rzeczy, ale to po prostu nie działa, terminal zawsze wyświetla tylko 1, 2, 3 ... Co robię źle?

SamYoungNY
źródło

Odpowiedzi:

203

Twój problem jest prosty:

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

Ten kod najpierw deklaruje globalną zmienną o nazwie names. Następnie zaczynasz pętlę for. Pętla for deklaruje lokalną zmienną, która tak się akurat wywołuje names; fakt, że zmienna została wcześniej zdefiniowana za pomocą, namesjest całkowicie nieistotny. Każde użycie nameswewnątrz pętli for będzie odnosić się do pętli lokalnej , a nie globalnej.

Pętla for mówi, że wewnętrzna część pętli zostanie wywołana names = 1, a potem names = 2, a wreszcie names = 3. Pętla for deklaruje licznik, który odlicza od pierwszej do ostatniej liczby, i wywoła kod wewnętrzny raz dla każdej zliczanej wartości.

Właściwie chciałeś coś takiego:

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

Składnia [] określa sposób uzyskiwania dostępu do elementów tabeli Lua. Tabele Lua odwzorowują „klucze” na „wartości”. Twoja tablica automatycznie tworzy klucze typu całkowitego, których liczba wzrasta. Zatem klucz powiązany z „Joe” w tabeli to 2 (indeksy Lua zawsze zaczynają się od 1).

Dlatego potrzebujesz pętli for, która liczy od 1 do 3, którą otrzymujesz. Używasz zmiennej count, aby uzyskać dostęp do elementu z tabeli.

Ma to jednak wadę. Co się stanie, jeśli usuniesz jeden z elementów z listy?

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

Teraz otrzymujemy John Joe nil, ponieważ próba uzyskania dostępu do wartości z tabeli, która nie istnieje, skutkuje nil. Aby temu zapobiec, musimy policzyć od 1 do długości stołu:

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

#Jest operatorem długość. Działa na tabelach i łańcuchach, zwracając długość obu. Teraz, bez względu na to, jak duże lub małe się namesstanie, to zawsze będzie działać.

Istnieje jednak wygodniejszy sposób na iterację po tablicy elementów:

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

ipairsjest standardową funkcją Lua, która iteruje po liście. Ten styl forpętli, iterator pętli for, używa tego rodzaju funkcji iteratora. iWartość indeks wpisu tablicy. nameJest wartością w tym indeksie. Więc w zasadzie wykonuje dla ciebie dużo ciężkiej pracy.

Nicol Bolas
źródło
1
Tak więc, ponieważ z ipairs () działa jak foreach () w innych językach
boctulus
15
Świetna odpowiedź, chciałbym tylko dodać, że w ostatnim przykładzie dość zwyczajowo używa się, _gdy var nie jest używany. np.names = {'John', 'Joe', 'Steve'} for _, name in ipairs(names) do print (name) end
Fraser
19

Czytając online ( samouczek dotyczący tabel ), wydaje się, że tabele zachowują się jak tablice, więc szukasz:

Way1

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 używa tabeli index/key, na twojej tabeli nameskażdy element ma klucz zaczynający się od 1, na przykład:

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

Więc po prostu iprzejdź od 1 do 3.

Na Way2 zamiast podać co stół chcesz uruchomić i przypisać zmiennej dla swojego klucza i wartości, na przykład:

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

drukuje:

1   John
2   Joe
myKey   myValue
derp
źródło
6
Przeczytałeś samouczek dotyczący tabel, ale nie widziałeś ipairs? Lub część, w której pairsnie trzeba zwracać wartości kluczy w żadnej określonej kolejności?
Nicol Bolas
Właściwie użyłem ipairsna początku, ale kiedy dodałem myKey="myValue"przykład, który wymaga pairsklucza nienumerycznego, postanowiłem zmienić również resztę pairs. Przepraszam, jeśli pominąłem, że zamówienie nie jest gwarantowane parami, ale zostawiłem link do przeczytania.
derp
1
names = {'John', 'Joe', 'Steve'}
for names = 1, 3 do
  print (names)
end
  1. Usuwasz tabelę i zastępujesz ją int
  2. Nie pobierasz wartości z tabeli

Próbować:

names = {'John','Joe','Steve'}
for i = 1,3 do
    print(names[i])
end
Elliot
źródło
1
Głos przeciwny: podaj ważny powód głosowania przeciw. Chociaż uważam, że odpowiedź jest myląca, ponieważ names(licznik całkowity) zadeklarowany w forzakresie wprowadza zmienną lokalną, która przesłania names(tablicę tabeli) zgodnie z deklaracją w zakresie globalnym.
Dejavu,