Created
June 25, 2011 15:54
-
-
Save vstarck/1046611 to your computer and use it in GitHub Desktop.
Implementacion de iteraciones basicas y metodos auxiliares
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Constructor que provee de la funcionalidad | |
* de iteracion | |
* | |
* @constructor | |
*/ | |
function Iterable() {} | |
/** | |
* Excepcion utilizada para detener la iteracion | |
*/ | |
Iterable.StopException = function() {}; | |
/** | |
* Itera los elementos provistos por el sujeto | |
* | |
* @param {Function} iterator | |
* @param {Object} context | |
* @return {Object} el sujeto | |
*/ | |
Iterable.prototype.each = function(iterator, context) { | |
if(typeof this._next != 'function') | |
throw new Error('Unimplemented method: _next'); | |
try { | |
iterator.call(context, this._next()); | |
return this.each(iterator, context); | |
} catch(e) { | |
if(e instanceof Iterable.StopException) | |
return this | |
throw e; | |
} | |
if(typeof this._reset == 'function') | |
this._reset(); | |
return this; | |
}; | |
/** | |
* Reduce el input multiple a un unico valor | |
* a partir del valor inicial | |
* | |
* @param {Function} iterator | |
* @param {Object} memo | |
* @param {Object} context | |
* @return {Object} | |
*/ | |
Iterable.prototype.reduce = function(iterator, memo, context) { | |
this.each(function(e) { | |
memo = iterator.call(context, memo, e); | |
}); | |
return memo; | |
}; | |
/** | |
* Devuelve el length calculado | |
* | |
* @return {Number} | |
*/ | |
Iterable.prototype.size = function() { | |
return this.reduce(function(memo, e) { | |
return memo + 1; | |
}, 0); | |
}; | |
/** | |
* Devuelve un array con la transformacion de | |
* cada elemento | |
* | |
* @param {Function} iterator | |
* @param {Object} context | |
* @return {Array} | |
*/ | |
Iterable.prototype.map = function(iterator, context) { | |
var res = []; | |
this.each(function(e) { | |
res.push( | |
iterator.call(context, e) | |
); | |
}); | |
return res; | |
}; | |
Iterable.prototype.pluck = function(property) { | |
return this.map(function(e) { | |
return e[property]; | |
}); | |
}; | |
/** | |
* Devuelve los elementos que pasen como ciertos | |
* para el iterador | |
* | |
* @return {Array} | |
*/ | |
Iterable.prototype.filter = function(iterator, context) { | |
var res = []; | |
this.each(function(e) { | |
if(iterator.call(context, e)) { | |
res.push(e); | |
} | |
}); | |
return res; | |
}; | |
/** | |
* Filtra los elementos que pasen como ciertos | |
* para el iterador | |
* | |
* @return {Array} | |
*/ | |
Iterable.prototype.reject = function(iterator, context) { | |
return this.filter(function(e) { | |
return !iterator.call(context, e); | |
}); | |
}; | |
Iterable.prototype.uniq = function() { | |
var res = []; | |
this.each(function(e) { | |
if(res.indexOf(e) == -1) { | |
res.push(e); | |
} | |
}); | |
return res; | |
}; | |
/** | |
* Verifica si todos los elementos pasan como ciertos | |
* para el iterador | |
* | |
* @param {Function} iterator | |
* @param {Object} context | |
* @return {Boolean} | |
*/ | |
Iterable.prototype.all = function(iterator, context) { | |
var status = true; | |
this.each(function(e) { | |
// Si hay un falso, detenemos la iteracion | |
if(!iterator.call(context, e)) { | |
status = false; | |
throw new Iterable.StopException; | |
} | |
}); | |
return status; | |
}; | |
/** | |
* Verifica si al menos un elemento cumple con la condicion | |
* | |
* @param {Function} iterator | |
* @param {Object} context | |
* @return {Boolean} | |
*/ | |
Iterable.prototype.any = function(iterator, context) { | |
var status = false; | |
this.each(function(e) { | |
// Si hay un true, detenemos la iteracion | |
if(!iterator.call(context, e)) { | |
status = true; | |
throw new Iterable.StopException; | |
} | |
}); | |
return status; | |
}; | |
/** | |
* Deuvelve el primer elemento que cumpla la condicion | |
* | |
* @param {Function} iterator | |
* @param {Object} context | |
* @return {Boolean} | |
*/ | |
Iterable.prototype.detect = function(iterator, context) { | |
var el = null; | |
this.each(function(e) { | |
// Si hay un true, detenemos la iteracion | |
if(iterator.call(context, e)) { | |
el = e; | |
throw new Iterable.StopException; | |
} | |
}); | |
return el; | |
}; | |
// ---------------- | |
/** | |
* Genera un rango numerico iterable | |
* | |
* @param {Number} from | |
* @param {Number} to | |
* @constructor | |
*/ | |
function Range (from, to) { | |
this.actual = this.from = from; | |
this.to = to; | |
} | |
// Extendemos el constructor iterador | |
Range.prototype = new Iterable(); | |
/** | |
* Implementacion del metodo requerido por Iterator | |
* | |
* @return {Number} | |
*/ | |
Range.prototype._next = function() { | |
// Limitamos la ejecucion a los numeros que | |
// pertenezcan al rango | |
if(this.actual > this.to) | |
throw new Iterable.StopException; | |
// Devolvemos el indice actual | |
return this.actual++; | |
}; | |
/** | |
* Implementacion del metodo | |
*/ | |
Range.prototype._reset = function() { | |
this.actual = this.from; | |
}; | |
//---------------------------------------------------- | |
console.log( | |
'Obtenemos la sumatoria del rango [0, 10]', | |
(new Range(0, 10)).reduce(function(memo, e) { | |
return memo + e; | |
}, 0) | |
); | |
console.log( | |
'Obtenemos el tamaño', | |
(new Range(0, 10)).size() | |
); | |
console.log( | |
'Obtenemos los cuadrados', | |
(new Range(0, 10)).map(function(e) { | |
return e * e; | |
}) | |
); | |
console.log( | |
'Verificamos si todos los elementos son pares', | |
(new Range(0, 10)).all(function(e) { | |
return e % 2 != 0; | |
}) | |
); | |
console.log( | |
'Verificamos si al menos un elemento par', | |
(new Range(0, 10)).any(function(e) { | |
return e % 2 != 0; | |
}) | |
); | |
console.log( | |
'Obtenemos el primer elemento divisible por 3 y por 2', | |
(new Range(0, 10)).detect(function(e) { | |
return e % 2 != 0 && e % 3 != 0; | |
}) | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment