Para Loop en Lua

86

Mi tarea es cómo hacer un bucle for. Lo he calculado en términos de números, pero no puedo descifrarlo en términos de nombres. Me gustaría crear un bucle for que recorra una lista de nombres. Lo siguiente es lo que tengo hasta ahora:

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

He intentado algunas otras cosas pero simplemente no funciona, el terminal siempre solo enumera 1, 2, 3 ... ¿Qué estoy haciendo mal?

SamYoungNY
fuente

Respuestas:

203

Tu problema es simple:

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

Este código primero declara una variable global llamada names. Luego, inicias un bucle for. El bucle for declara una variable local que resulta que también se llama names; el hecho de que una variable se haya definido previamente con nameses completamente irrelevante. Cualquier uso de namesdentro del bucle for se referirá al local , no al global.

El bucle for dice que se llamará a la parte interna del bucle con names = 1, luego names = 2y finalmente names = 3. El bucle for declara un contador que cuenta desde el primer número hasta el último, y llamará al código interno una vez por cada valor que cuente.

Lo que realmente querías era algo como esto:

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

La sintaxis [] es la forma de acceder a los miembros de una tabla Lua. Las tablas Lua asignan "claves" a "valores". Su matriz crea automáticamente claves de tipo entero, que aumentan. Entonces, la clave asociada con "Joe" en la tabla es 2 (los índices Lua siempre comienzan en 1).

Por lo tanto, necesita un bucle for que cuente de 1 a 3, que obtiene. Utiliza la variable de recuento para acceder al elemento de la tabla.

Sin embargo, esto tiene un defecto. ¿Qué sucede si elimina uno de los elementos de la lista?

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

Ahora, obtenemos John Joe nil, porque intentar acceder a valores de una tabla que no existe da como resultado nil. Para evitar esto, debemos contar desde 1 hasta la longitud de la tabla:

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

El #es el operador de longitud. Funciona en tablas y cadenas, devolviendo la longitud de cualquiera. Ahora, no importa cuán grande o pequeño namessea, esto siempre funcionará.

Sin embargo, hay una forma más conveniente de iterar a través de una matriz de elementos:

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

ipairses una función estándar de Lua que itera sobre una lista. Este estilo de forbucle, el iterador para bucle, utiliza este tipo de función de iterador. El ivalor es el índice de la entrada en la matriz. El namevalor es el valor en ese índice. Así que básicamente hace mucho trabajo duro para ti.

Nicol Bolas
fuente
1
Entonces, para con ipairs () funciona como foreach () en otros idiomas
boctulus
15
Excelente respuesta, solo agregaría que en el ejemplo final es bastante habitual usarlo _cuando la var no se usa . por ejemplonames = {'John', 'Joe', 'Steve'} for _, name in ipairs(names) do print (name) end
Fraser
19

Al leer en línea ( tutorial de tablas ), parece que las tablas se comportan como matrices, por lo que está buscando:

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 tabla index/key, en su tabla namescada elemento tiene una clave que comienza desde 1, por ejemplo:

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

Así que simplemente ipasa de 1 a 3.

En Way2, en cambio, especifica qué tabla desea ejecutar y asigna una variable para su clave y valor, por ejemplo:

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

imprime lo siguiente:

1   John
2   Joe
myKey   myValue
derp
fuente
6
¿Leíste el tutorial de tablas, pero no viste ipairs? ¿O la parte en la pairsque no tiene que devolver los valores clave en ningún orden en particular?
Nicol Bolas
De hecho, lo usé ipairsal principio, pero cuando agregué el myKey="myValue"ejemplo que necesita pairspara la clave no numérica, decidí cambiar el resto pairstambién. Lo siento si omití que el pedido no está garantizado con pares, pero dejé el enlace allí para que lo lea.
derp
1
names = {'John', 'Joe', 'Steve'}
for names = 1, 3 do
  print (names)
end
  1. Estás eliminando tu tabla y reemplazándola con un int
  2. No estás sacando un valor de la mesa

Tratar:

names = {'John','Joe','Steve'}
for i = 1,3 do
    print(names[i])
end
Elliot
fuente
1
Votante negativo: proporcione una razón válida para votar negativamente. Aunque creo que la respuesta es engañosa en el sentido de que names(el contador de enteros) como se declara en el foralcance introduce una variable local, que oculta names(la matriz de la tabla) como se declara en el alcance global.
Dejavu