Iterador

Este artículo puede contener trabajos no publicados o declaraciones no verificadas (octubre 2014).

Puede ayudar agregando referencias o eliminando contenido no publicado. Consulte la página de discusión para obtener más detalles.

En la ingeniería de software , el iterador es un patrón de diseño (patrón de diseño) el comportamiento .

Un iterador es un objeto que le permite navegar por todos los elementos contenidos en otro objeto, generalmente un contenedor ( lista , árbol , etc.). Un sinónimo de iterador es cursor , especialmente en el contexto de bases de datos .

Descripción

Un iterador parece un puntero con esencialmente dos primitivas: acceder al elemento apuntado actual (en el contenedor) y moverse para apuntar al siguiente elemento. Además, es necesario poder crear un iterador que apunte al primer elemento; así como determinar en cualquier momento si el iterador ha agotado todos los elementos del contenedor. Varias implementaciones también pueden ofrecer comportamientos adicionales.

El objetivo de un iterador es permitir a su usuario navegar por el contenedor, es decir acceder secuencialmente a todos sus elementos para aplicarles procesamiento, aislando al usuario de la estructura interna del contenedor, potencialmente compleja. Por lo tanto, el contenedor puede almacenar los elementos como quiera, al mismo tiempo que permite al usuario tratarlo como una simple lista. La mayoría de las veces, el iterador se diseña al mismo tiempo que la clase de contenedor que tendrá que navegar, y será el propio contenedor el que creará y distribuirá los iteradores para acceder a sus elementos.

Diferencias con la indexación

En los lenguajes de procedimiento, un índice se usa a menudo en un bucle simple , para acceder secuencialmente a todos los elementos, en particular a una matriz. Aunque este enfoque todavía es posible en la programación de objetos para algunos contenedores, el uso de iteradores tiene ciertas ventajas:

La posibilidad de modificar un contenedor durante una iteración se ha vuelto necesaria en la programación de objetos moderna, donde las relaciones entre los objetos y el efecto de ciertas operaciones pueden convertirse en un dolor de cabeza. Al utilizar un iterador tan "robusto", nos ahorramos estos inconvenientes.

Usando un iterador explícito

En un lenguaje orientado a objetos como C #, un iterador es un objeto que implementa la interfaz IEnumerator.

interface IEnumerator { void Reset(); bool MoveNext(); object Current { get; } }

El iterador se utiliza para acceder a los valores disponibles.

IterateurTypique iterateur = new IterateurTypique(); iterateur.Reset(); // optionnel : cet appel peut ne pas être effectué. while(iterateur.MoveNext()){ Console.WriteLine(iterateur.Current); }

Una de las muchas posibles implementaciones de objetos podría tener este aspecto.

class IterateurTypique : IEnumerator { private string[] _chainesAParcourir = new string[] { "TF1", "France2", "FR3", "Canal+" }; private int _positionCourante = -1; public void Reset() { _positionCourante = -1; } public bool MoveNext() { if( _positionCourante + 1 >= _chainesAParcourir.Length ) return false; _positionCourante +=1; return true; } public object Current { get { return _chainesAParcourir[_positionCourante]; } } }

La interfaz IEnumerableC # permite cambiar a un iterador implícito.

interface IEnumerable { IEnumerator GetEnumerator(); }

Las matrices, listas o diccionarios de C # son tipos derivados IEnumerabley tienen un método GetEnumerator()que llama al iterador explícito.

La instrucción foreach de C # llama a este método GetEnumerator()e itera explícitamente mientras oculta los detalles de la implementación.

if(Television is IEnumerable) { foreach(object chaine in Television) { Console.WriteLine(chaine); } }

Iteradores implícitos

Los lenguajes orientados a objetos como Perl y Python proporcionan una forma "interna" de iterar sobre los elementos de un contenedor sin introducir explícitamente un iterador. Esto a menudo se implementa mediante una estructura de control para cada uno , como en los siguientes ejemplos:

# Tcl: itérateur implicite foreach val $list { puts stdout $val } # Perl: itérateur implicite foreach $val (@list) { print "$val\n"; } # Python, itérateur implicite for Value in List: print Value // PHP, itérateur implicite foreach ($list as $value) print $value; // Java, J2SE 5.0, itérateur implicite for (Value v : list) System.out.print(v); // C#, itérateur implicite foreach (object obj in list) Console.WriteLine(obj ); // C#, itérateur explicite avec un yield foreach (object obj in IndicesPairs() ) Console.WriteLine(obj); // ou IndicesPairs() est une méthode IEnumerable IndicesPairs() { for(int i=0; i<tableau.Length; i++) if(i%2==0) yield return tableau[i]; } # Ruby, itérateur de bloc, (yield) list.each do |value| puts value end # ou each est une méthode de Array tel que : def each for i in 0...size yield(self[i]) end end

Atención, en Javascript, no iteramos directamente sobre los objetos sino sobre su nombre

// Javascript, itérateur implicite for(nom in Object) { var valeur = Object[nom]; alert(Value+" = "+valeur ]); }

El lenguaje C ++ también tiene la función de plantilla std::for_each()que permite iteraciones implícitas similares, pero aún requiere proporcionar objetos iteradores como parámetros de entrada.

Nota  : Ruby, Python y C # desde su versión 2.0, se ofrecen a través de yielduna herramienta específica para construir iteradores.

El lenguaje PHP implementa iteradores desde su versión 5 a través del SPL .