Set.prototype.symmetricDifference()

Returns a new Set of the elements that are in one set or the other, but not in both.

Signature
symmetricDifference(other)
  • Added in JavaScript ES2025

Parameters

ParameterTypeDescription
$otherSet | set-like objectA Set, or any set-like object: one with a numeric size property and callable has() and keys() methods. Map qualifies, and its keys are used.

Return value

SetA new Set object containing the elements that are in either this set or the other set, but not in both. Elements from this set come first, followed by elements from other.

Errors

Throws a TypeError if other is not set-like — that is, if it lacks a non-negative numeric size or callable has() and keys() methods (an Array fails this test).

Changelog

  • PHP ES2025Added along with union(), intersection(), difference(), isSubsetOf(), isSupersetOf() and isDisjointFrom(); Baseline newly available since June 2024.

symmetricDifference() answers "what is different between these two sets?" in one call. It is the union of the two one-way differences: everything in a that is missing from b, followed by everything in b that is missing from a. Written out, a.symmetricDifference(b) is equivalent to a.difference(b).union(b.difference(a)), but it reads better and only walks each collection once.

When to reach for it

Use it whenever you have a previous state and a next state and want the churn, not the overlap: which feature flags flipped, which permissions were added or revoked, which file names appeared or vanished between two scans. If you need to know which side a value came from, use difference() twice instead — the symmetric difference throws that information away.

What trips people up

The argument must be set-like, and an Array is not: it has length, not size, so passing one throws a TypeError. Wrap it in new Set(arr) first. A Map, on the other hand, works and is matched on its keys.

Membership uses SameValueZero, so two objects with identical contents are still two different elements, and NaN matches NaN.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Show which tags were added or removed between two saves of a document
  • Report the feature flags that differ between staging and production
  • Find files that exist in only one of two directory listings
  • Detect which user roles changed after a permissions sync

Frequently asked questions

How is symmetricDifference different from difference?

symmetricDifference() is two-way and difference() is one-way: a.difference(b) keeps only elements of a that are missing from b, while a.symmetricDifference(b) also adds the elements of b that are missing from a. Use difference() when you care which side a value came from.

Can I call symmetricDifference on an array?

No — the method only exists on Set instances, and the argument must also be set-like. Convert both sides with new Set(...), then spread the result back to an array if you need one.

What order are the results in?

Elements from the receiver come first in their insertion order, followed by the elements contributed by other. The returned value is always a new Set; neither input is modified.

More examples

Comparing against a Map

A Map is set-like, so it can be passed directly. Only its keys take part in the comparison — the values are never read. The output shows the id present only in the set (1) and the key present only in the map (4).

Example · javascript
const ids = new Set([1, 2, 3]);
const rows = new Map([
  [2, { name: "b" }],
  [3, { name: "c" }],
  [4, { name: "d" }],
]);

console.log([...ids.symmetricDifference(rows)]); // [1, 4]

Arrays must be converted first

The first call fails because an array has no size property, so it is not set-like. Wrapping the array in a Set makes the same comparison work and yields the two values that appear on only one side.

Example · javascript
const set = new Set(["a", "b"]);

try {
  set.symmetricDifference(["b", "c"]);
} catch (err) {
  console.log(err.name); // "TypeError"
}

console.log([...set.symmetricDifference(new Set(["b", "c"]))]); // ["a", "c"]

Objects compare by identity

The shared object is the same reference on both sides, so it is excluded. The two distinct { id: 2 } literals are different references, so each survives — producing a set of size 2 that looks like a duplicate when you print the ids.

Example · javascript
const shared = { id: 1 };
const a = new Set([shared, { id: 2 }]);
const b = new Set([shared, { id: 2 }]);

console.log(a.symmetricDifference(b).size); // 2
console.log([...a.symmetricDifference(b)].map((o) => o.id)); // [2, 2]

Discussion

  • Be the first to comment on this lesson.