Skip to content

Instantly share code, notes, and snippets.

@bradennapier
Created May 30, 2018 18:15
Show Gist options
  • Save bradennapier/c6a8f1ea34b56297c62854fcd7d0472a to your computer and use it in GitHub Desktop.
Save bradennapier/c6a8f1ea34b56297c62854fcd7d0472a to your computer and use it in GitHub Desktop.
/**
* SetMap provides an extended Map which mixes in some extra commands. The idea is
* to use this when you need to manage a Map of Sets or Maps. It provides various
* prototype methods that make it easy to build these data structures.
*
* Map<any, Set<any> | Map<any, any> | any>
* @extends {Map}
*/
export default class SetMap extends Map {
add(key, ...values) {
return this.addSet(key, ...values);
}
addSet(key, ...values) {
let val;
if (this.has(key)) {
val = this.get(key);
if (!(val instanceof Set)) {
throw TypeError(`[SetMap] | addSet | ERROR | Expected ${key} to be a Set`);
}
} else {
val = new Set();
this.set(key, val);
}
values.forEach(v => val.add(v));
return this;
}
addMap(key, mapKey, mapValue) {
let val;
if (this.has(key)) {
val = this.get(key);
if (!(val instanceof Map)) {
throw TypeError(`[SetMap] | addMap | ERROR | Expected ${key} to be a Map`);
}
} else {
val = new Map();
this.set(key, val);
}
val.set(mapKey, mapValue);
return this;
}
hasSet(...args) {
return this.hasMap(...args);
}
hasMap(key, ...values) {
let val;
if (this.has(key)) {
val = this.get(key);
if (!(val instanceof Set || val instanceof Map)) {
throw TypeError(`[SetMap] | hasMap/hasSet | ERROR | Expected ${key} to be a Map or Set`);
}
return values.every(v => val.has(v));
}
return false;
}
sizeSet(key) {
return this.sizeMap(key);
}
sizeMap(key) {
let val;
if (this.has(key)) {
val = this.get(key);
if (!(val instanceof Set || val instanceof Map)) {
throw TypeError(`[SetMap] | sizeMap/sizeSet | ERROR | Expected ${key} to be a Map or Set`);
}
return val.size;
}
return 0;
}
remove(key, ...values) {
if (values.length && this.has(key)) {
const val = this.get(key);
if (val instanceof Set || val instanceof Map) {
values.forEach(v => val.delete(v));
if (val.size === 0) {
this.delete(key);
}
} else {
throw TypeError(`[SetMap] | remove | ERROR | Expected ${key} to be a Set or Map`);
}
}
return this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment