Escribe tu búsqueda

Curso Xojo: Diccionarios

Compartir

En la anterior entrega vimos el tipo de dato Collection, capaz de contener cualquier otro tipo de dato como si se tratase de un registro de una base de datos, y sobre los que es posible acceder posteriormente mediante una clave de tipo string o bien a través de un índice numérico, como si se tratase de un Array.

Obviamente, su característica de almacenamiento secuencia significa que no es el más óptimo si lo que deseamos es la máxima velocidad en el acceso a grandes volúmenes de información almacenados bajo una variable de tipo Collection.

Afortunadamente Xojo ofrece otro tipo de dato que reúne las ventajas del Collection sin sus inconvenientes, proporcionando la máxima velocidad de acceso. Se trata del Dictionary (http://docs.xojo.com/index.php/Dictionary).

Diccionarios, la colección perfecta

En tus aplicaciones Xojo utilizarás este tipo de colección de datos con una gran frecuencia, dado que elimina los problemas de rendimiento de los Collection al sustituir la búsqueda secuencial de elementos por una tabla ‘hash’. Esto significa que el tiempo de búsqueda no se ve determinado, en gran medida, por el número de elementos contenidos en la colección.

Adicionalmente, mientras que en las Collection se limitaba el uso del tipo string para definir la clave asociada a un elemento, mientras que el valor propiamente dicho podría ser absolutamente cualquiera (es decir, una variante), en el caso de los diccionarios podemos utilizar cualquier tipo de dato tanto para definir tanto la clave como para asignar el valor asociado con dicha clave. Por ejemplo:

  Dim d as new dictionary

  dim miImagen as new Picture(320,320,32)

  d.value("rojo") = rgb(255,0,0)

  d.value( rgb(255,0,0) ) = "Color rojo"

  d.value( miImagen ) = "Fotografía de perfil"

  d.value("fotografía de perfil") = miImagen

  MsgBox d.Value( rgb(255,0,0) )

  dim c as color = d.Value("rojo")

Como puedes ver en el anterior código, en el primer caso utilizamos como clave del diccionario ‘d’ la clave de tipo string “rojo”, asociándola con el color RGB rojo puro (valores 255, 0, 0). En el segundo caso hacemos justamente lo opuesto, y utilizamos una clave de tipo Color con la descripción del mismo.

 

Como puedes ver, posteriormente accedemos a la clave de tipo color para que el MsgBox muestre su descripción, mientras que a continuación declaramos una variable de tipo Color ‘c’ sobre la cual asignamos el valor del diccionario a través de la clave “rojo”. Esto es lo que puedes ver en la parte inferior derecha (columna “Variables”) una vez que hemos detenido la ejecución del programa en el depurador.

Ahora bien, dado que Xojo utiliza hash para crear una tabla de accesos a los contenidos del Diccionario, hemos de tener muy en cuenta el uso de un tipo string para la clave puesto que mientras que las cadenas “color” y “Color” serán interpretadas como la misma, no ocurrirá así si utilizamos “Árbol” o “árbol” (¡sus hash son distintos!). Esto es lo que hemos hecho en el código del siguiente ejemplo, sustituyendo las claves “rojo” del ejemplo anterior por “Árbol” para la asignación y, erróneamente, “árbol” para su posterior recuperación:

 
 

Como puedes ver en la imagen, un error tan simple como ese en nuestro código producirá una Excepción al no haber encontrado la clave correspondiente en el diccionario. Eso significaría que el programa interrumpiría anormalmente su ejecución saliendo al depurador si estás trabajando desde el IDE, o bien al sistema operativo si se tratase ya de una aplicación compilada. ¡Ojo con el uso de tildes y otros caracteres no ASCII en la definición de claves para los Diccionarios!

Identificar una clave en el Diccionario

Precisamente para evitar ese tipo de errores, ya sea por ‘bugs’ en la escritura de las claves o bien por pasar como clave cualquier otro tipo no definido, el Diccionario nos proporciona el método HasKey, y cuya utilidad es la de devolvernos un valor cierto (True) en el caso de que la clave que le pasemos esté comprendida entre las utilizadas en el diccionario, o bien falso (False) en el caso de que no sea así. Por tanto, en el código que trabaja con diccionarios suele ser muy frecuente el siguiente tipo de construcción:

  Dim c as Color

  if d.HasKey("árbol") then

c = d.Value("árbol")

 else

MsgBox( "Clave no encontrada!" )

 c = RGB(255, 255, 255)

 end

Sin embargo también encontramos entre los métodos de Xojo otro que permite resolver este tipo de situaciones con mayor elegancia. Se trata de Lookup (http://docs.xojo.com/index.php/Dictionary.Lookup), donde obtendremos el valor asignado a la clave pasada, si esta exista, o bien el valor por omisión que indiquemos en el método si no se encuentra la clave en cuestión. De este modo, la anterior comprobación quedaría resuelta así:

dim c as Color

c = d.lookup( "árbol", RGB(255, 255, 255) )

¿Cuál será el valor de ‘c’ en este ejemplo? ¿Y en el siguiente?:

dim c as Color

c = d.lookup( "Árbol", RGB(255, 255, 255) )

Efectivamente, en el primer ejemplo la variable ‘c’ tendrá asignado el color blanco (255, 255, 255), mientras que en el segundo se podrá recuperar efectivamente el color rojo contenido bajo la clave “Árbol” que sí existe como parte del diccionario.

Obtener el valor de una Clave de Diccionario

También es posible accede a los contenidos de un Diccionario mediante el uso de un índice para las claves que, tal y como ocurre con los Array, tiene establecido el valor base del primer elemento en cero. Todo ello a través del método Key (http://docs.xojo.com/index.php/Dictionary.Key). Por tanto, para acceder al primer y segundo elemento de nuestro Diccionario podríamos utilizar lo siguiente:

dim c as color = d.value( d.key(0) )

dim s as string = d.value( d.key(1) )

Como puedes ver, hemos declarado en nuestro ejemplo variables con el tipo que sabemos que contiene cada una de las posiciones del diccionario. Pero para que nuestro código resulte más seguro (y abstracto sobre los tipos de los elementos) podríamos haber utilizado lo siguiente:

dim c, s as variant

c = d.value( d.key(0) )

s = d.value ( d.key(1) )

El uso de una asignación u otra dependerá de cómo diseñemos nuestra aplicación, en cualquier caso; pero siempre está bien saber cuáles son las opciones disponibles.

Como has visto el método Key se encarga de devolvernos el valor utilizado como clave en el diccionario para la posición indicada. Pero, ¿cómo sabemos cuál es el máximo valor para un índice? Como probablemente ya intuyas, dicho valor lo obtendremos mediante la propiedad Count del diccionario. De este modo, podremos iterar por todas las claves de un diccionario de la siguiente forma (asumiendo que todas las claves sean de tipo string, en este ejemplo):

for n as integer = 0 to d.count-1

  msgBox d.key( n )

next

¿Se te ocurre otra forma de iterar que ya hallamos visto en anteriores entregas? (echa un ojo a los métodos de Dictionary) La solución un poco más adelante.

Obtener todas las claves y valores de un Diccionario

En nuestras aplicaciones probablemente tengamos la necesidad de obtener bien todos los valores contenidos en un diccionario, todas las claves, o bien ambos pares. Para ello, disponemos en el tipo Dictionary de dos métodos tremendamente útiles: Keys y Values.

Como habrás adivinado, con el primero obtendremos como resultado un Array cuyo contenido será el de todas las claves utilizadas en el diccionario. Por ejemplo:

Dim d as dictionary

d.value("Primero") = 1

d.value("Segundo") = 2

d.value("Tercero") = 3

d.value("Cuarto") = 4

d.value("Quinto") = 5

dim a() as Variant = d.keys

 
 

Como puedes ver en la imagen del Depurador, en la columna inferior derecha hemos inspeccionado el contenido de la variable de Array ‘a’ y podemos ver que los contenidos se corresponden efectivamente con todas las claves de nuestro diccionario.

dim v() as Variant = d.values

¿Cuáles serán los contenidos de la variable ‘v’?

En el anterior apartado habíamos dejado pendiente otra forma de iterar por las claves de un diccionario, ahorrando así la necesidad de hallar previamente el valor máximo del índice o bien recuperarlas sobre un array intermedio. La solución es la siguiente:

For each s as string in d.keys

    msgBox s

next

Eliminar una entrada del Diccionario, o borrar sus contenidos

Por último, también tendremos que echar mano de las claves si lo que deseamos es eliminar una entrada del Diccionario. Y al igual que ocurre con la recuperación de valores, hemos de asegurarnos de que dicha clave exista, de lo contrario obtendremos el mismo tipo de Excepción en la ejecución debido a que no se ha encontrado la clave.

Así, volviendo a nuestro ejemplo original, podremos borrar el par de clave-valor correspondiente a RGB(255,0,0) – “Color rojo” con la siguiente línea:

d.remove( rgb(255, 0, 0)

O bien con algo más de seguridad:

if d.hasKey( rgb(255, 0, 0) )

  d.remove( rgb(255, 0, 0) )

end if

Por otra parte, si lo que deseamos es vaciar el Diccionario por completo, tan sencillo como utilizar la siguiente línea de código:

d.clear

Al ejecutarla tendremos un diccionario limpio y listo para usar, además de que se habrá recuperado la memoria utilizada por el mismo, claro está.

Hacia los pares de valores

Recordarás que al ver la estructura interna del tipo Collection obteníamos un elemento de tipo Pair, y en el caso de los Diccionarios también existe una misma asociación de “par” clave-valor. Pues bien, no te sorprenda, porque Xojo incluye un último tipo que también podríamos denominar de ‘colección’ y que se llama precisamente Pair. Echa un ojo a la documentación, porque lo veremos con detalle en la próxima entrega.

Enlaces de Interés sobre Xojo

Artículos anteriores

Javier Rodríguez (@bloguintosh) es desarrollador OS X e iOS, director de Macsoluciones.com. Puedes contactar con él para el desarrollo de aplicaciones para Mac e iOS en entornos empresariales así como consultoría y formación.

Dejar un comentario

Twitter
Visit Us
Tweet
YouTube
Pinterest
LinkedIn
Share