ECMAScript 6 sets: union, intersection, difference

[2015-01-14] esnext, dev, javascript
(Ad, please don’t block)
Warning: This blog post is outdated. Instead, read section “Missing Set operations” in “JavaScript for impatient programmers”.

A recent question by Dmitry Moskowski reminded me: ECMAScript 6 sets have no methods for computing the union (e.g. addAll), intersection (e.g. retainAll) or difference (e.g. removeAll). This blog post explains how to work around that limitation.

Union  

Union (ab): create a set that contains the elements of both set a and set b.

let a = new Set([1,2,3]);
let b = new Set([4,3,2]);
let union = new Set([...a, ...b]);
    // {1,2,3,4}

The pattern is always the same:

  • Convert one or both sets to arrays.
  • Perform the operation.
  • Convert the result back to a set.

As explained in [1], the spread operator (...) inserts the elements of something iterable (like a set) into an array. Therefore, [...a, ...b] means that a and b are converted to arrays and concatenated. It is equivalent to [...a].concat([...b]).

Intersection  

Intersection (ab): create a set that contains those elements of set a that are also in set b.

let a = new Set([1,2,3]);
let b = new Set([4,3,2]);
let intersection = new Set(
    [...a].filter(x => b.has(x)));
    // {2,3}

Steps: Convert a to an array, filter the elements, convert the result to a set.

Difference  

Difference (a \ b): create a set that contains those elements of set a that are not in set b. This operation is also sometimes called minus (-).

let a = new Set([1,2,3]);
let b = new Set([4,3,2]);
let difference = new Set(
    [...a].filter(x => !b.has(x)));
    // {1}

Conclusion  

This blog post showed how you can implement union, intersection and different for sets. Long-term, I expect JavaScript to have built-in functionality for this, e.g. via functions that operate on iterables (similar to Python’s itertools).

Further reading  


  1. ECMAScript 6: maps and sets ↩︎