Per Loop su Lua


87

Il mio compito è come fare un ciclo for. L'ho capito in termini di numeri ma non riesco a capirlo in termini di nomi. Vorrei creare un ciclo for che percorra un elenco di nomi. Di seguito è quello che ho finora:

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

Ho provato altre cose ma semplicemente non funziona, il terminale elenca sempre solo 1, 2, 3 ... Cosa sto facendo di sbagliato?

Risposte:


204

Il tuo problema è semplice:

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

Questo codice dichiara prima una variabile globale chiamata names. Quindi, avvia un ciclo for. Il ciclo for dichiara una variabile locale che viene chiamata namesanche per caso; il fatto che una variabile fosse stata precedentemente definita con namesè del tutto irrilevante. Qualsiasi utilizzo namesall'interno del ciclo for farà riferimento a quello locale , non a quello globale.

Il ciclo for dice che la parte interna del ciclo verrà chiamata con names = 1, quindi names = 2e infine names = 3. Il ciclo for dichiara un contatore che conta dal primo all'ultimo numero e chiamerà il codice interno una volta per ogni valore che conta.

Quello che volevi davvero era qualcosa del genere:

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

La sintassi [] è il modo in cui accedi ai membri di una tabella Lua. Le tabelle Lua associano le "chiavi" ai "valori". Il tuo array crea automaticamente chiavi di tipo intero, che aumentano. Quindi la chiave associata a "Joe" nella tabella è 2 (gli indici Lua iniziano sempre da 1).

Pertanto, hai bisogno di un ciclo for che conti da 1 a 3, che ottieni. Si utilizza la variabile count per accedere all'elemento dalla tabella.

Tuttavia, questo ha un difetto. Cosa succede se rimuovi uno degli elementi dall'elenco?

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

Ora, otteniamo John Joe nil, perché il tentativo di accedere a valori da una tabella che non esistono risulta in nil. Per evitare ciò, dobbiamo contare da 1 alla lunghezza della tabella:

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

Il #è l'operatore lunghezza. Funziona su tabelle e stringhe, restituendo la lunghezza di entrambe. Ora, non importa quanto grande o piccolo namessia, funzionerà sempre.

Tuttavia, esiste un modo più conveniente per scorrere una serie di elementi:

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

ipairsè una funzione standard di Lua che itera su un elenco. Questo stile di forciclo, l'iteratore per ciclo, utilizza questo tipo di funzione iteratore. Il ivalore è l'indice della voce nell'array. Il namevalore è il valore in quell'indice. Quindi fondamentalmente fa molto lavoro per te.


1
Quindi, per with ipairs () funziona come foreach () in altre lingue
boctulus

15
Ottima risposta, aggiungerei solo che nell'esempio finale è abbastanza consuetudine usare _quando la var è inutilizzata. ad esempionames = {'John', 'Joe', 'Steve'} for _, name in ipairs(names) do print (name) end
Fraser

19

Leggendo online ( tutorial sulle tabelle ) sembra che le tabelle si comportino come array, quindi stai cercando:

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 usa la tabella index/key, sulla tua tabella namesogni elemento ha una chiave che parte da 1, ad esempio:

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

Quindi devi solo ipassare da 1 a 3.

Su Way2 invece specifichi quale tabella vuoi eseguire e assegni una variabile per la sua chiave e valore ad esempio:

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

stampa quanto segue:

1   John
2   Joe
myKey   myValue

6
Hai letto il tutorial delle tabelle, ma non l'hai visto ipairs? O la parte in cui pairsnon deve restituire i valori chiave in un ordine particolare?
Nicol Bolas

In realtà l'ho usato ipairsall'inizio, ma quando ho aggiunto l' myKey="myValue"esempio che necessita pairsdel tasto non numerico ho deciso di cambiare anche il resto pairs. Mi dispiace se ho omesso che l'ordine non è garantito con le coppie ma ho lasciato il link proprio lì perché lui lo leggesse.
derp

1
names = {'John', 'Joe', 'Steve'}
for names = 1, 3 do
  print (names)
end
  1. Stai eliminando la tua tabella e sostituendola con un int
  2. Non stai estraendo un valore dalla tabella

Provare:

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

1
Downvoter: fornire un motivo valido per il downvoter. Anche se penso che la risposta sia fuorviante in quanto names(il contatore intero) come dichiarato nello forscope introduce una variabile locale, che ombreggia il names(l'array della tabella) come dichiarato nello scope globale.
Dejavu
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.