Skip to content

Commit 85e43bc

Browse files
committed
Add support for getting the index in the iterators (../index)
1 parent e7f810e commit 85e43bc

File tree

6 files changed

+34
-12
lines changed

6 files changed

+34
-12
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
experiments/
12
node_modules/
23
.nyc_output
34
coverage

.npmignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ bench/
88
.github/
99
.eslintrc.json
1010
perf*.js
11-
*.test.js
11+
*.test.js
12+
experiments/

async_iterators.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,34 @@
44
// I am supporting filter, reduce, some, every, map
55
export async function filter (arr, iter) {
66
const result = []
7+
let index = 0
78
for (const item of arr) {
8-
if (await iter(item)) result.push(item)
9+
if (await iter(item, index++)) result.push(item)
910
}
1011
return result
1112
}
1213

1314
export async function some (arr, iter) {
15+
let index = 0
1416
for (const item of arr) {
15-
if (await iter(item)) return true
17+
if (await iter(item, index++)) return true
1618
}
1719
return false
1820
}
1921

2022
export async function every (arr, iter) {
23+
let index = 0
2124
for (const item of arr) {
22-
if (!(await iter(item))) return false
25+
if (!(await iter(item, index++))) return false
2326
}
2427
return true
2528
}
2629

2730
export async function map (arr, iter) {
2831
const result = []
32+
let index = 0
2933
for (const item of arr) {
30-
result.push(await iter(item))
34+
result.push(await iter(item, index++))
3135
}
3236
return result
3337
}

compiler.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import asyncIterators from './async_iterators.js'
2828
* @property {*} [yieldUsed]
2929
* @property {Boolean} [useContext]
3030
* @property {Boolean} [avoidInlineAsync]
31+
* @property {string} [extraArguments]
3132
*
3233
*/
3334

@@ -497,7 +498,7 @@ function processBuiltString (method, str, buildState) {
497498
}
498499
}
499500

500-
const final = `(state, values, methods, gen, notTraversed, Override, asyncIterators, r, rAsync) => ${buildState.asyncDetected ? 'async' : ''} (context ${
501+
const final = `(state, values, methods, gen, notTraversed, Override, asyncIterators, r, rAsync) => ${buildState.asyncDetected ? 'async' : ''} (context ${buildState.extraArguments ? ',' + buildState.extraArguments : ''} ${
501502
buildState.yieldUsed ? ', resumable = {}' : ''
502503
}) => { ${copyStateCall} const result = ${str}; return result }`
503504

defaultMethods.js

+12-6
Original file line numberDiff line numberDiff line change
@@ -443,9 +443,9 @@ function createArrayIterativeMethod (name) {
443443
engine.run(selector, context, {
444444
above
445445
}) || []
446-
return selector[name]((i) => {
446+
return selector[name]((i, index) => {
447447
return engine.run(mapper, i, {
448-
above: [selector, context, ...above]
448+
above: [{ item: selector, index }, context, ...above]
449449
})
450450
})
451451
},
@@ -456,9 +456,9 @@ function createArrayIterativeMethod (name) {
456456
(await engine.run(selector, context, {
457457
above
458458
})) || []
459-
return asyncIterators[name](selector, (i) => {
459+
return asyncIterators[name](selector, (i, index) => {
460460
return engine.run(mapper, i, {
461-
above: [selector, context, ...above]
461+
above: [{ item: selector, index }, context, ...above]
462462
})
463463
})
464464
},
@@ -470,8 +470,9 @@ function createArrayIterativeMethod (name) {
470470
const mapState = {
471471
...buildState,
472472
state: {},
473-
above: [selector, state, ...above],
474-
avoidInlineAsync: true
473+
above: [{ item: selector }, state, ...above],
474+
avoidInlineAsync: true,
475+
iteratorCompile: true
475476
}
476477
mapper = build(mapper, mapState)
477478
buildState.useContext = buildState.useContext || mapState.useContext
@@ -841,6 +842,11 @@ defaultMethods.var.compile = function (data, buildState) {
841842
typeof data === 'number' ||
842843
(Array.isArray(data) && data.length <= 2)
843844
) {
845+
if (data === '../index' && buildState.iteratorCompile) {
846+
buildState.extraArguments = 'index'
847+
return 'index'
848+
}
849+
844850
if (Array.isArray(data)) {
845851
key = data[0]
846852
defaultValue = typeof data[1] === 'undefined' ? null : data[1]

general.test.js

+9
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,15 @@ describe('Various Test Cases', () => {
154154
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { var: '\\\\foo' }, { '\\foo': 2 }, 2)
155155
})
156156

157+
it('is able to access the index in the iterators', async () => {
158+
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { map: [[0, 1, 2, 3], { '+': [{ var: '' }, { var: '../index' }] }] }, {}, [0, 2, 4, 6])
159+
})
160+
161+
// This is not fully supported right now.
162+
// it('is able to access the source array in the iterators', async () => {
163+
// for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { map: [[0, 1, 2, 3], { '+': [{ var: '' }, { var: '../item.2' }] }] }, {}, [2, 3, 4, 5])
164+
// })
165+
157166
it('should be able to handle various instances of "in" with good, bad and invalid data', async () => {
158167
const rule = {
159168
in: ['Spring', { var: 'city' }]

0 commit comments

Comments
 (0)