UNPKG

@itwin/core-bentley

Version:

Bentley JavaScript core components

103 lines 3.53 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Collections */ Object.defineProperty(exports, "__esModule", { value: true }); exports.TupleKeyedMap = void 0; /** A map similar to the standard JavaScript Map collection except that the keys must be a tuple * (javascript array), and two keys are considered equal if their elements in order are strict-equal, * and the tuples have the same amount of elements * * This means you can use array literals to key data in Maps that would otherwise be reference-compared * if using JavaScript's built in Map * * Note that JavaScript's Map type, unlike this one that uses strict equality, uses instead * SameValueZero equality comparison * @see https://262.ecma-international.org/6.0/#sec-samevaluezero * * ```js * const map = new TupleKeyedMap([[1,"y"], "value"]); * const value = map.get([1, "y"]); // a normal map would identify these keys as different because they are independent objects * ``` * * It is implemented by each index of the tuple key being used as a singular key into a submap * @note this only implements a subset of the Map interface * @public */ class TupleKeyedMap { _map = new Map(); // argument types match those of Map constructor(entries) { if (entries) for (const [k, v] of entries) { this.set(k, v); } } clear() { return this._map.clear(); } makeKeyError() { return Error("A Bad key was used, it didn't match the key type of the the map."); } get(key) { let cursor = this._map; for (const subkey of key) { if (!(cursor instanceof Map)) throw this.makeKeyError(); cursor = cursor.get(subkey); if (cursor === undefined) return undefined; } if (cursor instanceof Map) throw this.makeKeyError(); return cursor; } has(key) { return this.get(key) !== undefined; } set(key, value) { let cursor = this._map; for (let i = 0; i < key.length - 1; ++i) { const subkey = key[i]; let next = cursor.get(subkey); if (next === undefined) { next = new Map(); cursor.set(subkey, next); } cursor = next; } const finalSubkey = key[key.length - 1]; if (!(cursor instanceof Map)) throw this.makeKeyError(); cursor.set(finalSubkey, value); this._size++; return this; } *[Symbol.iterator]() { function* impl(map, keyPrefix) { for (const [k, v] of map) { const nextKey = [...keyPrefix, k]; if (v instanceof Map) { yield* impl(v, nextKey); } else { yield [nextKey, v]; } } } yield* impl(this._map, []); } _size = 0; get size() { return this._size; } get [Symbol.toStringTag]() { return this.constructor.name; } } exports.TupleKeyedMap = TupleKeyedMap; //# sourceMappingURL=TupleKeyedMap.js.map