diff --git a/packages/core-js-pure/override/internals/set-helpers.js b/packages/core-js-pure/override/internals/set-helpers.js index bdf35ecde927..73dc651cc017 100644 --- a/packages/core-js-pure/override/internals/set-helpers.js +++ b/packages/core-js-pure/override/internals/set-helpers.js @@ -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) { @@ -54,5 +55,7 @@ module.exports = { has: has, size: size, clone: clone, - iterate: iterate + iterate: iterate, + $has: SetPrototype.has, + $keys: SetPrototype.keys }; diff --git a/packages/core-js/internals/set-helpers.js b/packages/core-js/internals/set-helpers.js index bc7cae631611..beedb7cb1a1f 100644 --- a/packages/core-js/internals/set-helpers.js +++ b/packages/core-js/internals/set-helpers.js @@ -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) { @@ -42,5 +44,7 @@ module.exports = { has: has, size: size, clone: clone, - iterate: iterate + iterate: iterate, + $has: $has, + $keys: $keys }; diff --git a/packages/core-js/internals/set-intersection.js b/packages/core-js/internals/set-intersection.js index bcbf8a9d49b1..8e86fece661b 100644 --- a/packages/core-js/internals/set-intersection.js +++ b/packages/core-js/internals/set-intersection.js @@ -9,6 +9,12 @@ 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 @@ -16,11 +22,25 @@ 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; }; diff --git a/tests/unit-global/esnext.set.intersection.js b/tests/unit-global/esnext.set.intersection.js index 3111adec2550..133767833bd2 100644 --- a/tests/unit-global/esnext.set.intersection.js +++ b/tests/unit-global/esnext.set.intersection.js @@ -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]); diff --git a/tests/unit-pure/esnext.set.intersection.js b/tests/unit-pure/esnext.set.intersection.js index d2798cce7740..e69270a33403 100644 --- a/tests/unit-pure/esnext.set.intersection.js +++ b/tests/unit-pure/esnext.set.intersection.js @@ -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]);