mirror of
https://github.com/flynx/types.js.git
synced 2025-10-29 02:20:07 +00:00
fixes...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
b4c5effbd2
commit
635df6a889
119
Generator.js
119
Generator.js
@ -11,14 +11,65 @@
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
// The generator hirearchy in JS is a bit complicated.
|
||||
//
|
||||
// Consider the following:
|
||||
//
|
||||
// // this is the generator function (i.e. the constructor)
|
||||
// var Iter = function*(lst){
|
||||
// for(var e of lst){
|
||||
// yield e }}
|
||||
//
|
||||
// // this is the generator instance (constructod instance)...
|
||||
// var iter = Iter([1,2,3])
|
||||
//
|
||||
//
|
||||
// In this module we need to add methods to be visible from either Iter
|
||||
// or iter from the above example, so we need the access the prototypes
|
||||
// of each of them.
|
||||
//
|
||||
// GeneratorPrototype
|
||||
// is the prototype of the generator construcotrs (i.e. Iter(..)
|
||||
// from the above example)
|
||||
//
|
||||
// GeneratorPrototype.prototype
|
||||
// is the generator instance prototype (i.e. iter for the above
|
||||
// code)
|
||||
//
|
||||
//
|
||||
// Also the following applies:
|
||||
//
|
||||
// iter instanceof Iter // -> true
|
||||
//
|
||||
// Iter instanceof Generator
|
||||
//
|
||||
//
|
||||
// NOTE: there appears no way to test if iter is instnace of some
|
||||
// generic Generator...
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
var GeneratorPrototype =
|
||||
(function*(){}).constructor.prototype
|
||||
|
||||
var Generator =
|
||||
module.Generator =
|
||||
(function*(){}).constructor
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
// generic generator wrapper...
|
||||
var iter =
|
||||
module.iter =
|
||||
function*(lst){
|
||||
for(var e of lst){
|
||||
yield e } }
|
||||
|
||||
var Generator =
|
||||
module.Generator =
|
||||
(function*(){}).__proto__
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Generator "class" methods...
|
||||
// GeneratorPrototype "class" methods...
|
||||
//
|
||||
// the following are the same:
|
||||
// 1) Wrapper
|
||||
@ -57,31 +108,41 @@ var makePromise = function(name){
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// XXX GeneratorPrototype can't be used as a generator constructor...
|
||||
|
||||
// XXX need testing...
|
||||
Generator.at = makeGenerator('at')
|
||||
Generator.slice = makeGenerator('slice')
|
||||
Generator.flat = makeGenerator('flat')
|
||||
Generator.toArray = function(){
|
||||
// XXX should this be a generator???
|
||||
GeneratorPrototype.at = makeGenerator('at')
|
||||
GeneratorPrototype.slice = makeGenerator('slice')
|
||||
GeneratorPrototype.flat = makeGenerator('flat')
|
||||
GeneratorPrototype.toArray = function(){
|
||||
var that = this
|
||||
return function(){
|
||||
return that(...arguments).toArray() } }
|
||||
GeneratorPrototype.pop = function(){
|
||||
var that = this
|
||||
return function(){
|
||||
return that(...arguments).toArray().pop() } }
|
||||
GeneratorPrototype.shift = function(){
|
||||
var that = this
|
||||
return function(){
|
||||
return that(...arguments).toArray().shift() } }
|
||||
|
||||
Generator.map = makeGenerator('map')
|
||||
Generator.filter = makeGenerator('filter')
|
||||
Generator.reduce = makeGenerator('reduce')
|
||||
Generator.flat = makeGenerator('flat')
|
||||
GeneratorPrototype.map = makeGenerator('map')
|
||||
GeneratorPrototype.filter = makeGenerator('filter')
|
||||
GeneratorPrototype.reduce = makeGenerator('reduce')
|
||||
GeneratorPrototype.flat = makeGenerator('flat')
|
||||
|
||||
Generator.then = makePromise('then')
|
||||
Generator.catch = makePromise('catch')
|
||||
Generator.finally = makePromise('finally')
|
||||
GeneratorPrototype.then = makePromise('then')
|
||||
GeneratorPrototype.catch = makePromise('catch')
|
||||
GeneratorPrototype.finally = makePromise('finally')
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Generator instance methods...
|
||||
// GeneratorPrototype instance methods...
|
||||
|
||||
Generator.prototype.at = function*(i){
|
||||
// XXX should this be a generator???
|
||||
GeneratorPrototype.prototype.at = function*(i){
|
||||
// sanity check...
|
||||
if(i < 0){
|
||||
throw new Error('.at(..): '
|
||||
@ -94,7 +155,7 @@ Generator.prototype.at = function*(i){
|
||||
// NOTE: this is different from Array's .slice(..) in that it does not
|
||||
// support negative indexes -- this is done because there is no way
|
||||
// to judge the length of a generator untill it is fully done...
|
||||
Generator.prototype.slice = function*(from=0, to=Infity){
|
||||
GeneratorPrototype.prototype.slice = function*(from=0, to=Infity){
|
||||
// sanity check...
|
||||
if(from < 0 || to < 0){
|
||||
throw new Error('.slice(..): '
|
||||
@ -108,7 +169,7 @@ Generator.prototype.slice = function*(from=0, to=Infity){
|
||||
if(i >= from){
|
||||
yield e }
|
||||
i++ } },
|
||||
Generator.prototype.flat = function*(depth=1){
|
||||
GeneratorPrototype.prototype.flat = function*(depth=1){
|
||||
if(depth == 0){
|
||||
return this }
|
||||
for(var e of this){
|
||||
@ -123,7 +184,7 @@ Generator.prototype.flat = function*(depth=1){
|
||||
: e[i] } }
|
||||
|
||||
// XXX the test will not work yet...
|
||||
} else if(e instanceof Generator){
|
||||
} else if(e instanceof GeneratorPrototype){
|
||||
if(depth <= 1){
|
||||
// XXX should we expand the generaaator here???
|
||||
yield [...e]
|
||||
@ -133,19 +194,19 @@ Generator.prototype.flat = function*(depth=1){
|
||||
|
||||
} else {
|
||||
yield e } } }
|
||||
Generator.prototype.toArray = function(){
|
||||
GeneratorPrototype.prototype.toArray = function(){
|
||||
return [...this] }
|
||||
|
||||
Generator.prototype.map = function*(func){
|
||||
GeneratorPrototype.prototype.map = function*(func){
|
||||
var i = 0
|
||||
for(var e of this){
|
||||
yield func(e, i++, this) } }
|
||||
Generator.prototype.filter = function*(func){
|
||||
GeneratorPrototype.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){
|
||||
GeneratorPrototype.prototype.reduce = function*(func, res){
|
||||
var i = 0
|
||||
for(var e of this){
|
||||
res = func(res, e, i++, this) }
|
||||
@ -154,15 +215,15 @@ Generator.prototype.reduce = function*(func, res){
|
||||
// promise results...
|
||||
//
|
||||
// XXX how do we handle reject(..) / .catch(..)???
|
||||
Generator.prototype.promise = function(){
|
||||
GeneratorPrototype.prototype.promise = function(){
|
||||
var that = this
|
||||
return new Promise(function(resolve){
|
||||
resolve([...that]) }) }
|
||||
Generator.prototype.then = function(func){
|
||||
GeneratorPrototype.prototype.then = function(func){
|
||||
return this.promise().then(func) }
|
||||
Generator.prototype.catch = function(func){
|
||||
GeneratorPrototype.prototype.catch = function(func){
|
||||
return this.promise().catch(func) }
|
||||
Generator.prototype.finally = function(func){
|
||||
GeneratorPrototype.prototype.finally = function(func){
|
||||
return this.promise().finally(func) }
|
||||
|
||||
|
||||
|
||||
63
README.md
63
README.md
@ -26,6 +26,7 @@ A library of JavaScript type extensions, types and type utilities.
|
||||
- [`<array>.toKeys(..)`](#arraytokeys)
|
||||
- [`<array>.toMap(..)`](#arraytomap)
|
||||
- [`Array.zip(..)` / `<array>.zip(..)`](#arrayzip--arrayzip)
|
||||
- [`<array>.iter()`](#arrayiter)
|
||||
- [Abortable `Array` iteration](#abortable-array-iteration)
|
||||
- [`array.StopIteration`](#arraystopiteration)
|
||||
- [`<array>.smap(..)` / `<array>.sfilter(..)` / `<array>.sreduce(..)` / `<array>.sforEach(..)`](#arraysmap--arraysfilter--arraysreduce--arraysforeach)
|
||||
@ -58,6 +59,18 @@ A library of JavaScript type extensions, types and type utilities.
|
||||
- [`RegExp.quoteRegExp(..)`](#regexpquoteregexp)
|
||||
- ['Promise'](#promise)
|
||||
- [`Promise.cooperative(..)`](#promisecooperative)
|
||||
- [`Generator`](#generator)
|
||||
- [Generator instance iteration](#generator-instance-iteration)
|
||||
- [`<generator>.map(..)` / `<generator>.filter(..)` / `<generator>.reduce(..)` / `<generator>.flat()`](#generatormap--generatorfilter--generatorreduce--generatorflat)
|
||||
- [`<generator>.promise()`](#generatorpromise)
|
||||
- [`<generator>.then(..)` / `<generator>.catch(..)` / `<generator>.finally(..)`](#generatorthen--generatorcatch--generatorfinally)
|
||||
- [`<generator>.toArray()`](#generatortoarray)
|
||||
- [Generator constructor iteration workflow](#generator-constructor-iteration-workflow)
|
||||
- [`Generator.at(..)`](#generatorat)
|
||||
- [`Generator.slice(..)`](#generatorslice)
|
||||
- [`Generator.map(..)` / `Generator.filter(..)` / `Generator.reduce(..)` / `Generator.flat()`](#generatormap--generatorfilter--generatorreduce--generatorflat-1)
|
||||
- [`Generator.toArray()`](#generatortoarray-1)
|
||||
- [`Generator.then(..)` / `Generator.catch(..)` / `Generator.finally(..)`](#generatorthen--generatorcatch--generatorfinally-1)
|
||||
- [Containers](#containers)
|
||||
- [`containers.UniqueKeyMap()` (`Map`)](#containersuniquekeymap-map)
|
||||
- [`<unique-key-map>.set(..)`](#unique-key-mapset)
|
||||
@ -342,6 +355,12 @@ This will return `true` if:
|
||||
|
||||
#### `Array.zip(..)` / `<array>.zip(..)`
|
||||
|
||||
#### `<array>.iter()`
|
||||
|
||||
Return an iterator/generator from the current array.
|
||||
|
||||
This is useful in combination with the Generator extensions XXX
|
||||
|
||||
|
||||
### Abortable `Array` iteration
|
||||
|
||||
@ -533,12 +552,56 @@ Default value: `50`
|
||||
|
||||
#### `RegExp.quoteRegExp(..)`
|
||||
|
||||
|
||||
### 'Promise'
|
||||
|
||||
#### `Promise.cooperative(..)`
|
||||
|
||||
|
||||
|
||||
## `Generator`
|
||||
|
||||
|
||||
### Generator instance iteration
|
||||
|
||||
#### `<generator>.map(..)` / `<generator>.filter(..)` / `<generator>.reduce(..)` / `<generator>.flat()`
|
||||
|
||||
#### `<generator>.promise()`
|
||||
|
||||
#### `<generator>.then(..)` / `<generator>.catch(..)` / `<generator>.finally(..)`
|
||||
|
||||
#### `<generator>.toArray()`
|
||||
|
||||
|
||||
### Generator constructor iteration workflow
|
||||
|
||||
```javascript
|
||||
var {Generator} = require('ig-types/Generator')
|
||||
|
||||
var sumOdds = Generator
|
||||
.filter(function(e){
|
||||
return e % 2 == 1 })
|
||||
.reduce(function(r, e){
|
||||
return r + e }, 0)
|
||||
.pop()
|
||||
|
||||
console.log(sumOdds([1, 2, 3, 4, 5, 6, 7])) // -> 16
|
||||
|
||||
```
|
||||
|
||||
### `Generator.at(..)`
|
||||
|
||||
### `Generator.slice(..)`
|
||||
|
||||
This is like `Array`'s `.slice(..)` but does not support negative indexes.
|
||||
|
||||
### `Generator.map(..)` / `Generator.filter(..)` / `Generator.reduce(..)` / `Generator.flat()`
|
||||
|
||||
### `Generator.toArray()`
|
||||
|
||||
### `Generator.then(..)` / `Generator.catch(..)` / `Generator.finally(..)`
|
||||
|
||||
|
||||
## Containers
|
||||
|
||||
```javascript
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ig-types",
|
||||
"version": "3.4.2",
|
||||
"version": "3.4.3",
|
||||
"description": "Generic JavaScript types and type extensions...",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user