Las categorías de clases Collections- son las más prolíficas,
hay 7 de ellas conteniendo 46 clases.
La categoría Collections-Abstract agrupa clases que se
consideran abstractas. Una clase abstracta no se puede instanciar,
su comportamiento se declara pero no se implementa por completo. Es
responsabilidad de sus subclases implementar la parte del comportamiento
que falta.
Una clase abstracta es útil para establecer un conjunto de métodos polimórficos que se espera que cada una de sus subclases concretas especialice. Esto captura y comunica nuestra intención.
Observe cómo se declara el importante método #do:, pero no se implementa:
Collection>>do: aBlock "Evaluate aBlock with each of the receiver's elements as the argument." self subclassResponsibility
A continuación, observa cómo lo implementan dos subclases diferentes de
Collection:
OrderedCollection>>do: aBlock firstIndex to: lastIndex do: [ :index | aBlock value: (array at: index) ]
and:
Dictionary>>do: aBlock super do: [:assoc | aBlock value: assoc value]
Hay que distinguir dos grupos importantes de colecciones: las colecciones con un tamaño fijo y las colecciones con un tamaño variable.
Colección de tamaño fijo. Estas colecciones se agrupan en la
categoría Collections-Arrayed. La más destacada es
Array, cuyo tamaño (el número de elementos que puede contener)
se establece al crear la instancia. Una vez instanciada, no se pueden
añadir ni eliminar elementos de una matriz.
Hay diferentes formas de crear una instancia de Array:
array1 := #(2 'Apple' $@ 4) "create at compile time"
array1b := {2 . 'Apple' . 2@1 . 1/3 } "created a execution time"
array2 := Array with: 2 with: 'Apple' with: 2@3 with: 1/3.
array3 := Array ofSize: 4 "an empty array with a 4 element capacity"
Ejemplo 4.9: Colección con un tamaño fijo
El array array1 y el array1b son un poco
diferentes. El primero se crea y se rellena con su contenido durante la
compilación del código, por lo que sólo se puede rellenar con elementos
literales como enteros, flotantes o cadenas. El segundo se crea en el
momento de la ejecución del código y se puede rellenar con elementos
instanciados en ese momento, como instancias de Fraction o
Point.
Puedes acceder a elementos con una gran variedad de mensajes:
array1 first ⇒ 2 array1 second ⇒ 'Apple' array1 third ⇒ $@ array1 fourth ⇒ 4 array1 last ⇒ 4 array1 at: 2 ⇒ 'Apple' array2 at: 3 ⇒ 2@3 array2 swap: 2 with: 4 ⇒ #(2 1/3 2@3 'Apple') array1 at: 2 put: 'Orange'; yourself ⇒ #(2 'Orange' $@ 4) array1 indexOf: 'Orange' ⇒ 2
Ejemplo 4.10: Acceso a elementos de colección
Utiliza el System Browser para descubrir formas alternativas de acceder a los elementos de una colección.
¿Cuál es el mensaje adecuado para acceder a los dos primeros elementos de la colección
array1?
Ejercicio 4.12: Acceder a parte de una colección
Sin embargo, no se puede añadir ni eliminar ningún elemento:
array1 add: 'Orange' ⇒ Error: 'This message is not appropriate for this object' array1 remove: 'Apple' ⇒ Error: 'This message is not appropriate for this object'
Sin embargo, es posible rellenar una matriz de una sola vez:
¿Rellenar todos los elementos de
array1con ’kiwi’ de una sola vez?
Ejercicio 4.13: Rellenar un array
Colección de tamaño variable. Dichas colecciones se agrupan en
varias categorías de clases: Collections-Unordered,
Collections-Sequenceable, etc. Representan las colecciones más
comunes.
Es destacable OrderedCollection. Sus elementos están ordenados:
los elementos se añaden uno tras otros en secuencia19. Su tamaño
varía dependiendo de los elementos añadidos o eliminados.
coll1 := {2 . 'Apple' . 2@1 . 1/3 } asOrderedCollection
coll2 := OrderedCollection with: 2 with: 'Apple' with: 2@1 with: 1/3
coll3 := OrderedCollection ofSize: 4
Ejemplo 4.11: Colección con un tamaño variable
El acceso a los elementos es idéntico al de una instancia de
Array, pero las colecciones dinámicas te permiten añadir y
eliminar elementos:
coll1 add: 'Orange'; yourself ⇒ an OrderedCollection(2 'Apple' 2@1 1/3 'Orange') coll1 remove: 2@1; yourself ⇒ an OrderedCollection(2 'Apple' 1/3)
Ejemplo 4.12: Añadir, eliminar elementos de un array dinámico
¿Cómo añadir ’Orange’ después de ’Apple’ en
coll1?
Ejercicio 4.14: Añadir un elemento después
Set. Set es una colección desordenada sin elemenntos
duplicados. En cambio, el orden de los elementos no está
garantizado. Observa cómo pi es el primer elemento del set:
set := Set new. set add: 1; add: Float pi; yourself ⇒ a Set(3.141592653589793 1)
Ejemplo 4.13: Colección Set
Se garantiza que no habrá duplicados, incluso con varios tipos
diferentes. Fíjate cómo 1, 3/3 y 1.0
se consideran iguales y no se duplican en el conjunto:
set := Set new. set add: 1; add: Float pi; add: 3/3; add: 1/3; add: 1.0; yourself ⇒ a Set(1/3 3.141592653589793 1)
Ejemplo 4.14: Set, sin duplicados
Una forma muy práctica de crear una instancia Set, o
cualquier otra colección, es crear una matriz dinámica y convertirla con
el mensaje #asSet:
{1 . Float pi . 3/3 . 1/3 . 1.0} asSet
⇒ a Set(3.141592653589793 1/3 1)
Ejemplo 4.15: Convertir un array dinámico
Fíjate en los mensajes de conversión alternativos:
{1 . Float pi . 3/3 . 1/3 . 1.0} asOrderedCollection
⇒ an OrderedCollection(1 3.141592653589793 1 1/3 1.0)
{1 . Float pi . 3/3 . 1/3 . 1.0} asSortedCollection
⇒ a SortedCollection(1/3 1 1 1.0 3.141592653589793)
Para recopilar de forma única la lista de divisores de 30 y 45 (no los divisores comunes):
Set new addAll: #(1 2 3 5 6 10 15 30) ; addAll: #(1 3 5 9 15 45) ; yourself. ⇒ a Set(5 10 15 1 6 30 45 2 3 9)
¿Cómo recopilarás las letras en las frases ’buenos días’ y ’bonjour’?
Ejercicio 4.15: Letras
Dictionary. Un diccionario es una lista de asociaciones de una clave y un objeto. Por supuesto, una clave es un objeto, pero debe responder a pruebas de igualdad. La mayoría de las veces, se utilizan símbolos como claves.
Para agrupar una lista de colores:
| colors | colors := Dictionary new. colors add: #red -> Color red; add: #blue -> Color blue; add: #green -> Color green
Ejemplo 4.16: Diccionario de colores
Hay descripciones más breves:
colors := Dictionary newFrom:
{#red -> Color red . #blue -> Color blue . #green -> Color green}.
colors := {#red -> Color red . #blue -> Color blue .
#green -> Color green} asDictionary
Accedes al color mediante símbolos:
colors at: #blue ⇒ Color blue colors at: #blue put: Color blue darker colors at: #yellow ifAbsentPut: Color yellow ⇒ association `#yellow -> Colors yellow` added to the dictionary
Hay diferentes formas de acceder al contenido de un diccionario:
colors keys. ⇒ #(#red #green #blue) colors keyAtValue: Color green ⇒ #green
Ten cuidado. Los enumeradores clásicos iteran los valores del diccionario:
colors do: [:value | Transcript show: value; space ] ⇒ (Color r: 1.000 g: 1.000 b: 0.078) (Color r: 0.898 g: 0.000 b: 0.000)...
A veces, realmente es necesario iterar toda la asociación clave-valor:
colors associationsDo: [:assoc | Transcript show: assoc key; space; show: assoc value; cr ]
Hay otras variantes que puedes explorar por tu cuenta.
Con el apropiado enumerador, ¿cómo puedes modificar los contenidos del diccionario
colorspara reemplazar sus valores por un bonita cadena capitalizada que represente el nombre del color?
Ejercicio 4.16: Color por nombre
Hay muchas más colecciones por explorar. Ahora ya sabes lo suficiente como para explorar y buscar por ti mismo con el navegador del sistema, y para experimentar con el espacio de trabajo.
Por
supuesto, pueden insertar un elemento entre otros dos. Sin embargo, una
instancia LinkList es más efiiente en este caso.