Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reference for stage 3 set-methods #28414

Merged
merged 5 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
title: Set.prototype.difference()
slug: Web/JavaScript/Reference/Global_Objects/Set/difference
page-type: javascript-instance-method
browser-compat: javascript.builtins.Set.difference
---

{{JSRef}}

The **`difference()`** method of {{jsxref("Set")}} instances takes a set and returns a new set containing elements in this set but not in the given set.

## Syntax

```js-nolint
difference(other)
```

### Parameters

- `other`
- : A {{jsxref("Set")}} object, or [set-like](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#set-like_objects) object.

### Return value

A new {{jsxref("Set")}} object containing elements in this set but not in `other`.

## Description

In mathematical notation, _difference_ is defined as:

<math display="block"><semantics><mrow><mi>A</mi><mo>∖</mo><mi>B</mi><mo>=</mo><mo stretchy="false">{</mo><mi>x</mi><mo>∊</mo><mi>A</mi><mo>∣</mo><mi>x</mi><mo>∉</mo><mi>B</mi><mo stretchy="false">}</mo></mrow><annotation encoding="TeX">A\setminus B = \{x\in A\mid x\notin B\}</annotation></semantics></math>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The <mo>∊</mo> and <mo>∉</mo> are very different sizes. Just want to confirm that that is OK.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's mostly a font issue. MDN doesn't seem to be using a decent math font.


And using Venn diagram:

![A Venn diagram illustrating the difference between set A and B](diagram.svg)

`difference()` accepts [set-like](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#set-like_objects) objects as the `other` parameter. It requires {{jsxref("Operators/this", "this")}} to be an actual {{jsxref("Set")}} instance, because it directly retrieves the underlying data stored in `this` without invoking any user code. Then, its behavior depends on the sizes of `this` and `other`:

- If there are more elements in `this` than `other.size`, then it iterates over `other` by calling its `keys()` method, and constructs a new set with all elements in `this` that are not seen in `other`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- If there are more elements in `this` than `other.size`, then it iterates over `other` by calling its `keys()` method, and constructs a new set with all elements in `this` that are not seen in `other`.
- If there are more elements in `this` than `other.size`, then it iterates over `other` by calling its {{jsxref("Set.prototype.keys()", "keys()")}} method, and constructs a new set with all elements in `this` that are not seen in `other`.

or /en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The keys() method here is an arbitrary method that the user provides, which may or may not be Set.prototype.keys(). This is explained in the "set-like objects" section, linked above.

- Otherwise, it iterates over the elements in `this`, and constructs a new set with all elements `e` in `this` that cause `other.has(e)` to return a [falsy](/en-US/docs/Glossary/Falsy) value.

The order of elements in the returned set is the same as in `this`.

## Examples

### Using difference()

The following example computes the difference between the set of odd numbers (<10) and the set of perfect squares (<10). The result is the set of odd numbers that are not perfect squares.

```js
const odds = new Set([1, 3, 5, 7, 9]);
const squares = new Set([1, 4, 9]);
console.log(odds.difference(squares)); // Set(3) { 3, 5, 7 }
```

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- [Polyfill of `Set.prototype.difference` in `core-js`](https://github.com/zloirock/core-js#new-set-methods)
- {{jsxref("Set.prototype.intersection()")}}
- {{jsxref("Set.prototype.isDisjointFrom()")}}
- {{jsxref("Set.prototype.isSubsetOf()")}}
- {{jsxref("Set.prototype.isSupersetOf()")}}
- {{jsxref("Set.prototype.symmetricDifference()")}}
- {{jsxref("Set.prototype.union()")}}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,83 @@ Value equality is based on the [SameValueZero](/en-US/docs/Web/JavaScript/Equali

The [`has`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has) method checks if a value is in the set, using an approach that is, on average, quicker than testing most of the elements that have previously been added to the set. In particular, it is, on average, faster than the [`Array.prototype.includes`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes) method when an array has a `length` equal to a set's `size`.

### Set composition

The `Set` object provides some methods that allow you to compose sets like you would with mathematical operations. These methods include:

<table>
<thead>
<tr>
<th scope="col">Method</th>
<th scope="col">Mathematical equivalent</th>
<th scope="col">Venn diagram</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{jsxref("Set/difference", "A.difference(B)")}}</td>
<td><math display="inline"><semantics><mrow><mi>A</mi><mo>∖</mo><mi>B</mi></mrow><annotation encoding="TeX">A\setminus B</annotation></semantics></math></td>
<td style="margin:0;padding:0"><img src="difference/diagram.svg" alt="A Venn diagram illustrating the difference between set A and B" style="margin:0;border:0;border-radius:0" width="200" /></td>
</tr>
<tr>
<td>{{jsxref("Set/intersection", "A.intersection(B)")}}</td>
<td><math display="inline"><semantics><mrow><mi>A</mi><mo>∩</mo><mi>B</mi></mrow><annotation encoding="TeX">A\cap B</annotation></semantics></math></td>
<td style="margin:0;padding:0"><img src="intersection/diagram.svg" alt="A Venn diagram illustrating the intersection between set A and B" style="margin:0;border:0;border-radius:0" width="200" /></td>
</tr>
<tr>
<td>{{jsxref("Set/isDisjointFrom", "A.isDisjointFrom(B)")}}</td>
<td><math display="inline"><semantics><mrow><mi>A</mi><mo>∩</mo><mi>B</mi><mo>=</mo><mi>∅</mi></mrow><annotation encoding="TeX">A\cap B = \empty</annotation></semantics></math></td>
<td style="margin:0;padding:0"><img src="isDisjointFrom/diagram.svg" alt="A Venn diagram illustrating two sets A and B with no intersection" style="margin:0;border:0;border-radius:0" width="200" /></td>
</tr>
<tr>
<td>{{jsxref("Set/isSubsetOf", "A.isSubsetOf(B)")}}</td>
<td><math display="inline"><semantics><mrow><mi>A</mi><mo>⊆</mo><mi>B</mi></mrow><annotation encoding="TeX">A\subseteq B</annotation></semantics></math></td>
<td style="margin:0;padding:0"><img src="isSubsetOf/diagram.svg" alt="A Venn diagram illustrating set A being a subset of B" style="margin:0;border:0;border-radius:0" width="200" /></td>
</tr>
<tr>
<td>{{jsxref("Set/isSupersetOf", "A.isSupersetOf(B)")}}</td>
<td><math display="inline"><semantics><mrow><mi>A</mi><mo>⊇</mo><mi>B</mi></mrow><annotation encoding="TeX">A\supseteq B</annotation></semantics></math></td>
<td style="margin:0;padding:0"><img src="isSupersetOf/diagram.svg" alt="A Venn diagram illustrating set A being a superset of B" style="margin:0;border:0;border-radius:0" width="200" /></td>
</tr>
<tr>
<td>{{jsxref("Set/symmetricDifference", "A.symmetricDifference(B)")}}</td>
<td><math display="inline"><semantics><mrow><mo stretchy="false">(</mo><mi>A</mi><mo>∖</mo><mi>B</mi><mo stretchy="false">)</mo><mo>∪</mo><mo stretchy="false">(</mo><mi>B</mi><mo>∖</mo><mi>A</mi><mo stretchy="false">)</mo></mrow><annotation encoding="TeX">(A\setminus B)\cup(B\setminus A)</annotation></semantics></math></td>
<td style="margin:0;padding:0"><img src="symmetricDifference/diagram.svg" alt="A Venn diagram illustrating the symmetric difference between set A and B" style="margin:0;border:0;border-radius:0" width="200" /></td>
</tr>
<tr>
<td>{{jsxref("Set/union", "A.union(B)")}}</td>
<td><math display="inline"><semantics><mrow><mi>A</mi><mo>∪</mo><mi>B</mi></mrow><annotation encoding="TeX">A\cup B</annotation></semantics></math></td>
<td style="margin:0;padding:0"><img src="union/diagram.svg" alt="A Venn diagram illustrating the union between set A and B" style="margin:0;border:0;border-radius:0" width="200" /></td>
</tr>
</tbody>
</table>

To make them more generalizable, these methods don't just accept `Set` objects, but anything that's [set-like](#set-like_objects).

### Set-like objects

All [set methods](#set_methods) require {{jsxref("Operators/this", "this")}} to be an actual `Set` instance, but their arguments just need to be set-like. A _set-like object_ is an object that provides the following:

- A {{jsxref("Set/size", "size")}} property that contains a number.
- A {{jsxref("Set/has", "has()")}} method that takes an element and returns a boolean.
- A {{jsxref("Set/keys", "keys()")}} method that returns an [iterator](/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) of the elements in the set.

For example, {{jsxref("Map")}} objects are set-like because they also have {{jsxref("Map/size", "size")}}, {{jsxref("Map/has", "has()")}}, and {{jsxref("Map/keys", "keys()")}}, so they behave just like sets of keys when used in set methods:

```js
const a = new Set([1, 2, 3]);
const b = new Map([
[1, "one"],
[2, "two"],
[4, "four"],
]);
console.log(a.union(b)); // Set(4) {1, 2, 3, 4}
```

> **Note:** The set-like protocol invokes the `keys()` method instead of [`[@@iterator]()`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/@@iterator) to produce elements, because for maps, the iterator produces _entries_ but the `has()` method takes _keys_, and maps are intended to behave like sets of keys.

[Arrays](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) are not set-like because they don't have a `has()` method or the `size` property, and their `keys()` method produces indices instead of elements. {{jsxref("WeakSet")}} objects are also not set-like because they don't have a `keys()` method.

### Set-like browser APIs

Browser **`Set`-like objects** (or "setlike objects") are [Web API](/en-US/docs/Web/API) interfaces that behave in many ways like a `Set`.
Expand Down Expand Up @@ -88,14 +165,28 @@ These properties are defined on `Set.prototype` and shared by all `Set` instance
- : Removes all elements from the `Set` object.
- {{jsxref("Set.prototype.delete()")}}
- : Removes the element associated to the `value` and returns a boolean asserting whether an element was successfully removed or not. `Set.prototype.has(value)` will return `false` afterwards.
- {{jsxref("Set.prototype.difference()")}}
- : Takes a set and returns a new set containing elements in this set but not in the given set.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- : Takes a set and returns a new set containing elements in this set but not in the given set.
- : Takes a set and returns a new set containing elements in this set that are not in the given set.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find both equally fine, but the preposition "but" makes the logical relationship slightly more saliant.

- {{jsxref("Set.prototype.entries()")}}
- : Returns a new iterator object that contains **an array of `[value, value]`** for each element in the `Set` object, in insertion order. This is similar to the {{jsxref("Map")}} object, so that each entry's _key_ is the same as its _value_ for a `Set`.
- {{jsxref("Set.prototype.forEach()")}}
- : Calls `callbackFn` once for each value present in the `Set` object, in insertion order. If a `thisArg` parameter is provided, it will be used as the `this` value for each invocation of `callbackFn`.
- {{jsxref("Set.prototype.has()")}}
- : Returns a boolean asserting whether an element is present with the given value in the `Set` object or not.
- {{jsxref("Set.prototype.intersection()")}}
- : Takes a set and returns a new set containing elements both in this set and in the given set.
- {{jsxref("Set.prototype.isDisjointFrom()")}}
- : Takes a set and returns a boolean indicating if this set has no elements in common with the given set.
- {{jsxref("Set.prototype.isSubsetOf()")}}
- : Takes a set and returns a boolean indicating if all elements of this set are in the given set.
- {{jsxref("Set.prototype.isSupersetOf()")}}
- : Takes a set and returns a boolean indicating if all elements of the given set are in this set.
- {{jsxref("Set.prototype.keys()")}}
- : An alias for {{jsxref("Set.prototype.values()")}}.
- {{jsxref("Set.prototype.symmetricDifference()")}}
- : Takes a set and returns a new set containing elements which are in either this set or the given set, but not in both.
- {{jsxref("Set.prototype.union()")}}
- : Takes a set and returns a new set containing elements which are in either or both of this set and the given set.
- {{jsxref("Set.prototype.values()")}}
- : Returns a new iterator object that yields the **values** for each element in the `Set` object in insertion order.
- [`Set.prototype[@@iterator]()`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/@@iterator)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
title: Set.prototype.intersection()
slug: Web/JavaScript/Reference/Global_Objects/Set/intersection
page-type: javascript-instance-method
browser-compat: javascript.builtins.Set.intersection
---

{{JSRef}}

The **`intersection()`** method of {{jsxref("Set")}} instances takes a set and returns a new set containing elements both in this set and in the given set.

## Syntax

```js-nolint
intersection(other)
```

### Parameters

- `other`
- : A {{jsxref("Set")}} object, or [set-like](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#set-like_objects) object.

### Return value

A new {{jsxref("Set")}} object containing elements both in this set and in `other`.

## Description

In mathematical notation, _intersection_ is defined as:

<math display="block"><semantics><mrow><mi>A</mi><mo>∩</mo><mi>B</mi><mo>=</mo><mo stretchy="false">{</mo><mi>x</mi><mo>∊</mo><mi>A</mi><mo>∣</mo><mi>x</mi><mo>∊</mo><mi>B</mi><mo stretchy="false">}</mo></mrow><annotation encoding="TeX">A\cap B = \{x\in A\mid x\in B\}</annotation></semantics></math>

And using Venn diagram:

![A Venn diagram illustrating the intersection between set A and B](diagram.svg)

`intersection()` accepts [set-like](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#set-like_objects) objects as the `other` parameter. It requires {{jsxref("Operators/this", "this")}} to be an actual {{jsxref("Set")}} instance, because it directly retrieves the underlying data stored in `this` without invoking any user code. Then, its behavior depends on the sizes of `this` and `other`:

- If there are more elements in `this` than `other.size`, then it iterates over `other` by calling its `keys()` method, and constructs a new set with all elements produced that are also present in `this`.
- Otherwise, it iterates over the elements in `this`, and constructs a new set with all elements `e` in `this` that cause `other.has(e)` to return a [truthy](/en-US/docs/Glossary/Truthy) value.

Because of this implementation, the efficiency of `intersection()` mostly depends on the size of the smaller set between `this` and `other` (assuming sets can be accessed in sublinear time). The order of elements in the returned set is the same as that of the smaller of `this` and `other`.

## Examples

### Using intersection()

The following example computes the intersection between the set of odd numbers (<10) and the set of perfect squares (<10). The result is the set of odd numbers that are perfect squares.

```js
const odds = new Set([1, 3, 5, 7, 9]);
const squares = new Set([1, 4, 9]);
console.log(odds.intersection(squares)); // Set(2) { 1, 9 }
```

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- [Polyfill of `Set.prototype.intersection` in `core-js`](https://github.com/zloirock/core-js#new-set-methods)
- {{jsxref("Set.prototype.difference()")}}
- {{jsxref("Set.prototype.isDisjointFrom()")}}
- {{jsxref("Set.prototype.isSubsetOf()")}}
- {{jsxref("Set.prototype.isSupersetOf()")}}
- {{jsxref("Set.prototype.symmetricDifference()")}}
- {{jsxref("Set.prototype.union()")}}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
title: Set.prototype.isDisjointFrom()
slug: Web/JavaScript/Reference/Global_Objects/Set/isDisjointFrom
page-type: javascript-instance-method
browser-compat: javascript.builtins.Set.isDisjointFrom
---

{{JSRef}}

The **`isDisjointFrom()`** method of {{jsxref("Set")}} instances takes a set and returns a boolean indicating if this set has no elements in common with the given set.

## Syntax

```js-nolint
isDisjointFrom(other)
```

### Parameters

- `other`
- : A {{jsxref("Set")}} object, or [set-like](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#set-like_objects) object.

### Return value

`true` if this set has no elements in common with `other`, and `false` otherwise.

## Description

Two sets are _disjoint_ if they have no elements in common. In mathematical notation:

<math display="block"><semantics><mrow><mi>A</mi><mtext>&nbsp;is disjoint from&nbsp;</mtext><mi>B</mi><mo stretchy="false">⇔</mo><mi>A</mi><mo>∩</mo><mi>B</mi><mo>=</mo><mi>∅</mi></mrow><annotation encoding="TeX">A\text{ is disjoint from }B \Leftrightarrow A\cap B = \empty</annotation></semantics></math>

And using Venn diagram:

![A Venn diagram illustrating two sets A and B with no intersection](diagram.svg)

`isDisjointFrom()` accepts [set-like](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#set-like_objects) objects as the `other` parameter. It requires {{jsxref("Operators/this", "this")}} to be an actual {{jsxref("Set")}} instance, because it directly retrieves the underlying data stored in `this` without invoking any user code. Then, its behavior depends on the sizes of `this` and `other`:

- If there are more elements in `this` than `other.size`, then it iterates over `other` by calling its `keys()` method, and if any element in `other` is present in `this`, it returns `false` (and closes the `keys()` iterator by calling its `return()` method). Otherwise, it returns `true`.
- Otherwise, it iterates over the elements in `this`, and returns `false` if any element `e` in `this` causes `other.has(e)` to return a [truthy](/en-US/docs/Glossary/Truthy) value. Otherwise, it returns `true`.

Because of this implementation, the efficiency of `isDisjointFrom()` mostly depends on the size of the smaller set between `this` and `other` (assuming sets can be accessed in sublinear time).

## Examples

### Using isDisjointFrom()

The set of perfect squares (<20) is disjoint from the set of prime numbers (<20), because a perfect square is by definition decomposable into the product of two integers, while 1 is also not considered a prime number:

```js
const primes = new Set([2, 3, 5, 7, 11, 13, 17, 19]);
const squares = new Set([1, 4, 9, 16]);
console.log(primes.isDisjointFrom(squares)); // true
```

The set of perfect squares (<20) is not disjoint from the set of composite numbers (<20), because all non-1 perfect squares are by definition composite numbers:

```js
const composites = new Set([4, 6, 8, 9, 10, 12, 14, 15, 16, 18]);
const squares = new Set([1, 4, 9, 16]);
console.log(composites.isDisjointFrom(squares)); // false
```

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- [Polyfill of `Set.prototype.isDisjointFrom` in `core-js`](https://github.com/zloirock/core-js#new-set-methods)
- {{jsxref("Set.prototype.difference()")}}
- {{jsxref("Set.prototype.intersection()")}}
- {{jsxref("Set.prototype.isSubsetOf()")}}
- {{jsxref("Set.prototype.isSupersetOf()")}}
- {{jsxref("Set.prototype.symmetricDifference()")}}
- {{jsxref("Set.prototype.union()")}}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading