UNPKG

deep-equality-data-structures

Version:

Javascript data structures (e.g., Map, Set) that support deep object equality

72 lines (71 loc) 2.44 kB
"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;