Iterador
# Iterador

En programación de computadoras, un iterador se refiere al objeto que permite al programador recorrer un contenedor, (una colección de elementos) particularmente listas.

Varios tipos de iteradores se suministran frecuentemente a través de una interfaz del contenedor. La interfaz y la semántica de un determinado iterador suelen ser fijas. Un iterador sigue una ruta y da acceso a elementos de datos del contenedor, pero no realiza iteración (es decir, no tiene total libertad, como sugiere su terminología). Un iterador se comporta como el cursor de una base de datos. Los iteradores se empezaron a utilizar en el lenguaje de programación CLU en 1974.

## Descripción

### Iteradores externos y un patrón iterador

Un iterador externo puede ser imaginado como un tipo de puntero que tiene dos operaciones primarias: referenciar un elemento particular en la colección de objetos y modificarse para apuntar al siguiente elemento. También debe existir una manera de crear un iterador para apuntar a algún primer elemento así como alguna manera de determinar cuando el iterador ha agotado todos los elementos en el contenedor. Dependiendo del lenguaje y del uso deseado, los iteradores también pueden proporcionar operaciones adicionales o mostrar comportamientos diferentes.

El propósito primario de un iterador es permitir que un usuario procese cada elemento de un contenedor mientras aísla al usuario de la estructura interna de un contenedor. Esto permite que el contenedor almacene elementos de la manera que él desee permitiendo que el usuario trate como si fuera una simple lista o secuencia. Una clase iterador normalmente se proyecta en estrecha coordinación con la clase contenedor correspondiente. Normalmente, el contenedor proporciona los métodos para crear iteradores.

### Generadores

Una manera de implementar iteradores es utilizar un tipo especial de su subrutina, conocido como un generador, que puede producir valores para quien lo llama varias veces (en lugar de devolver sólo uno).

A continuación se puede ver un ejemplo de un generador que devuelve los números de Fibonacci mediante la declaración siguiente código (en Python):

### Iteradores implícitos

Algunos lenguajes orientados a objetos como C#, Delphi (versiones más recientes), Go (lenguaje de programación), Java , Lua, Perl, Python, Ruby, ofrecen una manera intrínseca de iteración a través de elementos de un objeto contenedor sin la introducción de un objeto iterador explícito. Un objeto iterador real puede existir en realidad, pero si existe, no se expone dentro del código fuente del lenguaje.

Los iteradores implícitos se manifiestan generalmente por una declaración "foreach" (u otra equivalente), como en el siguiente ejemplo en Python:

Otras veces pueden ser creados por un objeto de la colección, como en este ejemplo en Ruby:

Este estilo de iteración es llamado a veces "iteración interna" debido a que su código se ejecuta completamente dentro del contexto del objeto iterable (que controla todos los aspectos de la iteración) y el programador sólo proporciona la operación para ejecutar en cada paso (utilizando una función anónima).

Los lenguajes que soportan comprensión de lista o construcciones similares también pueden hacer uso de iteradores implícitos durante la construcción de la lista de resultados, como en Python:

A veces la naturaleza oculta implícita es sólo parcial. El lenguaje C++ tiene pocas plantillas de función, como for_each, que permiten la iteración implícita similar. Sin embargo, todavía requieren objetos interactivos explícitos como su entrada inicial. Una vez inicializada la iteración subsiguiente ocurre implícitamente sin el uso continuado de cualquier objeto iterador expuesto.

## En diferentes lenguajes de programación

### Java

Como un patrón para recorrer listas, conjuntos, mapas, etc:

Es lo que usted llamaría "cursor" si escribiera procedimientos almacenados en SQL. Por lo tanto, no es un concepto nuevo o extraordinariamente difícil de manipular.

Si se sabe que la List es un ArrayList, entonces no hay problemas en el uso del índice en vez de utilizar un Iterator. Para todos los demás tipos (LinkedList, Set, Map, etc.) hay que usar el Iterator.

Y de todos modos se continúa usando el for:

En Java 5, el iterador puede incluso esconderse:

En el siguiente ejemplo tenemos la clase principal MenuItem que simplemente es un ítem de un menú que tiene un nombre, este podría ser un menú que aparecería en la sección de menú de un sitio, por ejemplo:

### Python

Los iteradores en Python son una parte fundamental del lenguaje y en muchos casos pasan desapercibidos, pues se utilizan implícitamente en la declaración for(foreach), en comprensiones de listas y en expresiones generadoras. Todos los tipos de colección nativos de Python soportan iteración, así como muchas clases que son parte de la biblioteca estándar. En el siguiente ejemplo se muestra una iteración implícita típica sobre una secuencia:

Los diccionarios de Python (una forma de matriz asociativa) también pueden ser iterados directamente, cuando se devuelven las claves del diccionario; o el método items de un diccionario puede ser iterado sobre donde produce pares clave, valores correspondientes como una tupla:

Los iteradores, sin embargo, se pueden utilizar y definir explícitamente. Para cualquier tipo de secuencia iterable o clase, la función nativa iter se utiliza para crear un objeto iterador. El objeto iterador puede entonces ser iterado con la función next, que utiliza el método __next__ internamente, que devuelve el siguiente elemento en el contenedor (La declaración anterior es aplicable en Python 3.x. En Python 2.x, es equivalente el método next). Una excepción StopIteration será lanzada cuando no queden más los elementos. El siguiente ejemplo muestra una iteración sobre una cadena equivalente utilizando iteradores explícitos:

Cualquier clase definida por el usuario puede soportar iteración estándar (implícita o explícita), mediante la definición de un método __iter__ que devuelve un objeto iterador. El objeto iterador, entonces, debe definir un método __next__ que devuelve el siguiente elemento y un método __iter__ que devuelve el siguiente objeto iterador a utilizar.

Los generadores de Python implementan este protocolo de iteración.

### PHP

El foreach fue introducido en la versión 4.0 de PHP y hecho compatible con los objetos como valores en 4.0 Beta 4. Sin embargo, el soporte a iteradores se añadió en PHP 5 a través de la introducción de la interfaz interna atravesable (no implementable en el código PHP, sino en lenguaje C.

Las dos interfaces principales para la implementación de código PHP que permiten que los objetos sean iterados a través del bucle foreach son Iterator y IteratorAggregate. Este último no requiere que la clase de implementación declare todos los métodos requeridos, sino que implementa un método a para acceder (getter) (getIterator) que devuelve una instancia de Traversable . La Biblioteca estándar de PHP proporciona varias clases para trabajar con iteradores especiales. PHP también soporta generadores desde la versión 5.5.

La implementación más simple es envolviendo un arreglo, esto puede ser útil para sugerencia de tipo y ocultación de información.

Todos los métodos de la clase de ejemplo se utilizan durante la ejecución de un bucle foreach completo (foreach($iterator as $key => $ current)). Los métodos del iterador se ejecutan en el siguiente orden:

* $iterator-> rewind asegura que la estructura interna comienza desde el principio.
* $iterator-> valid devuelve true en este ejemplo.
* $iterator-> current el valor devuelto se almacena en $value .
* $iterator-> key el valor devuelto se almacena en $key .
* $iterator-> next avanza al siguiente elemento de la estructura interna.
* $iterator-> valid devuelve "false" y el bucle se anula.

El siguiente ejemplo ilustra una clase PHP que implementa la interfaz Traversable, que podría ser envuelta en una clase IteratorIterator para actuar sobre los datos antes de ser devuelta al bucle foreach. El uso junto con la constante MYSQLI_USE_RESULT permite que los scripts PHP iteren conjuntos de resultados con miles de millones de filas con muy poco uso de memoria. Estas características no son exclusivas de PHP ni de sus implementaciones de clase MySQL (por ejemplo, la clase PDOStatement implementa la interfaz Traversable).

