Skip to content

Commit 884e103

Browse files
slowcheetahzloirock
authored andcommitted
Iterator.zipKeyed implementation
1 parent 945edea commit 884e103

File tree

11 files changed

+136
-1
lines changed

11 files changed

+136
-1
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2488,6 +2488,8 @@ export const data = {
24882488
},
24892489
'esnext.iterator.zip': {
24902490
},
2491+
'esnext.iterator.zip-keyed': {
2492+
},
24912493
'esnext.json.is-raw-json': {
24922494
bun: '1.1.43',
24932495
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
@@ -294,5 +294,6 @@ export default {
294294
'es.symbol.async-dispose',
295295
'es.symbol.dispose',
296296
'esnext.iterator.zip',
297+
'esnext.iterator.zip-keyed',
297298
],
298299
};

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var parent = require('../../actual/iterator');
33
require('../../modules/esnext.iterator.concat');
44
require('../../modules/esnext.iterator.range');
55
require('../../modules/esnext.iterator.zip');
6+
require('../../modules/esnext.iterator.zip-keyed');
67
// TODO: Remove from `core-js@4`
78
require('../../modules/esnext.iterator.as-indexed-pairs');
89
require('../../modules/esnext.iterator.indexed');
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'use strict';
2+
require('../../modules/es.object.to-string');
3+
require('../../modules/es.object.create');
4+
require('../../modules/es.iterator.constructor');
5+
require('../../modules/es.reflect.own-keys');
6+
require('../../modules/esnext.iterator.zip-keyed');
7+
8+
var entryUnbind = require('../../internals/entry-unbind');
9+
10+
module.exports = entryUnbind('Iterator', 'zipKeyed');

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ var IteratorProxy = createIteratorProxy(function () {
8686
push(results, result);
8787
}
8888

89-
return finishResults !== undefined ? finishResults(results) : results;
89+
return finishResults ? finishResults(results) : results;
9090
});
9191

9292
module.exports = function (iters, mode, padding, finishResults) {
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
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 getBuiltIn = require('../internals/get-built-in');
7+
var getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f;
8+
var getIteratorFlattenable = require('../internals/get-iterator-flattenable');
9+
var getModeOption = require('../internals/get-mode-option');
10+
var getPaddingOption = require('../internals/get-padding-option');
11+
var isDataDescriptor = require('../internals/is-data-descriptor');
12+
var iteratorCloseAll = require('../internals/iterator-close-all');
13+
var iteratorZip = require('../internals/iterator-zip');
14+
var uncurryThis = require('../internals/function-uncurry-this');
15+
16+
var create = getBuiltIn('Object', 'create');
17+
var ownKeys = getBuiltIn('Reflect', 'ownKeys');
18+
var push = uncurryThis([].push);
19+
20+
// `Iterator.zipKeyed` method
21+
// https://github.com/tc39/proposal-joint-iteration
22+
$({ target: 'Iterator', stat: true, forced: true }, {
23+
zipKeyed: function zipKeyed(iterables /* , options */) {
24+
anObject(iterables);
25+
var options = arguments.length > 1 ? arguments[1] : undefined;
26+
anObjectOrUndefined(options);
27+
var mode = getModeOption(options);
28+
var paddingOption = mode === 'longest' ? getPaddingOption(options) : undefined;
29+
30+
var iters = [];
31+
var padding = [];
32+
var allKeys = ownKeys(iterables);
33+
var keys = [];
34+
var desc, i, iter, key, value;
35+
for (i = 0; i < allKeys.length; i++) {
36+
key = allKeys[i];
37+
try {
38+
desc = getOwnPropertyDescriptor(iterables, key);
39+
} catch (error) {
40+
return iteratorCloseAll(iters, 'throw', error);
41+
}
42+
if (!desc || !desc.enumerable) continue;
43+
if (isDataDescriptor(desc)) {
44+
value = desc.value;
45+
} else {
46+
var getter = desc.get;
47+
if (getter !== undefined) {
48+
try {
49+
value = call(getter, iterables);
50+
} catch (error) {
51+
return iteratorCloseAll(iters, 'throw', error);
52+
}
53+
}
54+
}
55+
56+
if (value !== undefined) {
57+
push(keys, key);
58+
try {
59+
iter = getIteratorFlattenable(value, true);
60+
} catch (error) {
61+
return iteratorCloseAll(iters, 'throw', error);
62+
}
63+
push(iters, iter);
64+
}
65+
}
66+
67+
var iterCount = iters.length;
68+
if (mode === 'longest') {
69+
if (paddingOption === undefined) {
70+
for (i = 0; i < iterCount; i++) push(padding, undefined);
71+
} else {
72+
for (i = 0; i < keys.length; i++) {
73+
try {
74+
value = paddingOption[keys[i]];
75+
} catch (error) {
76+
return iteratorCloseAll(iters, 'throw', error);
77+
}
78+
push(padding, value);
79+
}
80+
}
81+
}
82+
83+
var finishResults = function (results) {
84+
var obj = create(null);
85+
for (i = 0; i < iterCount; i++) {
86+
obj[keys[i]] = results[i];
87+
}
88+
return obj;
89+
};
90+
91+
return iteratorZip(iters, mode, padding, finishResults);
92+
}
93+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
'use strict';
22
// https://github.com/tc39/proposal-joint-iteration
33
require('../modules/esnext.iterator.zip');
4+
require('../modules/esnext.iterator.zip-keyed');

tests/compat/tests.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,6 +1847,9 @@ GLOBAL.tests = {
18471847
'esnext.iterator.zip': function () {
18481848
return Iterator.zip;
18491849
},
1850+
'esnext.iterator.zipKeyed': function () {
1851+
return Iterator.zipKeyed;
1852+
},
18501853
'esnext.json.is-raw-json': NATIVE_RAW_JSON,
18511854
'esnext.json.parse': function () {
18521855
var unsafeInt = '9007199254740993';

tests/entries/unit.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,8 @@ for (PATH of ['core-js-pure', 'core-js']) {
773773
ok(typeof load(NS, 'iterator/indexed') == 'function');
774774
ok(load(NS, 'iterator/concat')([2]).next().value === 2);
775775
ok(load(NS, 'iterator/range')(1, 2).next().value === 1);
776+
ok(typeof load(NS, 'iterator/zip') == 'function');
777+
ok(typeof load(NS, 'iterator/zip-keyed') == 'function');
776778
ok(load(NS, 'map/delete-all')(new Map(), 1, 2) === false);
777779
ok(load(NS, 'map/emplace')(new Map([[1, 2]]), 1, { update: it => it ** 2 }) === 4);
778780
ok(load(NS, 'map/every')(new Map([[1, 2], [2, 3], [3, 4]]), it => it % 2) === false);
@@ -941,6 +943,7 @@ for (PATH of ['core-js-pure', 'core-js']) {
941943
load('proposals/iterator-helpers-stage-3-2');
942944
load('proposals/iterator-range');
943945
load('proposals/iterator-sequencing');
946+
load('proposals/joint-iteration');
944947
load('proposals/json-parse-with-source');
945948
load('proposals/keys-composition');
946949
load('proposals/map-update-or-insert');

tests/eslint/eslint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,7 @@ const forbidCompletelyNonExistentBuiltIns = {
12501250
'concat',
12511251
'range',
12521252
'zip',
1253+
'zipKeyed',
12531254
] }],
12541255
'es/no-nonstandard-iterator-prototype-properties': [ERROR, { allow: [
12551256
'toAsync',

0 commit comments

Comments
 (0)