deep-equality-data-structures
Version:
Javascript data structures (e.g., Map, Set) that support deep object equality
72 lines (71 loc) • 2.44 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BiDirectionalDeepMap = void 0;
const errors_1 = require("./errors");
const map_1 = require("./map");
const utils_1 = require("./utils");
/**
* A DeepMap implementation that supports O(1) lookups by both keys and values
* NOTE: All key-value pairs must be 1-to-1
*/
class BiDirectionalDeepMap extends map_1.DeepMap {
/**
* @param entries optional list of key-value pairs to initialize the map
* @param options configuration options
*/
constructor(entries, options) {
super(entries, options);
const valueEntries = entries ? entries.map(([key, val]) => [this.normalizeValue(val), key]) : null;
this.valueMap = new Map(valueEntries);
}
/**
* @inheritdoc
*/
set(key, val) {
// Enforce 1-to-1: Don't allow writing a value which is already present in the map for a different key
const preexistingValueKey = this.getKeyByValue(val);
if (preexistingValueKey !== undefined && this.normalizeKey(preexistingValueKey) !== this.normalizeKey(key)) {
throw new errors_1.DeepEqualityDataStructuresError(`Could not set key='${(0, utils_1.stringify)(key)}': The value='${(0, utils_1.stringify)(val)}' is already associated with key='${(0, utils_1.stringify)(preexistingValueKey)}'`);
}
this.valueMap.set(this.normalizeValue(val), key);
return super.set(key, val);
}
/**
* @inheritdoc
*/
delete(key) {
const val = this.get(key);
if (val) {
this.valueMap.delete(this.normalizeValue(val));
}
return super.delete(key);
}
/**
* @inheritdoc
*/
clear() {
this.valueMap.clear();
super.clear();
}
// BI-DIRECTIONAL API
/**
* @returns true if the given value is present in the key-value map.
*/
hasValue(val) {
return this.valueMap.has(this.normalizeValue(val));
}
/**
* @returns the key associated with the specified value
*/
getKeyByValue(val) {
return this.valueMap.get(this.normalizeValue(val));
}
/**
* @returns true if a value in the map existed and has been removed, else false
*/
deleteByValue(val) {
const key = this.getKeyByValue(val);
return key ? this.delete(key) : false;
}
}
exports.BiDirectionalDeepMap = BiDirectionalDeepMap;