Entendiendo el patrón iterador "Iterator pattern" en Javascript

El patrón iterador es uno de los patrones de diseño de software más usado en Javascript y también uno de los más sencillos. Es un patrón de comportamiento ya que define como se comunican objetos entre si. De él se extienden importantes aplicaciones que pueden ayudar a definir mejores arquitecturas en aplicaciones web, por lo que su uso y estudio es altamente recomendado. En este post aprenderemos como implementarlo en Javascript y en que situaciones lo podemos usar.

Empecemos por definir este patrón. Básicamente todos hemos usado arrays de esta forma [1,2,3,4] y usualmente si queremos recorrerlo nos inclinamos rápidamente por usar una estructura cíclica como “for” o “while” sin embargo esto hace que el código sea un poco mas imperativa y menos declarativa haciendo que no tengamos tanto control con cada dato unitario dentro del arreglo. Desde este punto es donde empieza a cobrar fuerza este patron iterador ya que básicamente lo que nos provee es una manera de recorrer el arreglo de una manera declarativa. El principal principio de este patrón es permitirnos recorrer colecciones de objetos de una manera que podamos decidir cuando queremos el siguiente objeto y cuando no. Para ello obligatoriamente deben existir tres métodos dentro del iterador:

  • first() –> Retorna siempre el primer objeto de la colección.
  • next() –> Retorna el siguiente objeto de la colección si existe.
  • current() –> Retorna el objeto actual de la colección sobre el estamos parado.

Empecemos entonces por definir una clase llamada iterator con estos tres métodos:

  • js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Iterator {
constructor(collection) {
this.index = 0;
this.collection = collection;
}
first() {
return this.collection\[0\];
}
next() {
this.index += 1;
return this.collection\[this.index\];
}
current() {
return this.collection\[this.index\];
}
}

Como ves usando ES6 hemos definido una clase que permite hacer operaciones muy básicas sobre el array, pero siempre conservando cual es el índice sobre que esta la colección en todo momento. Esto nos permitirá fácilmente movernos sobre ella. Adicionalmente aunque no es obligatorio en la implementación de este patrón. Si es altamente recomendado añadir dos métodos utilitarios mas sobre la clase iterador. Estos son:

  • hasNext() —> Retorna true si hay mas items disponibles en la colección.
  • reset() —> Permite reiniciar el indice para iterar de nuevo sobre la colección.

Veamos entonces como sería la implementación:

  • js
1
2
3
4
5
6
7
8
9
10
11
class Iterator {

reset() {
this.index = 0;
}

hasNext() {
return (this.collection.length > this.index +1);
}

}

Super simple!, una vez que tu clase esté definida puedes usar prácticamente cualquier tipo de array para construir tu iterador y operar sobre él. Veamos un ejemplo de su uso práctico usando un ciclo while:

  • js
1
2
3
4
5
6
7
// Usando un ciclo while
const arr = \[1,2,3,4,5\];
const arrayIterator = new Iterator(arr);
console.log(arrayIterator.first());
while (arrayIterator.hasNext()) {
console.log(arrayIterator.next());
}

De esta manera queda totalmente completo el patrón iterador. Como vez es muy fácil implementar el patrón iterador y su utilidad es casi inmediata. A continuación podrás observar todo el código completo de este ejemplo:

  • js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Iterator {

constructor(collection) {
this.index = 0;
this.collection = collection;
}
first() {
return this.collection\[0\];
}

next() {
this.index += 1;
return this.collection\[this.index\];
}

current() {
return this.collection\[this.index\];
}

reset() {
this.index = 0;
}

hasNext() {
return (this.index + 1 < this.collection.length );
}
}

const arr = \[1,2,3,4,5\];

const arrayIterator = new Iterator(arr);

console.log(arrayIterator.first());


while (arrayIterator.hasNext()) {
console.log(arrayIterator.next());
}

Eso es todo, espero que este post te sea de utilidad y lo puedas aplicar a algún proyecto que tengas en mente y que simplemente te haya ayudado a entender la naturaleza del patrón iterator. déjame un comentario si lograste implementarlo, si quieres añadir alguna otra funcionalidad o si tienes alguna duda no dudes en dejarme un comentario en la parte de abajo, recuerda que si te gustó también puedes compartir usando los links a las redes sociales en la parte de abajo.

Copyrights © 2018 Sebastian Gomez. All Rights Reserved.

Sobre mí

sebastianMi nombre es Sebastián Gómez, soy ingeniero de sistemas e Informática y Magister en Ingeniería de Sistemas de la Universidad Nacional de Colombia.

Actualmente trabajo en Globant como Web UI Developer con énfasis en aplicaciones híbridas y cross compiladas. Soy el organizador del Google Developers Group de Medellín, así que contactame si quieres dar alguna charla o participar actuamente de esta comunidad.

He participado en una Startup Colombiana llamada SponzorMe al lado de Carlos Rojas y fuí participante de Startup Chile a pesar de no haber continuado con esta startup me apasiona el emprendimiento y me gusta aconsejar y ayudar startups como mentor técnico. También he trabajado en empresas Americanas como StudioHyperset en Estados Unidos y para Measured Medium. Mi interés y mi experiencia es el desarrollo de web y móvil full stack como Front-end con Javascript. Me apasiona desarrollar software, escribir código y enseñar lo que aprendo día a día.

También he trabajado como profesor en diferentes universidades en Medellín Colombia, con tematicas relacionadas con la Inteligencia Artificial, Bases de datos, programación orientada a objetos, minería de datos, desarrollo de software, desarrollo móvil y desarrollo web.

Me encanta escribir código rápido y prototipar de una manera accelerada si quieres ver que hago día a día puedes darle un vistazo a mi codepen:  https://codepen.io/seagomezar/.

Todos los días trato de crear o participar en proyectos, la mayoría open source, así que puede chequear mi GitHub:  https://github.com/seagomezar.

Mi áreas de investigación académica son: Ingeniería de software, Ingeniería de requisitos, procesamiento del lenguaje natural, Ontologías, Bases De Datos,  Machine Learning, Seguimiento de trayectorias y Modelamiento matemático de formaciones.

Estas son algunas de mis publicaciones académicas mas recientes: