Skip to content

Instantly share code, notes, and snippets.

@MikeyBurkman
Last active June 9, 2017 20:15
Show Gist options
  • Save MikeyBurkman/a4241fb05534065e19571b25f7dfc4f2 to your computer and use it in GitHub Desktop.
Save MikeyBurkman/a4241fb05534065e19571b25f7dfc4f2 to your computer and use it in GitHub Desktop.
JS Set implementation without prototype nonsense
'use strict';
// A drop-in replacement for Set.
// Why?
// 1) newSet() can be called as a regular function (no need for new)
// 2) None of the functions on it use `this`, which means they can be used as higher-order functions
function newSet(initialValues) {
const s = new Set();
const o = {
// Standard set functions
add: (value) => { s.add(value); return o; },
clear: s.clear.bind(s),
delete: s.delete.bind(s),
entries: s.entries.bind(s),
forEach: s.forEach.bind(s),
has: s.has.bind(s),
keys: s.keys.bind(s),
values: s.values.bind(s),
[Symbol.iterator]: s[Symbol.iterator].bind(s),
// Extra utility methods
addAll: (values) => { values.forEach(o.add); return o; },
deleteAll: (values) => values.map(o.delete).some((i) => i),
hasAll: (values) => values.every(o.has),
asArray: () => Array.from(o[Symbol.iterator]())
};
if (initialValues !== undefined) {
o.addAll(initialValues);
}
return o;
}
// Usage
const s = newSet([1, 2]);
['abc', 'def', 'ghi'].forEach(s.add);
console.log('s has 2: ', s.has(2)); // true
console.log('s has abc: ', s.has('abc')); // true
console.log('s has def: ', s.has('def')); // true
console.log('s has ghi: ', s.has('ghi')); // true
console.log('s has xyz: ', s.has('xyz')); // false
console.log('s has both 1 and 2: ', s.hasAll([1, 2])); // true
console.log('s has both abc and xyz: ', s.hasAll(['abc', 'xyz'])); // false
s.deleteAll([2, 'ghi']);
// Test iteration
for (let x of s) {
console.log('\t x = ', x);
}
console.log('s = ', s.asArray()); // [ 1, 'abc', 'def' ]
function whyNotRegularSet() {
const s2 = new Set();
// The following line will throw.
// Need to do s2.add.bind(s2) to make this work.
[1, 2, 3].forEach(s2.add);
console.log(s2.has(1));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment