domingo, 23 de octubre de 2016

Colecciones en smalltalk


Como verán sigo leyendo sobre Smalltalk, ahora nos toca ver las colecciones:

Smalltalk cuenta con un framework de colecciones muy poderoso.  No es de extrañar ya que lleva más de 20 años de depuración.

Contamos con numerosos tipos de colecciones (Bag, Set, OrderedCollection, Dictionary, Array, etc) y, a su vez, con un rico y extenso protocolo de mensajes.

A continuación enumero algunos de los mensajes que se les puede enviar a todas las colecciones.

#add: Agrega un objeto (dado como argumento) a la colección.

#addAll: Agrega todos los elementos de la colección dada como argumento a la colección receptora del mensaje.

#remove: Remueve un determinado objeto de la colección. Genera un error si el elemento no es parte de la colección.

#remove:ifAbsent: Remueve un determinado elemento de la colección. Evalúa el bloque dado si el elemento no es parte de la colección.

#removeAll: Remueve todos los elementos del receptor que están contenidos en la colección dada en el argumento.

#do: Evalúa el bloque dado como argumento por cada elemento contenido en la colección.  Este es el principal mensaje de las colecciones y prácticamente todo el resto de mensajes están implementados usando el #do: de alguna forma.  Es interesante ver la implementación de, por ejemplo, los mensajes #select:, #collect:, #anyOne, #detect:ifNone:, #do:separatedBy:, etc.

#do:separatedBy: Evalúa el primer bloque dado como argumento por cada elemento contenido en la colección y evalúa el segundo bloque entre elementos.

#select: Evalúa el bloque dado por cada elemento del receptor como argumento.  Colecciona los elementos en los cuales el bloque evalúa a true (verdadero) en una colección del tipo del receptor. Responde esa colección nueva como resultado.

#reject: Similar a #select: pero colecciona los elementos para los cuales el bloque evalúa a false.

#collect: Evalúa el bloque dado por cada elemento del receptor como argumento.  Colecciona los resultados en una colección del tipo del receptor. Responde esa colección nueva como resultado.

#size Responde el tamaño de la colección.

#anyOne Responde algún elemento de la colección.

#atRandom Responde uno de los elementos del receptor de forma aleatoria.

#detect: Evalúa el bloque dado con cada elemento del receptor. Devuelve el primer elemento donde el bloque evalúa a true. Genera un error si ningún elemento es encontrado.

#detect:ifNone: Evalúa el bloque dado con cada elemento del receptor. Devuelve el primer elemento donde el bloque evalúa a true. Evalúa el otro bloque dado si ningún elemento es encontrado y devuelve el resultado de esa evaluación.

#isEmpty Responde si el receptor está vacío y no contiene elementos.

#includes: Responde si el objeto dado es un elemento del receptor.

#includesAllOf: Responde si todos los elementos de la colección dada están incluidos en la colección receptora.

#includesAnyOf: Responde si algunos de los elementos de la colección dada está incluido en la colección receptora.

#allSatisfy: Responde true si el bloque dado se evalúa a true por todos los elementos de la colección receptora.

#anySatisfy: Responde true si el bloque dado se evalúa a true por algunos de los elementos de la colección receptora.

#noneSatisfy: Responde true si el bloque dado se evalúa a false por todos los elementos de la colección receptora.

#occurrencesOf: Responde cuantas veces está incluido el objeto dado en la colección receptora.

Veamos los Conjuntos: El Set es un tipo de colección que no mantiene ningún orden sobre sus elementos y que no permite que un objeto esté contenido más de una vez.

Un Set representa el concepto matemático de conjunto, donde no tiene sentido decir que un elemento está más de una vez ni tiene sentido hablar de orden.

Ejemplos:
| set |
set := Set new.
set add: 'un string'.
set add: 'otro string'.
set add: 'un string'.
set add: 'otro string'.
set add: 'un string'.
set explore.

"convertir colecciones de diferente tipo a Set para remover los duplicados"
#(5 4 1 2 2 2 1 2 1 2 3 4 3 2 3 4 5) asSet.
'un string que tiene muchos caracteres' asSet.

"Los 2 sets contienen sólo un elemento"
(Set with: 1) = (Set with:1 with:1).

"El orden no importa"
(Set with: 1 with: 2) = (Set with:2 with:1).