more work on te generic .iter(..) (Array.js is not done yet) + docs...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-06-23 13:37:46 +03:00
parent 2b6dfb35c2
commit c804028d9f
4 changed files with 72 additions and 14 deletions

View File

@ -212,6 +212,7 @@ object.Mixin('ArrayMixin', 'soft', {
// done...
: [] },
// XXX add handler function support -- a-la generator.js'
iter: function*(lst=[]){
yield* lst.iter() },
})

View File

@ -94,7 +94,7 @@ Library of JavaScript type extensions, types and utilities.
- [`generator.iter(..)`](#generatoriter)
- [`generator.STOP`](#generatorstop)
- [Generator instance iteration](#generator-instance-iteration)
- [`<generator>.iter()`](#generatoriter-1)
- [`<generator>.iter(..)`](#generatoriter-1)
- [`<generator>.map(..)` / `<generator>.filter(..)`](#generatormap--generatorfilter)
- [`<generator>.reduce(..)` / `<generator>.greduce(..)`](#generatorreduce--generatorgreduce)
- [`<generator>.slice(..)`](#generatorslice)
@ -2031,7 +2031,7 @@ Chained generators handle items depth-first, i.e. the items are passed as they
are yielded down the generator chain.
#### `<generator>.iter()`
#### `<generator>.iter(..)`
Iterate over the generator.
```bnf
@ -2039,7 +2039,24 @@ Iterate over the generator.
-> <generator>
```
This is here mainly for compatibility with [`<array>`'s `.iter()`](#arrayiter--arrayiter).
XXX move this to `generator.iter(..)`
Compatible with [`<array>`'s `.iter()`](#arrayiter--arrayiter).
`.iter(..)` also supports a handler function
```bnf
<generator>.iter(<handler>)
-> <generator>
<handler>(<elem>, <index>)
-> <elem>
-> [<elem>, ..]
-> []
```
Note that the iterables returned by `<handler>(..)` will be expanded, to prevent
this wrap them in an array.
#### `<generator>.map(..)` / `<generator>.filter(..)`

View File

@ -85,14 +85,38 @@ var ITERATOR_PROTOTYPES = [
//---------------------------------------------------------------------
// generic generator wrapper...
// helper...
var __iter =
module.__iter =
function*(lst=[]){
if(typeof(lst) == 'object' && Symbol.iterator in lst){
yield* lst
} else {
yield lst } }
// XXX updatae Array.js' version for compatibility...
// XXX DOCS!!!
var iter =
module.iter =
Generator.iter =
function*(lst=[]){
for(var e of lst){
yield e } }
function(lst=[]){
// handler -> generator-constructor...
if(typeof(lst) == 'function'){
// we need to be callable...
var that = this instanceof Function ?
this
// generic root generator...
: module.__iter
return function*(){
yield* that(...arguments).iter(lst) } }
// no handler -> generator instance...
return module.__iter(lst) }
// NOTE: we need .iter(..) to both return generators if passed an iterable
// and genereator constructos if passed a function...
iter.__proto__ = GeneratorPrototype
@ -229,9 +253,7 @@ module.GeneratorMixin =
object.Mixin('GeneratorMixin', 'soft', {
STOP: object.STOP,
// NOTE: this is here for compatibility with Array.iter(..)
iter: function*(lst=[]){
yield* module.iter(lst) },
iter: module.iter,
gat: makeGenerator('gat'),
at: function(i){
@ -309,9 +331,23 @@ object.Mixin('GeneratorMixin', 'soft', {
var GeneratorProtoMixin =
module.GeneratorProtoMixin =
object.Mixin('GeneratorProtoMixin', 'soft', {
// NOTE: this is here for compatibility with [..].iter()
iter: function*(){
yield* this },
// XXX use module.iter(..) ???
iter: function*(handler){
if(handler){
var i = 0
for(var elem of this){
var res = handler.call(this, elem, i)
// expand iterables...
if(typeof(res) == 'object'
&& Symbol.iterator in res){
yield* res
// as-is...
} else {
yield res }}
// no handler...
} else {
yield* this } },
//*/
at: function(i){
return this.gat(i).next().value },
@ -477,6 +513,7 @@ module.AsyncGeneratorMixin =
object.Mixin('AsyncGeneratorMixin', 'soft', {
// XXX TEST...
iter: makeGenerator('async', 'iter'),
map: makeGenerator('async', 'map'),
filter: makeGenerator('async', 'filter'),
reduce: makeGenerator('async', 'reduce'),
@ -522,6 +559,9 @@ object.Mixin('AsyncGeneratorProtoMixin', 'soft', {
return func.call(this, elem, i) ?
[elem]
: [] }) },
// NOTE: there is not much point in .reduceRight(..) in an async
// generator as we'll need to fully unwind it then go from the
// end...
reduce: async function(func, state){
this.iter(function(elem, i){
state = func.call(this, state, elem, i)

View File

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