refactoring and bugfixes...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2021-05-25 18:21:30 +03:00
parent 4277580689
commit fe1f39cba6
4 changed files with 54 additions and 27 deletions

View File

@ -29,14 +29,14 @@ module.STOP =
//---------------------------------------------------------------------
// Mixins...
// Equivalent to .map(..) / .filter(..) / .reduce(..) / .. with support for
// STOP...
// Wrap .map(..) / .filter(..) / .reduce(..) / .. to support STOP...
//
// NOTE: these add almost no overhead to the iteration.
// NOTE: these will not return a partial result if stopped.
//
// XXX should these return a partial result on STOP?
var wrapIterFunc = function(iter){
/*/ XXX should these return a partial result on STOP?
// ...use generators to do this...
var stoppable = function(iter){
return function(func){
try {
return this[iter](...arguments)
@ -46,6 +46,17 @@ var wrapIterFunc = function(iter){
} else if(err instanceof STOP){
return err.value }
throw err } } }
/*/
var stoppableList = function(iter){
return function(func){
return [...this.iter()[iter](...arguments)] } }
var stoppableValue = function(iter, no_return=false){
return function(func){
var res = this.iter()[iter](...arguments)
return no_return ?
undefined
: res } }
//*/
// Equivalent to .map(..) / .filter(..) / .reduce(..) that process the
@ -493,10 +504,10 @@ object.Mixin('ArrayProtoMixin', 'soft', {
// Stoppable iteration...
//
smap: wrapIterFunc('map'),
sfilter: wrapIterFunc('filter'),
sreduce: wrapIterFunc('reduce'),
sforEach: wrapIterFunc('forEach'),
smap: stoppableList('map'),
sfilter: stoppableList('filter'),
sreduce: stoppableValue('reduce'),
sforEach: stoppableValue('map', true),
// Chunk iteration...
//

View File

@ -76,7 +76,8 @@ A library of JavaScript type extensions, types and type utilities.
- [`generator.iter(..)`](#generatoriter)
- [`generator.STOP`](#generatorstop)
- [Generator instance iteration](#generator-instance-iteration)
- [`<generator>.map(..)` / `<generator>.filter(..)` / `<generator>.reduce(..)`](#generatormap--generatorfilter--generatorreduce)
- [`<generator>.map(..)` / `<generator>.filter(..)`](#generatormap--generatorfilter)
- [`<generator>.reduce(..)` / `<generator>.greduce(..)`](#generatorreduce--generatorgreduce)
- [`<generator>.slice(..)`](#generatorslice)
- [`<generator>.at(..)` / `<generator>.gat(..)`](#generatorat--generatorgat)
- [`<generator>.flat(..)`](#generatorflat)
@ -1650,7 +1651,7 @@ Chained generators handle items depth-first, i.e. the items are passed as they
are yielded down the generator chain.
#### `<generator>.map(..)` / `<generator>.filter(..)` / `<generator>.reduce(..)`
#### `<generator>.map(..)` / `<generator>.filter(..)`
Equivalents to `Array`'s `.map(..)`, `.filter(..)` and `.reduce(..)` but return
generators that yield the handler return values.
@ -1683,6 +1684,9 @@ var L = [1,2,3,4,5]
.toArray()
```
#### `<generator>.reduce(..)` / `<generator>.greduce(..)`
<!--
XXX .reduce(..) can return a non-iterable -- test and document this case...
...compare with Array.prototype.reduce(..)
@ -1910,7 +1914,7 @@ but returning a reusable `<Generator>`.
#### `<Generator>.map(..)` / `<Generator>.filter(..)` / `<Generator>.reduce(..)` / `<Generator>.flat()`
Counterparts to `<generator>`'s
[`.map(..)` and friends](#generatormap--generatorfilter--generatorreduce) and
[`.map(..)`, `.filter(..)`](#generatormap--generatorfilter), [`.reduce(..)`/`.greduce(..)`](#generatorreduce--generatorgreduce) and
[`.flat(..)`](#generatorflat)
but return a `<Generator>`.

View File

@ -157,7 +157,7 @@ function(func){
if(err === STOP){
return
} else if(err instanceof STOP){
yield err.value
yield err.value
return }
throw err } }
: function(){
@ -305,24 +305,36 @@ object.Mixin('GeneratorProtoMixin', 'soft', {
// will be expanded...
// NOTE: there is no point to add generator-handler support to either
// .filter(..) or .reduce(..)
map: stoppable(function*(func){
var i = 0
if(func instanceof Generator){
for(var e of this){
yield* func(e, i++, this) }
} else {
for(var e of this){
yield func(e, i++, this) } } }),
map: stoppable(
function*(func){
var i = 0
if(func instanceof Generator){
for(var e of this){
yield* func(e, i++, this) }
} else {
for(var e of this){
yield func(e, i++, this) } } }),
filter: stoppable(function*(func){
var i = 0
for(var e of this){
if(func(e, i++, this)){
yield e } } }),
reduce: stoppable(function*(func, res){
var i = 0
try{
for(var e of this){
if(func(e, i++, this)){
yield e } }
// normalize the stop value...
} catch(err){
if(err instanceof STOP){
if(!err.value){
throw STOP }
err.value = e }
throw err } }),
reduce: stoppable(function(func, res){
var i = 0
for(var e of this){
res = func(res, e, i++, this) }
yield res }),
return res }),
greduce: function*(func, res){
yield this.reduce(...arguments) },
pop: function(){
return [...this].pop() },

View File

@ -1,6 +1,6 @@
{
"name": "ig-types",
"version": "6.3.0",
"version": "6.3.1",
"description": "Generic JavaScript types and type extensions...",
"main": "main.js",
"scripts": {