Last active
August 29, 2015 14:04
-
-
Save martianboy/92a367009dcc10515b44 to your computer and use it in GitHub Desktop.
Testing higher-order functions with es6 generators
This file contains hidden or 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
/* This will run async without creating intermediate arrays. */ | |
function* makeGeneratorFromArray(array){ | |
var nextIndex = 0; | |
while(nextIndex < array.length) { | |
yield array[nextIndex++]; | |
} | |
} | |
function GeneratorsWrapper(input) { | |
if (Array.isArray(input)) | |
this._internalGenerator = makeGeneratorFromArray(input); | |
else if (input.isGenerator && input.isGenerator()) | |
this._internalGenerator = input(); | |
else | |
throw new TypeError('Unidentifiable input.') | |
} | |
GeneratorsWrapper.prototype.each = function(fn, context) { | |
if (typeof fn !== 'function') | |
throw new TypeError('callback is not a function.'); | |
var index = 0; | |
for (var x of this._internalGenerator) { | |
fn.call(context, x, index++, this); | |
} | |
} | |
GeneratorsWrapper.prototype.map = function(fn, context) { | |
if (typeof fn !== 'function') | |
throw new TypeError('callback is not a function.'); | |
var _internalGenerator = this._internalGenerator; | |
return new GeneratorsWrapper(function* () { | |
var index = 0; | |
for (var x of _internalGenerator) { | |
yield fn.call(context, x, index++, this); | |
} | |
}); | |
} | |
GeneratorsWrapper.prototype.filter = function (fn, context) { | |
if (typeof fn !== 'function') | |
throw new TypeError('callback is not a function.'); | |
var _internalGenerator = this._internalGenerator; | |
return new GeneratorsWrapper(function* () { | |
var index = 0; | |
for (var x of _internalGenerator) { | |
if (fn.call(context, x, index++, this)) { | |
yield x; | |
} | |
} | |
}); | |
} | |
GeneratorsWrapper.prototype.reduce = function(fn, initialValue) { | |
if (typeof fn !== 'function') | |
throw new TypeError('callback is not a function.'); | |
var index = 0; | |
var accumulator; | |
var genVal = this._internalGenerator.next(); | |
if (genVal.done) | |
throw new TypeError('This generator is done for!'); | |
if (initialValue) | |
accumulator = initialValue; | |
else | |
accumulator = genVal.value; | |
while(!genVal.done) { | |
accumulator = fn.call(undefined, accumulator, genVal.value, index, this); | |
genVal = this._internalGenerator.next(); | |
} | |
return accumulator; | |
} | |
GeneratorsWrapper.prototype.take = function (n) { | |
if (n < 1) | |
throw new TypeError('Can\'t take zero or less items!'); | |
var _internalGenerator = this._internalGenerator; | |
return new GeneratorsWrapper(function* () { | |
var genVal = _internalGenerator.next(); | |
for(var i = 0; (i < n) && !genVal.done; i++) { | |
yield genVal.value; | |
genVal = _internalGenerator.next(); | |
} | |
}); | |
}; | |
GeneratorsWrapper.prototype.first = function() { | |
return this.take(1); | |
} | |
GeneratorsWrapper.prototype.toArray = function() { | |
return this.reduce(function(arr, elem) { | |
arr.push(elem); | |
return arr; | |
}, []); | |
} | |
GeneratorsWrapper.prototype.single = function() { | |
var arr = this.toArray(); | |
if (arr.length) | |
return arr[0]; | |
else | |
throw new Error('Generator is empty.'); | |
} | |
module.exports = GeneratorsWrapper; |
This file contains hidden or 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
var Generator = require('./generators'); | |
/************************************************ | |
* Fibonacci Sequence & Golden Ratio * | |
************************************************/ | |
console.log( | |
new Generator([1,2,3,4,5,6]) | |
.map(function(x) { return x * x; }) | |
.filter(function(x) { return x > 10; }) | |
.toArray() | |
); | |
/************************************************ | |
* Fibonacci Sequence & Golden Ratio * | |
************************************************/ | |
function *fibonacci() { | |
var x1 = 0, x2 = 1; | |
while(true) { | |
x2 += x1; | |
x1 = x2 - x1; | |
yield x1; | |
} | |
} | |
var previous; | |
new Generator(fibonacci) | |
.take(26) | |
.each(function(x) { | |
if (previous) | |
console.log((previous + x) / x); | |
previous = x; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment