sábado, 13 de julio de 2013

Iterador en Scala


En Scala trabajar con conjuntos (List, Set, Map) es muy cómodo (map, filter...) pero ¿Qué pasa si no necesitas calcular el conjunto completo?

Para estos casos Scala dispone de Iterator, View y Stream, que posibilitan el cálculo bajo demanda.

Ejemplo

Encontrar un nombre de archivo no existente.
Supongamos que la función de cálculo de nombre (randomName en este caso) es costosa.

Alternativa funcional: Defino un conjunto (lista de nombres) y la operación a realizar (buscar el primero no existente).
  1. Obtengo un iterador a la lista de nombres ¡Que todavía no están generados!
  2. Usando el iterador busco el primero que no exista (paths.find(!_exists)) calculando únicamente los nombres que he necesitado.


Alternativa iterativa: Defino un bucle que calcula nombres y comprueba si no existe, finalizando cuando encuentre uno no existente. Posiblemente más propenso a errores (más variables, condición de finalización) y menos legible.

Posibles dudas

¿val o def ?
Val guarda el iterador, que puedes usar para obtener valores consecutivos. Por ejemplo: iterador.next; iterador.next;
Def crea un nuevo iterador cada vez que lo llamas.

¿En qué se diferencia iterator de stream? Simplificando: Stream guarda los valores en memoria al calcularlos, con lo que no tiene que recalcularlos si vuelves a recorrer la lista.

¿En qué se diferencia iterator de view? View permite acceso aleatorio al valor. Iterator recorre la lista avanzando y calculando cada elemento. Realmente View no es un contenedor, si no un envoltorio alrededor del contenedor que hace las peticiones cuando es necesario, lo que para elementos pequeños puede suponer una sobrecarga a considerar. Más información sobre las diferencias entre iterator y view en stackoferflow.

No hay comentarios:

Publicar un comentario