Working with Sets Flashcards

1
Q

What is a Set?

A

Set objects are collections of values. A value in the set may only occur once; it is unique in the set’s collection. You can iterate through the elements of a set in insertion order. The insertion order corresponds to the order in which each element was inserted into the set by the add() method successfully (that is, there wasn’t an identical element already in the set when add() was called).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What did we use before Sets?

A

Before ES6, JavaScript didn’t have a data structure for sets. Instead, two workarounds were used:

  • The keys of an object were used as a set of strings.
  • Arrays were used as sets of arbitrary values. The downside is that checking membership (if an Array contains a value) is slower.

Since ES6, JavaScript has the data structure Set, which can contain arbitrary values and performs membership checks quickly.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

How do you create a Set?

A

There are three common ways of creating Sets.

First, you can use the constructor without any parameters to create an empty Set:

const emptySet = new Set();
assert.equal(emptySet.size, 0);

Second, you can pass an iterable (e.g., an Array) to the constructor. The iterated values become elements of the new Set:

const set = new Set(['red', 'green', 'blue']);

Third, the .add() method adds elements to a Set and is chainable:

const set = new Set()
.add('red')
.add('green')
.add('blue');
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

How can you add, remove, and check membership in a Set?

A

.add() adds an element to a Set.

const set = new Set();
set.add('red');

.has() checks if an element is a member of a Set.

assert.equal(set.has('red'), true);

.delete() removes an element from a Set.

assert.equal(set.delete('red'), true); // there was a deletion
assert.equal(set.has('red'), false);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

How can you determine the size of a Set?

A

.size contains the number of elements in a Set.

const set = new Set()
  .add('foo')
  .add('bar');
assert.equal(set.size, 2)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

How can you clear a Set?

A

.clear() removes all elements of a Set.

set.clear();
assert.equal(set.size, 0)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How can you iterate over Sets?

A

Sets are iterable and the for-of loop works as you’d expect:

const set = new Set(['red', 'green', 'blue']);
for (const x of set) {
  console.log(x);
}
// Output:
// 'red'
// 'green'
// 'blue'

As you can see, Sets preserve insertion order. That is, elements are always iterated over in the order in which they were added.

Given that Sets are iterable, you can use Array.from() to convert them to Arrays:

const set = new Set(['red', 'green', 'blue']);
const arr = Array.from(set); // ['red', 'green', 'blue']
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

How can you remove duplicates on an Array using Sets?

A

Converting an Array to a Set and back, removes duplicates from the Array:

assert.deepEqual(
  Array.from(new Set([1, 2, 1, 2, 3, 3, 3])),
  [1, 2, 3]);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

What Set elements are considered equal?

A

As with Map keys, Set elements are compared similarly to ===, with the exception of NaN being equal to itself.

const set = new Set([NaN, NaN, NaN]);
set.size; // 1

set.has(NaN); // true

As with ===, two different objects are never considered equal (and there is no way to change that at the moment):

const set = new Set();

set.add({});
set.size; // 1

set.add({});
set.size; // 2
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

How can you compute the union of two Sets (a ∪ b)?

A

Computing the union of two Sets a and b means creating a Set that contains the elements of both a and b.

const a = new Set([1,2,3]);
const b = new Set([4,3,2]);
// Use spreading to concatenate two iterables
const union = new Set([...a, ...b]);

assert.deepEqual(Array.from(union), [1, 2, 3, 4]);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

How can you compute the intersection of two Sets (a ∩ b) ?

A

Computing the intersection of two Sets a and b means creating a Set that contains those elements of a that are also in b.

const a = new Set([1,2,3]);
const b = new Set([4,3,2]);
const intersection = new Set(
  Array.from(a).filter(x => b.has(x))
);

assert.deepEqual(
  Array.from(intersection), [2, 3]
);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

How can you compute the difference of two Sets (a \ b)?

A

Computing the difference between two Sets a and b means creating a Set that contains those elements of a that are not in b. This operation is also sometimes called minus ().

const a = new Set([1,2,3]);
const b = new Set([4,3,2]);
const difference = new Set(
  Array.from(a).filter(x => !b.has(x))
);

assert.deepEqual(
  Array.from(difference), [1]
);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

How can you map over a Set?

A

Sets don’t have a method .map(). But we can borrow the one that Arrays have:

const set = new Set([1, 2, 3]);
const mappedSet = new Set(
  Array.from(set).map(x => x * 2)
);

// Convert mappedSet to an Array to check what’s inside it
assert.deepEqual(
  Array.from(mappedSet), [2, 4, 6]
);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

How can you filter over a Set?

A

We can’t directly .filter() Sets, so we need to use the corresponding Array method:

const set = new Set([1, 2, 3, 4, 5]);
const filteredSet = new Set(
  Array.from(set).filter(x => (x % 2) === 0)
);

assert.deepEqual(
  Array.from(filteredSet), [2, 4]
);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Why do Sets have a .size, while Arrays have a .length?

A

In JavaScript, indexable sequences (such as Arrays and strings) have a .length, while unindexed collections (such as Maps and Sets) have a .size:

  • .length is based on indices; it is always the highest index plus one.
  • .size counts the number of elements in a collection.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly