mirror of
https://github.com/flynx/types.js.git
synced 2025-10-29 02:20:07 +00:00
added experimental generator map/filter/reduce/...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
6f2d68bd1a
commit
6341313c59
17
Array.js
17
Array.js
@ -250,6 +250,12 @@ Array.prototype.sforEach = wrapIterFunc('forEach')
|
||||
// very long array by interrupting the processing with a timeout...
|
||||
//
|
||||
// XXX should these return a partial result on StopIteration?
|
||||
// XXX add generators:
|
||||
// .map(..) / .filter(..) / .reduce(..)
|
||||
// ...the basis here should be the chunks, i.e. each cycle should
|
||||
// go through a chunk...
|
||||
// ...the mixin can be generic, i.e. applicable to Array, and
|
||||
// other stuff...
|
||||
var makeChunkIter = function(iter, wrapper){
|
||||
wrapper = wrapper
|
||||
|| function(res, func, array, e){
|
||||
@ -436,6 +442,17 @@ function(func, ...arrays){
|
||||
: this.constructor.zip(func, this, ...arrays) }
|
||||
|
||||
|
||||
//
|
||||
// array.iter()
|
||||
// -> iterator
|
||||
//
|
||||
//
|
||||
// XXX revise name
|
||||
Array.prototype.iter = function*(){
|
||||
for(var e of this){
|
||||
yield e } }
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
133
Generator.js
Normal file
133
Generator.js
Normal file
@ -0,0 +1,133 @@
|
||||
/**********************************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
**********************************************/ /* c8 ignore next 2 */
|
||||
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
|
||||
(function(require){ var module={} // make module AMD/node compatible...
|
||||
/*********************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
var Generator =
|
||||
module.Generator =
|
||||
(function*(){}).__proto__
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Generator "class" methods...
|
||||
//
|
||||
// the following are the same:
|
||||
// 1) Wrapper
|
||||
// var combined = function(...args){
|
||||
// return someGenerator(...args)
|
||||
// .filter(function(e){ ... })
|
||||
// .map(function(e){ ... }) }
|
||||
//
|
||||
// combined( .. )
|
||||
//
|
||||
// 2) Static generator methods...
|
||||
// var combined = someGenerator
|
||||
// .filter(function(e){ ... })
|
||||
// .map(function(e){ ... })
|
||||
//
|
||||
// combined( .. )
|
||||
//
|
||||
|
||||
// XXX do a better .toString(..)...
|
||||
// should be of the format:
|
||||
// <root-gen>(<args>)
|
||||
// .<name>(<args>)
|
||||
// ...
|
||||
// XXX this needs to be of the correct type...
|
||||
var makeGenerator = function(name){
|
||||
return function(...args){
|
||||
var that = this
|
||||
return function*(){
|
||||
yield* that(...arguments)[name](...args) } } }
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
Generator.map = makeGenerator('map')
|
||||
Generator.filter = makeGenerator('filter')
|
||||
Generator.reduce = makeGenerator('reduce')
|
||||
Generator.flat = makeGenerator('flat')
|
||||
|
||||
Generator.then = function(...args){
|
||||
var that = this
|
||||
return function(){
|
||||
return that(...arguments).then(func) } }
|
||||
|
||||
Generator.toArray = function(){
|
||||
var that = this
|
||||
return function(){
|
||||
return that(...arguments).toArray() } }
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Generator instance methods...
|
||||
|
||||
Generator.prototype.map = function*(func){
|
||||
var i = 0
|
||||
for(var e of this){
|
||||
yield func(e, i++, this) } }
|
||||
Generator.prototype.filter = function*(func){
|
||||
var i = 0
|
||||
for(var e of this){
|
||||
if(func(e, i++, this)){
|
||||
yield e } } }
|
||||
Generator.prototype.reduce = function*(func, res){
|
||||
var i = 0
|
||||
for(var e of this){
|
||||
res = func(res, e, i++, this) }
|
||||
yield res }
|
||||
Generator.prototype.flat = function*(depth=1){
|
||||
if(depth == 0){
|
||||
return this }
|
||||
for(var e of this){
|
||||
if(e instanceof Array){
|
||||
for(var i=0; i < e.length; i++){
|
||||
if(depth <= 1){
|
||||
yield e[i]
|
||||
|
||||
} else {
|
||||
yield* typeof(e[i].flat) == 'function' ?
|
||||
e[i].flat(depth-1)
|
||||
: e[i] } }
|
||||
|
||||
// XXX the test will not work yet...
|
||||
} else if(e instanceof Generator){
|
||||
if(depth <= 1){
|
||||
// XXX should we expand the generaaator here???
|
||||
yield [...e]
|
||||
|
||||
} else {
|
||||
yield* e.flat(depth-1) }
|
||||
|
||||
} else {
|
||||
yield e } } }
|
||||
|
||||
Generator.prototype.then = function(func){
|
||||
var that = this
|
||||
return new Promise(function(resolve){
|
||||
resolve([...that]) }) }
|
||||
|
||||
Generator.prototype.toArray = function(){
|
||||
return [...this] }
|
||||
|
||||
|
||||
// XXX these are potentially bad because with negative indexes well need
|
||||
// to run throu the whole iterator and cache the data...
|
||||
//Generator.prototype.slice = function(from=0, to=-1){ }
|
||||
//Generator.prototype.reverse = function(){ }
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* vim:set ts=4 sw=4 : */ return module })
|
||||
15
Promise.js
15
Promise.js
@ -156,6 +156,21 @@ object.Constructor('_CooperativePromise', Promise, {
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// promise iterators...
|
||||
|
||||
// XXX like Promise.all(..) but creates an iterable promise...
|
||||
var IterablePromise =
|
||||
module.IterablePromise =
|
||||
Promise.iter =
|
||||
object.Constructor('IterablePromise', Promise, {
|
||||
map: function(){},
|
||||
filter: function(){},
|
||||
reduce: function(){},
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* vim:set ts=4 sw=4 : */ return module })
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ig-types",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.0",
|
||||
"description": "Generic JavaScript types and type extensions...",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
||||
10
runner.js
10
runner.js
@ -160,6 +160,16 @@ module.Queue = object.Constructor('Queue', Array, {
|
||||
queueEmpty: makeEvent(function(func){
|
||||
return this.on('queueEmpty', ...arguments) }),
|
||||
|
||||
// helpers...
|
||||
//
|
||||
// XXX how do we reference the tasks here???
|
||||
// - indexes
|
||||
// - ranges -- simelar to .slice(..)
|
||||
// - by value
|
||||
// XXX
|
||||
prioritize: function(){},
|
||||
// XXX same as prioritize but adds stuff to the tail...
|
||||
delay: function(){},
|
||||
|
||||
// main runner...
|
||||
//
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user