Bienvenidos sean a este post, hoy hablaremos sobre el tipo llamado table o tabla en castellano, este tipo implementa arrays asociativos y un array asocitativo es un tipo de array que no solamente permite la indexacion de los elementos por numeros sino tambien por cadenas o cualquier valor del lenguaje, este tipo de arrays no tienen un tamaño definido sino que se incrementaran a medida que se vayan agregando mas elementos, de hecho las tablas son la unica estructura de datos en el lenguaje.

Anuncios

Las tablas se utilizan para representar no solamente arrays sino tambien para representar tablas de simbolos, sets, records, queues y otras estructura de datos en una forma uniforme y eficiente, tambien se usa para representar modulos, paquetes y objetos.

Las tablas no son ni variables ni valores sino que son objetos, si ustedes tienen una idea de Arrays en Java o esquemas entonces tenes la mitad del camino recorrido pero sino les recomiendo este post donde hablo sobre esto, podemos pensar a la tabla como un objeto ubicado dinamicamente y tu programa solo manipula referencias (o apuntadores) a ellos, no posee copias ocultas o creacion de tablas detras de escenas, otro dato particular es que no debes declarar una tabla en Lua es mas de hecho no puede hacerse, la forma mas simple de crearse es por medio del bloque de llaves ({}), veamos un ejemplo:

tinchicus@dbn001dsk:~/lenguaje/lua$ lua5.3
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> a = {}
> k="x"
> a[k] = 10
> a[20] = "Piola"
> print(a["x"])
10
> k=20
> print(a[k])
Piola
> a["x"] = a["x"] + 1
> print(a["x"])
11
>

Vean como primero creamos una tabla, despues tenemos una variable llamada k a la que le asignamos el valor x, despues a la tabla a le asignamos la posicion almacenada en k y el valor de 10, luego asignamos un indice de posicion (20) con el valor “Piola”, primero mostraremos el valor almacenado en la posicion x, esperen un momento porque x y no k? porque nosotros al momento de crearlo no usa la variable informado sino el valor almacenado en la misma, despues le asignamos el valor 20 a k, en la siguiente linea mostraremos el valor de a con el valor almacenado en k, observen como nos trajo el valor de la posicion 20, por ultimo hicimos un incremento del valor contenido en x y observen como al mostrarlo se incremento, veamos otro ejemplo:

tinchicus@dbn001dsk:~/lenguaje/lua$ lua5.3
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> a = {}
> a["x"] = 10
> b = a
> print(b["x"])
10
> b["x"]=20
> print(a["x"])
20
> a=nil
> b=nil
>
Anuncios

Hablemos de lo mas interesante, la tercer linea hace una referencia en la variable b de la tabla a, si observan la cuarta linea imprimos el valor de la posicion x de la variable b y nos devolvio correctamente el valor, en la siguiente linea a la referencia, es decir b, le asignamos un nuevo valor pero no solamente modifico b sino tambien a la tabla a porque observen en la siguiente linea al momento de imprimir el valor de a se modifico, nuestras ultimas dos lineas son para eliminar la tabla en la penultima linea y la ultima tambien porque queda una referencia a algo que no existe y puede ocasionar errores, aunque Lua se encargara con el tiempo de borrar todas estas referencias perdidas y reutilizar la memoria recuperada, veamos otro ejemplo:

tinchicus@dbn001dsk:~/lenguaje/lua$ lua5.3
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> a = {}
> for i=1,1000 do a[i]=i*2 end
> print(a[9])
18
> a["x"] = 10
> print(a["x"])
10
> print(a["y"])
nil
>

En este caso primero crearemos la tabla, luego la llenaremos con 1000 entradas y en cada entrada le asignaremos la posicion (i) multiplicado por 2, observen como al recuperar una nos trajo el valor, despues asignamos una nueva entrada por fuera de los anteriores y vean como fue agregado y se pudo recuperar, en la ultima linea intentamos recuperar una posicion que no existe y nos devolvio un valor nil, recuerden que nil representa a un valor inexistente, una forma equivalente de poder recuperar posiciones es por medio de la tabla y el nombre de la referencia, la sintaxis es la siguiente:

a.x = 10		Equivale a a["x"] = 10
print(a.x)		Equivale a print(a["x"])
print(a.y)		Equivale a print(a["y"])
Anuncios

Para Lua las dos formas son equivalentes y se pueden mezclar libremente, al igual que trabajar con objetos nosotros al ver un punto sabremos que es una clave de referencia de la tabla, esto nos indica que la tabla esta siendo usada como record, obviamente el uso de la forma va a depender con cual nos resulte mas comodo porque los programadores mas viejos se sentiran mas en linea con la version mas tradicional, veamos un error tipico de los principiantes:

tinchicus@dbn001dsk:~/lenguaje/lua$ lua5.3
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> a={}
> x="y"
> a[x]=10
> print(a[x])
10
> print(a.x)
nil
> print(a.y)
10
>

Como vimos anteriormente al asignar un valor a la variable y despues nosotros usamos la variable para la posicion de la tabla, no usara la variable sino el valor contenido en el mismo, observen como en el primer print usamos el valor de la variable, en ese caso no hubo error porque es correcto, en la siguiente linea es nil porque x no existe, y en la siguiente linea si porque esta vez usamos el valor de x no a x, como dijimos antes este tipo se puede utilizar para crear arrays simples y para ello debemos usar numeros enteros para las posiciones, si bien nosotros podemos iniciar con cualquier numero y en cualquier orden lo mas usual es iniciarlo con el valor 1, a diferencia del 99.9% de los lenguajes que inician con 0.

En el post anterior hablamos de operador de longitud y dijimos que mostraba la cantidad de caracteres de una cadena pero en realidad muestra la posicion del ultimo caracter, veamos un ejemplo:

tinchicus@dbn001dsk:~/lenguaje/lua$ lua5.3
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> a={}
> for i=1,10 do
>> a[i]=i*2
>> end
> print(#a)
10
>
Anuncios

En este caso vean como nos devolvio la cantidad de entradas y no de caracteres, a diferencia que vimos en el post anterior, hablemos sobre una particularidad de las tablas, en una tabla con indices no inicializados van a tener valores nil y a la hora de trabajar con el operador anterior podriamos tener el inconveniente de no poder obtener el resultado verdadero porque este operador considera que el valor nil es el final de la tabla, y si poseemos huecos puede terminar antes del final de la tabla, para evitar esto podemos usar la funcion table.maxn la cual nos devolvera el numero maximo de las entradas, un ultimo detalle sobre la indexacion, nosotros podemos indexar de cualquer forma como hablamos antes pero por un tema de equivalencia no es lo mismo usar el indice 0 que el indice “0” porque son dos tipos distintos, de una forma similar las entradas “+1”, “01” y “1” son todas diferentes, para evitar esto lo mas recomendable es usar una conversion explicita, veamos un ejemplo:

tinchicus@dbn001dsk:~/lenguaje/lua$ lua5.3
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> i=10; j="10"; k="+10"
> a={}
> a[i]="nuevo valor"
> a[j]="otro valor"
> a[k]="otro valor mas"
> print(a[j])
otro valor
> print(a[k])
otro valor mas
> print(a[tonumber(j)])
nuevo valor
> print(a[tonumber(k)])
nuevo valor
>

Observen este ejemplo, en el primer caso creamos tres variables distintas, luego creamos la tabla, despues creamos tres entradas en base a las variables creadas anteriormente, observen las dos siguientes lineas donde nos muestras los valores asignados a las posiciones que creamos, pero las siguientes dos lineas convertimos los valores de j y k a numero, lo cual equivale a la primera variable y por esto observen que no nos devuelve los valores anteriores sino el valor de la primera posicion de nuestra tabla.

Anuncios

En resumen, hoy hemos visto tablas, que son, como trabajan, a que equivalen en otros lenguajes, otras formas de trabajar con la misma, algun error con el mismo, otras caracteristicas de las mismas, espero les haya sido util sigueme en Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00