Skip to content

Commit 945edea

Browse files
slowcheetahzloirock
authored andcommitted
Iterator.zip implementation
1 parent e3b0fdb commit 945edea

File tree

14 files changed

+272
-0
lines changed

14 files changed

+272
-0
lines changed

packages/core-js-compat/src/data.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2486,6 +2486,8 @@ export const data = {
24862486
'esnext.iterator.to-array': null,
24872487
'esnext.iterator.to-async': {
24882488
},
2489+
'esnext.iterator.zip': {
2490+
},
24892491
'esnext.json.is-raw-json': {
24902492
bun: '1.1.43',
24912493
chrome: '114',

packages/core-js-compat/src/modules-by-versions.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,5 +293,6 @@ export default {
293293
'es.suppressed-error.constructor',
294294
'es.symbol.async-dispose',
295295
'es.symbol.dispose',
296+
'esnext.iterator.zip',
296297
],
297298
};

packages/core-js/full/iterator/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
var parent = require('../../actual/iterator');
33
require('../../modules/esnext.iterator.concat');
44
require('../../modules/esnext.iterator.range');
5+
require('../../modules/esnext.iterator.zip');
56
// TODO: Remove from `core-js@4`
67
require('../../modules/esnext.iterator.as-indexed-pairs');
78
require('../../modules/esnext.iterator.indexed');

packages/core-js/full/iterator/zip.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict';
2+
require('../../modules/es.object.to-string');
3+
require('../../modules/es.iterator.constructor');
4+
require('../../modules/esnext.iterator.zip');
5+
6+
var entryUnbind = require('../../internals/entry-unbind');
7+
8+
module.exports = entryUnbind('Iterator', 'zip');
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict';
2+
var $TypeError = TypeError;
3+
4+
module.exports = function (options) {
5+
var mode = options && options.mode;
6+
if (mode === undefined || mode === 'shortest' || mode === 'longest' || mode === 'strict') return mode || 'shortest';
7+
throw new $TypeError('Incorrect `mode` option');
8+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'use strict';
2+
var isObject = require('../internals/is-object');
3+
4+
var $TypeError = TypeError;
5+
6+
module.exports = function (options) {
7+
var padding = options && options.padding;
8+
if (padding === undefined || isObject(padding)) return padding;
9+
throw new $TypeError('Incorrect `padding` option');
10+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict';
2+
var iteratorClose = require('../internals/iterator-close');
3+
4+
module.exports = function (iters, kind, value) {
5+
for (var i = iters.length - 1; i >= 0; i--) {
6+
if (iters[i] === undefined) continue;
7+
try {
8+
value = iteratorClose(iters[i], kind, value);
9+
} catch (error) {
10+
kind = 'throw';
11+
value = error;
12+
}
13+
}
14+
if (kind === 'throw') throw value;
15+
return value;
16+
};
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
'use strict';
2+
var call = require('../internals/function-call');
3+
var createIteratorProxy = require('../internals/iterator-create-proxy');
4+
var iteratorCloseAll = require('../internals/iterator-close-all');
5+
var uncurryThis = require('../internals/function-uncurry-this');
6+
7+
var $TypeError = TypeError;
8+
var slice = uncurryThis([].slice);
9+
var push = uncurryThis([].push);
10+
var ITERATOR_IS_EXHAUSTED = 'Iterator is exhausted';
11+
12+
// eslint-disable-next-line max-statements -- specification case
13+
var IteratorProxy = createIteratorProxy(function () {
14+
var iterCount = this.iterCount;
15+
if (!iterCount) {
16+
this.done = true;
17+
return;
18+
}
19+
var openIters = this.openIters;
20+
var iters = this.iters;
21+
var padding = this.padding;
22+
var mode = this.mode;
23+
var finishResults = this.finishResults;
24+
25+
var results = [];
26+
var result, done;
27+
for (var i = 0; i < iterCount; i++) {
28+
var iter = iters[i];
29+
if (iter === null) {
30+
push(results, padding[i]);
31+
} else {
32+
try {
33+
result = call(iter.next, iter.iterator);
34+
done = result.done;
35+
result = result.value;
36+
} catch (error) {
37+
openIters[i] = undefined;
38+
return iteratorCloseAll(openIters, 'throw', error);
39+
}
40+
if (done) {
41+
openIters[i] = undefined;
42+
if (mode === 'shortest') {
43+
this.done = true;
44+
return iteratorCloseAll(openIters, 'return', undefined);
45+
}
46+
if (mode === 'strict') {
47+
if (i) {
48+
this.done = true;
49+
return iteratorCloseAll(openIters, 'throw', new $TypeError(ITERATOR_IS_EXHAUSTED));
50+
}
51+
52+
var open;
53+
for (var k = 1; k < iterCount; k++) {
54+
// eslint-disable-next-line max-depth -- specification case
55+
try {
56+
open = call(iters[k].next, iters[k].iterator);
57+
} catch (error) {
58+
openIters[k] = undefined;
59+
return iteratorCloseAll(openIters, 'throw', open);
60+
}
61+
// eslint-disable-next-line max-depth -- specification case
62+
if (!open.value) {
63+
openIters[k] = undefined;
64+
} else {
65+
this.done = true;
66+
return iteratorCloseAll(openIters, 'throw', new $TypeError(ITERATOR_IS_EXHAUSTED));
67+
}
68+
}
69+
this.done = true;
70+
return;
71+
}
72+
var isEmptyOpenIters = true;
73+
for (var j = 0; j < openIters.length; j++) {
74+
if (openIters[j] === undefined) continue;
75+
isEmptyOpenIters = false;
76+
break;
77+
}
78+
if (isEmptyOpenIters) {
79+
this.done = true;
80+
return;
81+
}
82+
iters[i] = null;
83+
result = padding[i];
84+
}
85+
}
86+
push(results, result);
87+
}
88+
89+
return finishResults !== undefined ? finishResults(results) : results;
90+
});
91+
92+
module.exports = function (iters, mode, padding, finishResults) {
93+
var iterCount = iters.length;
94+
var openIters = slice(iters, 0);
95+
96+
return new IteratorProxy({
97+
iters: iters,
98+
iterCount: iterCount,
99+
openIters: openIters,
100+
mode: mode,
101+
padding: padding,
102+
finishResults: finishResults
103+
});
104+
};
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
'use strict';
2+
var $ = require('../internals/export');
3+
var anObject = require('../internals/an-object');
4+
var anObjectOrUndefined = require('../internals/an-object-or-undefined');
5+
var call = require('../internals/function-call');
6+
var getIterator = require('../internals/get-iterator');
7+
var getIteratorFlattenable = require('../internals/get-iterator-flattenable');
8+
var getModeOption = require('../internals/get-mode-option');
9+
var getPaddingOption = require('../internals/get-padding-option');
10+
var iteratorClose = require('../internals/iterator-close');
11+
var iteratorCloseAll = require('../internals/iterator-close-all');
12+
var iteratorZip = require('../internals/iterator-zip');
13+
var uncurryThis = require('../internals/function-uncurry-this');
14+
15+
var concat = uncurryThis([].concat);
16+
var push = uncurryThis([].push);
17+
18+
// `Iterator.zip` method
19+
// https://github.com/tc39/proposal-joint-iteration
20+
$({ target: 'Iterator', stat: true, forced: true }, {
21+
zip: function zip(iterables /* , options */) {
22+
anObject(iterables);
23+
var options = arguments.length > 1 ? arguments[1] : undefined;
24+
anObjectOrUndefined(options);
25+
var mode = getModeOption(options);
26+
var paddingOption = mode === 'longest' ? getPaddingOption(options) : undefined;
27+
28+
var iters = [];
29+
var padding = [];
30+
var inputIter = getIterator(iterables);
31+
var iter, done, result;
32+
while (!done) {
33+
try {
34+
result = anObject(call(inputIter.next, inputIter));
35+
done = result.done;
36+
} catch (error) {
37+
return iteratorCloseAll(iters, 'throw', error);
38+
}
39+
if (!done) {
40+
try {
41+
iter = getIteratorFlattenable(result.value, true);
42+
} catch (error) {
43+
return iteratorCloseAll(concat([inputIter], iters), 'throw', error);
44+
}
45+
push(iters, iter);
46+
}
47+
}
48+
49+
var iterCount = iters.length;
50+
var i, paddingIter;
51+
if (mode === 'longest') {
52+
if (paddingOption === undefined) {
53+
for (i = 0; i < iterCount; i++) push(padding, undefined);
54+
} else {
55+
try {
56+
paddingIter = getIterator(paddingOption);
57+
} catch (error) {
58+
return iteratorCloseAll(iters, 'throw', error);
59+
}
60+
var usingIterator = true;
61+
for (i = 0; i < iterCount; i++) {
62+
if (usingIterator) {
63+
try {
64+
result = anObject(call(paddingIter.next, paddingIter));
65+
} catch (error) {
66+
return iteratorCloseAll(iters, 'throw', error);
67+
}
68+
if (result.done) {
69+
usingIterator = false;
70+
} else {
71+
push(padding, result.value);
72+
}
73+
} else {
74+
push(padding, undefined);
75+
}
76+
}
77+
78+
if (usingIterator) {
79+
try {
80+
iteratorClose(paddingIter, 'normal');
81+
} catch (error) {
82+
return iteratorCloseAll(iters, 'throw', error);
83+
}
84+
}
85+
}
86+
}
87+
88+
return iteratorZip(iters, mode, padding);
89+
}
90+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict';
2+
// https://github.com/tc39/proposal-joint-iteration
3+
require('../modules/esnext.iterator.zip');

0 commit comments

Comments
 (0)