Skip to content

Commit

Permalink
ensure result order in Set#intersection
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Dec 10, 2022
1 parent 54d749b commit 9dee7f2
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 10 deletions.
5 changes: 4 additions & 1 deletion packages/core-js-pure/override/internals/set-helpers.js
Expand Up @@ -4,6 +4,7 @@ var tryToString = require('../internals/try-to-string');
var iterateSimple = require('../internals/iterate-simple');

var Set = getBuiltIn('Set');
var SetPrototype = Set.prototype;
var $TypeError = TypeError;

var aSet = function (it) {
Expand Down Expand Up @@ -54,5 +55,7 @@ module.exports = {
has: has,
size: size,
clone: clone,
iterate: iterate
iterate: iterate,
$has: SetPrototype.has,
$keys: SetPrototype.keys
};
10 changes: 7 additions & 3 deletions packages/core-js/internals/set-helpers.js
Expand Up @@ -5,10 +5,12 @@ var iterateSimple = require('../internals/iterate-simple');
// eslint-disable-next-line es/no-set -- safe
var $Set = Set;
var SetPrototype = $Set.prototype;
var $has = SetPrototype.has;
var $keys = SetPrototype.keys;
var add = uncurryThis(SetPrototype.add);
var forEach = uncurryThis(SetPrototype.forEach);
var has = uncurryThis(SetPrototype.has);
var keys = uncurryThis(SetPrototype.keys);
var has = uncurryThis($has);
var keys = uncurryThis($keys);
var next = keys(new $Set()).next;

var aSet = function (it) {
Expand Down Expand Up @@ -42,5 +44,7 @@ module.exports = {
has: has,
size: size,
clone: clone,
iterate: iterate
iterate: iterate,
$has: $has,
$keys: $keys
};
32 changes: 26 additions & 6 deletions packages/core-js/internals/set-intersection.js
Expand Up @@ -9,18 +9,38 @@ var add = SetHelpers.add;
var has = SetHelpers.has;
var size = SetHelpers.size;
var forEach = SetHelpers.forEach;
var nativeHas = SetHelpers.$has;
var nativeKeys = SetHelpers.$keys;

var isNativeSetRecord = function (record) {
return record.has === nativeHas && record.keys === nativeKeys;
};

// `Set.prototype.intersection` method
// https://github.com/tc39/proposal-set-methods
module.exports = function intersection(other) {
var O = aSet(this);
var otherRec = getSetRecord(other);
var result = new Set();
if (size(O) <= otherRec.size) forEach(O, function (e) {
if (otherRec.includes(e)) add(result, e);
});
else iterateSimple(otherRec.getIterator(), function (e) {
if (has(O, e)) add(result, e);
});

// observable side effects
if (!isNativeSetRecord(otherRec) && size(O) > otherRec.size) {
iterateSimple(otherRec.getIterator(), function (e) {
if (has(O, e)) add(result, e);
});

if (size(result) < 2) return result;

var disordered = result;
result = new Set();
forEach(O, function (e) {
if (has(disordered, e)) add(result, e);
});
} else {
forEach(O, function (e) {
if (otherRec.includes(e)) add(result, e);
});
}

return result;
};
7 changes: 7 additions & 0 deletions tests/unit-global/esnext.set.intersection.js
Expand Up @@ -18,6 +18,13 @@ QUnit.test('Set#intersection', assert => {
assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([4, 5]))), []);
assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([2, 3, 4]))), [2, 3]);

assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([3, 2]))), [2, 3]);
assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([3, 2, 1]))), [1, 2, 3]);
assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([3, 2, 1, 0]))), [1, 2, 3]);
assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([3, 2]))), [2, 3]);
assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([3, 2, 1]))), [1, 2, 3]);
assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([3, 2, 1, 0]))), [1, 2, 3]);

// TODO: drop from core-js@4
assert.deepEqual(from(new Set([1, 2, 3]).intersection([4, 5])), []);
assert.deepEqual(from(new Set([1, 2, 3]).intersection([2, 3, 4])), [2, 3]);
Expand Down
7 changes: 7 additions & 0 deletions tests/unit-pure/esnext.set.intersection.js
Expand Up @@ -19,6 +19,13 @@ QUnit.test('Set#intersection', assert => {
assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([4, 5]))), []);
assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([2, 3, 4]))), [2, 3]);

assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([3, 2]))), [2, 3]);
assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([3, 2, 1]))), [1, 2, 3]);
assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([3, 2, 1, 0]))), [1, 2, 3]);
assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([3, 2]))), [2, 3]);
assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([3, 2, 1]))), [1, 2, 3]);
assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([3, 2, 1, 0]))), [1, 2, 3]);

// TODO: drop from core-js@4
assert.deepEqual(from(new Set([1, 2, 3]).intersection([4, 5])), []);
assert.deepEqual(from(new Set([1, 2, 3]).intersection([2, 3, 4])), [2, 3]);
Expand Down

0 comments on commit 9dee7f2

Please sign in to comment.