En esta sesión, hablaremos sobre iteradores y colecciones.
Veremos como recorrer fácilmente las colecciones Gracias a los iteradores en Pharo.
Entenderá El poder de los iteradores en Pharo.
Revisaré los iteradores principales que puede utilizar.
Un primer ejemplo
este es el código que debería escribir en Java
para recorrer una colección
Exploraré las personas de la colección.
Para extraer la lista de personas (objecto Persona).
En Pharo, escribiría este código.
Usaría el iterador collect: Hablaremos de el más tarde.
Recoge todos los nombres de personas.
Por cierto, en Java 8, la última versión de Java
Han presentado los bloques,
el equivalente de cierres léxicos.
Como resultado, la sintaxis se acerca a Pharo.
Pero en Pharo, lo hemos tenido desde el comienzo.
Está en el corazón del idioma.
Da gran poder de expresión. a un programador
Hay muchos iteradores.
Primero, hay "collect:" ¿cual es el uso de "collect:" cuando se envía a una colección?
Esta es una colección de números positivos y negativos.
Envío el mensaje "collect:", y paso un bloque
Cada vez que navega por la colección,
el parámetro del bloque será a su vez: 2, -3, 4, etc.
Luego envía el mensaje abs, para absoluto
Significa que quieres el valor absoluto de este numero
Una vez que haya aplicado el bloque a cada elemento de la colección,
agrega los resultados en una nueva colección.
El resultado devuelto por collect Es una nueva colección.
El bloque se ha aplicado a cada elemento de la colección:
el valor absoluto de 2, el valor absoluto de -3, que es 3,
el valor absoluto de 4, 4, el valor absoluto de -35, 35.
y el valor absoluto de 4, 4.
Lo interesante que debe recordar
es que debe pensar en el objeto.
Pedimos a la colección hacer algo por nosotros
La colección navega por sus propios elementos por sí misma.
Proporcionamos el procesamiento de cada elemento
Ahí es donde está el secreto de los iteradores.
Este es otro ejemplo de "collect:"
Esta es una colección a la que envío el mensaje "collect:"
En el bloque, preguntaré cada vez
si el elemento es inpar.
Voy a agregar todos los resultados
false, true, false, true.
Por supuesto, puede escribir
lo que normalmente escribiría en otros idiomas
sin bloques e iteradores.
Podría escribir: tomo la colección,
construyo una colección de resultados.
Recorro desde uno al tamaño de la colección.
Usaré do
Recorro la colección y cada vez lo agrego a la colección de resultados.
Puedes escribir todo esto. Es exactamente lo mismo.
Tu decides. ¿Quieres escribir algo simple?
o algo complicado? Esa es la pregunta.
Prefiero la primera solución.
En la jerarquía de las colecciones Pharo,
hay algo crucial: todas las colecciones son polimórficas
y heredan de la clase Collection. Entonces tienes una API común.
La ventaja es que los iteradores también funcionaran
con la mayoría de colecciones.
Realmente se trata de pensar en un objeto:
le pide a la colección Iterar sobre sus elementos para nosotros.
No sabemos si estamos usando un diccionario.
No queremos saber sobre la lógica interna de claves, valores, etc.
Entonces le pide a la colección que se recorra
y procese sus elementos.
Se pueden usar muchos iteradores para hacer esto. Ya vimos "do:" y "collect:"
Hay mas: "select:", "reject:", "detect:", etc.
Estudiaremos algunos de estos Más adelante en este curso.
"do:" es el iterador más simple.
Navega por todos los elementos de la colección, lo muestro en el Transcript.
Ya lo vimos muchas veces.
Este es un nuevo iterador, "select:".
Quiero obtener todos los elementos de la colección
que coinciden con un criterio.
Quiero todos los elementos inpares de la colección
Envío "select:" a la colección.
Paso un bloque
Siempre que el valor del bloque sea true,
el elemento involucrado se agrega a la colección de resultados.
Es exactamente lo mismo que "select: #odd"
Cuando tengo un bloque aquí
o lo que equivale mensaje unario de envío al elemento de la colección,
el parámetro del bloque,
Puedo mostrar el nombre del mensaje para ser enviado como un símbolo.
Es incluso más corto.
Solo funciona con mensajes unarios.
Puede usar otros tipos de iteradores. como "reject:"
Quiero deshacerme de los elementos inpares. de la colección
En los resultados, Solo tendré elementos inpares.
O quiero usar "detect:"
Quiero detectar el primer elemento que coincide con un criterio
el valor del bloque debe ser true.
Quiero el primer elemento inpar de la colección
A veces, quieres detectar el primero elemento que coincide con un criterio
Si no hay ninguno, desea un valor predeterminado:
"detect: ifNone:"
Si no hay coincidencia, devolverá el valor de este bloque,
que es 0
Hay otros iteradores que facilitan la vida al programador.
Por ejemplo, "anySatisfy:"
comprueba si un objeto cumple un criterio
Puede comprobar si todos los objetos cumple con el criterio
Puede navegar por la colección al revés, desde el final.
Puede navegar por la colección utilizando un indice o explorar sus elementos por pares.
Puede navegar por todas las permutaciones circulares, etc.
Hay muchos iteradores.
También puede crear otras nuevas.
Quiere explorar una colección (1 2 3)
con otra colección (10 20 30).
En el bloque, "do:", tengo ":x" y ":y" que son dos parámetros.
":x" es un elemento de la primera colección
":y", de la segunda
al multiplicar estos elementos
Los resultados son 10, 40 y 90.
Por supuesto, con este iterador, las dos colecciones deben ser de igual longitud.
Hay otras formas
aquí utilizo "do: separatedBy:"
Tengo una colección Examino cada elemento.
Cada vez que se navega un elemento,
Doy valor a un bloque que coincide con una coma.
Entonces puedo navegar a,
mostrar una coma, luego b, una coma, luego c.
Entre cada elemento, Realizo una acción.
Este es el iterador "groupedBy:"
Puedo usarlo para agrupar los elementos de una colección
en función de un criterio.
Envié este mensaje a la colección 1 2 3 4 5 6 7.
Como resultado, obtengo un diccionario:
todos los elementos que devolvieron false a este criterio,
que fue #even, los elementos pares.
Como puede ver, Tengo todos los elementos inpares.
Todos los elementos pares devueltos son true.
A menudo es el caso, cuando computa,
que tiende a anidar colecciones en colecciones
Termina con grandes niveles de anidación.
Este es un ejemplo creado a mano.
Estas son colecciones anidadadas en colecciones.
Nos gustaría aplanar la colección para igualarlo todo.
En Pharo, hay una manera fácil
el iterador "flatCollect:"
Examino los elementos y creo una nueva colección donde todo es plano.
Entrega la colección 1 2 3 4 5 6.
Los niveles de anidamiento han desaparecido.
No tengo la intención de presentarle cada iterador de Pharo.
Sería largo y desagradable. Solo quiero mostrar que hay muchos.
Puede definir su propio.
Al leer los métodos en la clase Collection
averigua sobre ellos.
Por ejemplo, empiece por los iteradores que ya conoce.
Puedo preguntarme cómo se implementa "do:"
Lo busco en la jerarquía de colecciones.
Me doy cuenta de que está implementado como SequenceableCollection.
El método "do:" selecciona aBlock como su parámetro.
Esta es la implementación de la colección.
1 to: self size do: [i:|aBlock value: (self at: i)].
Evalúo el bloqueo utilizado como parámetro
pasándole el elemento en el indice i.
Es muy fácil.
En Pharo, los iteradores son muy poderosos, como acabamos de ver
Cada colección apoya los iteradores polimórficamente.
Los programadores usan iteradores
que se implementan en clases de Collection
de acuerdo con la colección ellos representan.
Puede definir otros nuevos. Es muy interesante.
Puedo definir mis propios iteradores en las clases de Collection
Hay un pequeño matiz quiénes conocen el patrón de diseño del iterador
un desarrollador no puede elegir cuándo pasa al elemento siguiente.
La colección lo decide internamente.
no se envía explícitamente el mensaje next al iterador
Es un matiz para aquellos que conocen el patrón de diseño del iterador.
Los iteradores son muy poderosos.
Son los mejores amigos del programador.
Facilitan la escritura de programas
Puede escribir código breve, simple, y elegante.
Se asegura
la encapsulación de datos en una colección.