export default class BiMap {
constructor(items = []) {
this._valueForKey = new Map;
this._keyForValue = new Map;
for (let [key, value] of items)
this.set(key, value);
}
// Public
get size() {
return this._valueForKey.size;
}
has(key) {
return this.hasKey(key);
}
hasKey(key) {
return this._valueForKey.has(key);
}
hasValue(value) {
return this._keyForValue.has(value);
}
get(key) {
return this.getValue(key);
}
getValue(key) {
return this._valueForKey.get(key);
}
getKey(value) {
return this._keyForValue.get(value);
}
set(key, value) {
this.deleteKey(key);
this.deleteValue(value);
this._valueForKey.set(key, value);
this._keyForValue.set(value, key);
console.assert(this._valueForKey.size === this._keyForValue.size, this);
}
delete(key) {
return this.deleteKey(key);
}
deleteKey(key) {
let value = this.getValue(key);
let deletedKey = this._valueForKey.delete(key);
let deletedValue = this._keyForValue.delete(value);
console.assert(deletedKey === deletedValue, this);
console.assert(this._valueForKey.size === this._keyForValue.size, this);
return deletedKey;
}
deleteValue(value) {
let key = this.getKey(value);
let deletedKey = this._valueForKey.delete(key);
let deletedValue = this._keyForValue.delete(value);
console.assert(deletedKey === deletedValue, this);
console.assert(this._valueForKey.size === this._keyForValue.size, this);
return deletedValue;
}
take(key) {
return this.takeKey(key);
}
takeKey(key) {
let value = this.getValue(key);
let deletedKey = this._valueForKey.delete(key);
let deletedValue = this._keyForValue.delete(value);
console.assert(deletedKey === deletedValue, this);
console.assert(this._valueForKey.size === this._keyForValue.size, this);
return value;
}
takeValue(value) {
let key = this.getKey(value);
let deletedKey = this._valueForKey.delete(key);
let deletedValue = this._keyForValue.delete(value);
console.assert(deletedKey === deletedValue, this);
console.assert(this._valueForKey.size === this._keyForValue.size, this);
return key;
}
clear() {
this._valueForKey.clear();
this._keyForValue.clear();
}
keys() {
return this._valueForKey.keys();
}
values() {
return this._valueForKey.values();
}
entries() {
return this._valueForKey.entries();
}
[Symbol.iterator]() {
return this._valueForKey[Symbol.iterator]();
}
toJSON() {
return Array.from(this);
}
}